summaryrefslogtreecommitdiff
path: root/boost
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:30:07 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:32:57 +0900
commit71d216b90256936a9638f325af9bc69d720e75de (patch)
tree9c5f682d341c7c88ad0c8e3d4b262e00b6fb691a /boost
parent733b5d5ae2c5d625211e2985ac25728ac3f54883 (diff)
downloadboost-71d216b90256936a9638f325af9bc69d720e75de.tar.gz
boost-71d216b90256936a9638f325af9bc69d720e75de.tar.bz2
boost-71d216b90256936a9638f325af9bc69d720e75de.zip
Imported Upstream version 1.59.0
Change-Id: I2dde00f4eca71df3eea9d251dcaecde18a6c90a5 Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost')
-rw-r--r--boost/align.hpp11
-rw-r--r--boost/align/align.hpp10
-rw-r--r--boost/align/aligned_alloc.hpp10
-rw-r--r--boost/align/aligned_allocator.hpp252
-rw-r--r--boost/align/aligned_allocator_adaptor.hpp261
-rw-r--r--boost/align/aligned_allocator_adaptor_forward.hpp22
-rw-r--r--boost/align/aligned_allocator_forward.hpp22
-rw-r--r--boost/align/aligned_delete.hpp38
-rw-r--r--boost/align/aligned_delete_forward.hpp20
-rw-r--r--boost/align/alignment_of.hpp50
-rw-r--r--boost/align/alignment_of_forward.hpp22
-rw-r--r--boost/align/assume_aligned.hpp29
-rw-r--r--boost/align/detail/address.hpp26
-rw-r--r--boost/align/detail/addressof.hpp26
-rw-r--r--boost/align/detail/align.hpp46
-rw-r--r--boost/align/detail/align_cxx11.hpp20
-rw-r--r--boost/align/detail/aligned_alloc.hpp66
-rw-r--r--boost/align/detail/aligned_alloc_android.hpp37
-rw-r--r--boost/align/detail/aligned_alloc_macos.hpp55
-rw-r--r--boost/align/detail/aligned_alloc_msvc.hpp37
-rw-r--r--boost/align/detail/aligned_alloc_posix.hpp49
-rw-r--r--boost/align/detail/aligned_alloc_sunos.hpp37
-rw-r--r--boost/align/detail/alignment_of.hpp32
-rw-r--r--boost/align/detail/alignment_of_clang.hpp30
-rw-r--r--boost/align/detail/alignment_of_codegear.hpp30
-rw-r--r--boost/align/detail/alignment_of_cxx11.hpp24
-rw-r--r--boost/align/detail/alignment_of_gcc.hpp30
-rw-r--r--boost/align/detail/alignment_of_msvc.hpp31
-rw-r--r--boost/align/detail/assume_aligned.hpp17
-rw-r--r--boost/align/detail/assume_aligned_clang.hpp21
-rw-r--r--boost/align/detail/assume_aligned_gcc.hpp18
-rw-r--r--boost/align/detail/assume_aligned_intel.hpp18
-rw-r--r--boost/align/detail/assume_aligned_msvc.hpp20
-rw-r--r--boost/align/detail/integral_constant.hpp48
-rw-r--r--boost/align/detail/is_aligned.hpp28
-rw-r--r--boost/align/detail/is_alignment.hpp30
-rw-r--r--boost/align/detail/is_alignment_constant.hpp31
-rw-r--r--boost/align/detail/max_align.hpp31
-rw-r--r--boost/align/detail/max_count_of.hpp32
-rw-r--r--boost/align/detail/min_size.hpp31
-rw-r--r--boost/align/detail/offset_object.hpp32
-rw-r--r--boost/align/detail/remove_traits.hpp132
-rw-r--r--boost/align/is_aligned.hpp10
-rw-r--r--boost/archive/archive_exception.hpp24
-rw-r--r--boost/archive/basic_archive.hpp4
-rw-r--r--boost/archive/basic_binary_iarchive.hpp58
-rw-r--r--boost/archive/basic_binary_iprimitive.hpp17
-rw-r--r--boost/archive/basic_binary_oarchive.hpp33
-rw-r--r--boost/archive/basic_binary_oprimitive.hpp16
-rw-r--r--boost/archive/basic_text_iarchive.hpp15
-rw-r--r--boost/archive/basic_text_iprimitive.hpp8
-rw-r--r--boost/archive/basic_text_oarchive.hpp19
-rw-r--r--boost/archive/basic_text_oprimitive.hpp8
-rw-r--r--boost/archive/basic_xml_archive.hpp16
-rw-r--r--boost/archive/basic_xml_iarchive.hpp43
-rw-r--r--boost/archive/basic_xml_oarchive.hpp67
-rw-r--r--boost/archive/binary_iarchive.hpp2
-rw-r--r--boost/archive/binary_iarchive_impl.hpp8
-rw-r--r--boost/archive/binary_oarchive.hpp2
-rw-r--r--boost/archive/binary_oarchive_impl.hpp8
-rw-r--r--boost/archive/codecvt_null.hpp4
-rw-r--r--boost/archive/detail/abi_prefix.hpp4
-rw-r--r--boost/archive/detail/abi_suffix.hpp4
-rw-r--r--boost/archive/detail/archive_serializer_map.hpp9
-rw-r--r--boost/archive/detail/basic_archive_impl.hpp45
-rw-r--r--boost/archive/detail/basic_config.hpp45
-rw-r--r--boost/archive/detail/basic_iarchive.hpp36
-rw-r--r--boost/archive/detail/basic_iserializer.hpp10
-rw-r--r--boost/archive/detail/basic_oarchive.hpp26
-rw-r--r--boost/archive/detail/basic_oserializer.hpp10
-rw-r--r--boost/archive/detail/basic_pointer_iserializer.hpp10
-rw-r--r--boost/archive/detail/basic_pointer_oserializer.hpp10
-rw-r--r--boost/archive/detail/basic_serializer_map.hpp8
-rw-r--r--boost/archive/detail/common_iarchive.hpp2
-rw-r--r--boost/archive/detail/common_oarchive.hpp2
-rw-r--r--boost/archive/detail/decl.hpp68
-rw-r--r--boost/archive/detail/helper_collection.hpp5
-rw-r--r--boost/archive/detail/interface_iarchive.hpp12
-rw-r--r--boost/archive/detail/interface_oarchive.hpp23
-rw-r--r--boost/archive/detail/iserializer.hpp37
-rw-r--r--boost/archive/detail/polymorphic_iarchive_route.hpp9
-rw-r--r--boost/archive/detail/polymorphic_oarchive_route.hpp8
-rw-r--r--boost/archive/impl/archive_serializer_map.ipp6
-rw-r--r--boost/archive/impl/basic_binary_iarchive.ipp10
-rw-r--r--boost/archive/impl/basic_binary_iprimitive.ipp14
-rw-r--r--boost/archive/impl/basic_binary_oarchive.ipp6
-rw-r--r--boost/archive/impl/basic_binary_oprimitive.ipp14
-rw-r--r--boost/archive/impl/basic_text_iarchive.ipp8
-rw-r--r--boost/archive/impl/basic_text_iprimitive.ipp13
-rw-r--r--boost/archive/impl/basic_text_oarchive.ipp4
-rw-r--r--boost/archive/impl/basic_text_oprimitive.ipp11
-rw-r--r--boost/archive/impl/basic_xml_grammar.hpp14
-rw-r--r--boost/archive/impl/basic_xml_iarchive.ipp24
-rw-r--r--boost/archive/impl/basic_xml_oarchive.ipp63
-rw-r--r--boost/archive/impl/text_iarchive_impl.ipp18
-rw-r--r--boost/archive/impl/text_oarchive_impl.ipp12
-rw-r--r--boost/archive/impl/text_wiarchive_impl.ipp10
-rw-r--r--boost/archive/impl/text_woarchive_impl.ipp8
-rw-r--r--boost/archive/impl/xml_iarchive_impl.ipp18
-rw-r--r--boost/archive/impl/xml_oarchive_impl.ipp22
-rw-r--r--boost/archive/impl/xml_wiarchive_impl.ipp27
-rw-r--r--boost/archive/impl/xml_woarchive_impl.ipp28
-rw-r--r--boost/archive/iterators/base64_from_binary.hpp6
-rw-r--r--boost/archive/iterators/binary_from_base64.hpp5
-rw-r--r--boost/archive/iterators/insert_linebreaks.hpp6
-rw-r--r--boost/archive/iterators/mb_from_wchar.hpp7
-rw-r--r--boost/archive/iterators/remove_whitespace.hpp6
-rw-r--r--boost/archive/iterators/transform_width.hpp8
-rw-r--r--boost/archive/iterators/wchar_from_mb.hpp5
-rw-r--r--boost/archive/iterators/xml_escape.hpp5
-rw-r--r--boost/archive/iterators/xml_unescape.hpp5
-rw-r--r--boost/archive/polymorphic_iarchive.hpp18
-rw-r--r--boost/archive/polymorphic_oarchive.hpp17
-rw-r--r--boost/archive/text_iarchive.hpp29
-rw-r--r--boost/archive/text_oarchive.hpp18
-rw-r--r--boost/archive/text_wiarchive.hpp20
-rw-r--r--boost/archive/text_woarchive.hpp12
-rw-r--r--boost/archive/xml_archive_exception.hpp5
-rw-r--r--boost/archive/xml_iarchive.hpp26
-rw-r--r--boost/archive/xml_oarchive.hpp14
-rw-r--r--boost/archive/xml_wiarchive.hpp26
-rw-r--r--boost/archive/xml_woarchive.hpp16
-rw-r--r--boost/bind/bind.hpp2
-rw-r--r--boost/bind/bind_mf_cc.hpp54
-rw-r--r--boost/concept/detail/general.hpp11
-rw-r--r--boost/config/compiler/intel.hpp73
-rw-r--r--boost/config/compiler/visualc.hpp49
-rw-r--r--boost/config/compiler/xlcpp.hpp258
-rw-r--r--boost/config/platform/haiku.hpp2
-rw-r--r--boost/config/select_compiler_config.hpp10
-rw-r--r--boost/config/stdlib/dinkumware.hpp19
-rw-r--r--boost/config/stdlib/libcomo.hpp12
-rw-r--r--boost/config/stdlib/libcpp.hpp10
-rw-r--r--boost/config/stdlib/libstdcpp3.hpp25
-rw-r--r--boost/config/stdlib/modena.hpp10
-rw-r--r--boost/config/stdlib/msl.hpp19
-rw-r--r--boost/config/stdlib/roguewave.hpp9
-rw-r--r--boost/config/stdlib/sgi.hpp13
-rw-r--r--boost/config/stdlib/stlport.hpp18
-rw-r--r--boost/config/stdlib/vacpp.hpp13
-rw-r--r--boost/container/adaptive_pool.hpp6
-rw-r--r--boost/container/allocator_traits.hpp73
-rw-r--r--boost/container/deque.hpp28
-rw-r--r--boost/container/detail/copy_move_algo.hpp71
-rw-r--r--boost/container/detail/flat_tree.hpp98
-rw-r--r--boost/container/detail/iterator.hpp1
-rw-r--r--boost/container/detail/iterators.hpp12
-rw-r--r--boost/container/detail/mpl.hpp175
-rw-r--r--boost/container/detail/node_alloc_holder.hpp108
-rw-r--r--boost/container/detail/pair.hpp79
-rw-r--r--boost/container/detail/std_fwd.hpp6
-rw-r--r--boost/container/detail/tree.hpp91
-rw-r--r--boost/container/detail/type_traits.hpp1
-rw-r--r--boost/container/list.hpp4
-rw-r--r--boost/container/node_allocator.hpp6
-rw-r--r--boost/container/scoped_allocator.hpp52
-rw-r--r--boost/container/slist.hpp4
-rw-r--r--boost/container/small_vector.hpp12
-rw-r--r--boost/container/stable_vector.hpp81
-rw-r--r--boost/container/string.hpp57
-rw-r--r--boost/container/vector.hpp471
-rw-r--r--boost/context/detail/config.hpp32
-rw-r--r--boost/context/detail/invoke.hpp48
-rw-r--r--boost/context/execution_context.hpp304
-rw-r--r--boost/context/execution_context.ipp374
-rw-r--r--boost/context/execution_context_winfib.ipp308
-rw-r--r--boost/context/fixedsize_stack.hpp6
-rw-r--r--boost/context/windows/protected_fixedsize_stack.hpp6
-rw-r--r--boost/convert.hpp216
-rw-r--r--boost/convert/base.hpp180
-rw-r--r--boost/convert/detail/boost_parameter_ext.hpp62
-rw-r--r--boost/convert/detail/char.hpp23
-rw-r--r--boost/convert/detail/forward.hpp39
-rw-r--r--boost/convert/detail/has_member.hpp61
-rw-r--r--boost/convert/detail/is_callable.hpp100
-rw-r--r--boost/convert/detail/is_converter.hpp47
-rw-r--r--boost/convert/detail/is_fun.hpp61
-rw-r--r--boost/convert/detail/is_string.hpp34
-rw-r--r--boost/convert/detail/range.hpp112
-rw-r--r--boost/convert/lexical_cast.hpp40
-rw-r--r--boost/convert/parameters.hpp33
-rw-r--r--boost/convert/printf.hpp89
-rw-r--r--boost/convert/spirit.hpp54
-rw-r--r--boost/convert/stream.hpp196
-rw-r--r--boost/convert/strtol.hpp218
-rw-r--r--boost/core/ignore_unused.hpp24
-rw-r--r--boost/coroutine/asymmetric_coroutine.hpp821
-rw-r--r--boost/coroutine/detail/coroutine_context.hpp8
-rw-r--r--boost/coroutine/detail/preallocated.hpp45
-rw-r--r--boost/coroutine/detail/pull_coroutine_object.hpp47
-rw-r--r--boost/coroutine/detail/push_coroutine_object.hpp51
-rw-r--r--boost/coroutine/detail/symmetric_coroutine_call.hpp301
-rw-r--r--boost/coroutine/detail/symmetric_coroutine_impl.hpp15
-rw-r--r--boost/coroutine/detail/symmetric_coroutine_object.hpp43
-rw-r--r--boost/coroutine/exceptions.hpp6
-rw-r--r--boost/coroutine2/all.hpp15
-rw-r--r--boost/coroutine2/coroutine.hpp39
-rw-r--r--boost/coroutine2/detail/config.hpp51
-rw-r--r--boost/coroutine2/detail/coroutine.hpp44
-rw-r--r--boost/coroutine2/detail/forced_unwind.hpp33
-rw-r--r--boost/coroutine2/detail/pull_control_block.hpp100
-rw-r--r--boost/coroutine2/detail/pull_control_block.ipp258
-rw-r--r--boost/coroutine2/detail/pull_coroutine.hpp312
-rw-r--r--boost/coroutine2/detail/pull_coroutine.ipp271
-rw-r--r--boost/coroutine2/detail/push_control_block.hpp104
-rw-r--r--boost/coroutine2/detail/push_control_block.ipp281
-rw-r--r--boost/coroutine2/detail/push_coroutine.hpp242
-rw-r--r--boost/coroutine2/detail/push_coroutine.ipp253
-rw-r--r--boost/coroutine2/detail/state.hpp37
-rw-r--r--boost/coroutine2/fixedsize_stack.hpp33
-rw-r--r--boost/coroutine2/protected_fixedsize_stack.hpp33
-rw-r--r--boost/coroutine2/segmented_stack.hpp37
-rw-r--r--boost/format/exceptions.hpp2
-rw-r--r--boost/format/feed_args.hpp2
-rw-r--r--boost/format/parsing.hpp2
-rw-r--r--boost/function/function_base.hpp14
-rw-r--r--boost/function/function_template.hpp30
-rw-r--r--boost/function_types/components.hpp3
-rw-r--r--boost/function_types/detail/classifier.hpp9
-rw-r--r--boost/function_types/function_arity.hpp2
-rw-r--r--boost/function_types/function_pointer.hpp2
-rw-r--r--boost/function_types/function_reference.hpp2
-rw-r--r--boost/function_types/function_type.hpp1
-rw-r--r--boost/function_types/is_callable_builtin.hpp2
-rw-r--r--boost/function_types/is_function.hpp2
-rw-r--r--boost/function_types/is_function_pointer.hpp2
-rw-r--r--boost/function_types/is_function_reference.hpp2
-rw-r--r--boost/function_types/is_member_function_pointer.hpp2
-rw-r--r--boost/function_types/is_member_object_pointer.hpp2
-rw-r--r--boost/function_types/is_member_pointer.hpp2
-rw-r--r--boost/function_types/is_nonmember_callable_builtin.hpp2
-rw-r--r--boost/function_types/member_function_pointer.hpp2
-rw-r--r--boost/function_types/member_object_pointer.hpp2
-rw-r--r--boost/function_types/parameter_types.hpp2
-rw-r--r--boost/function_types/result_type.hpp2
-rw-r--r--boost/fusion/adapted/std_tuple/detail/build_std_tuple.hpp35
-rw-r--r--boost/fusion/adapted/struct/adapt_struct.hpp19
-rw-r--r--boost/fusion/adapted/struct/detail/adapt_base_attr_filler.hpp10
-rw-r--r--boost/fusion/adapted/struct/detail/define_struct.hpp16
-rw-r--r--boost/fusion/adapted/struct/detail/define_struct_inline.hpp4
-rw-r--r--boost/fusion/algorithm/iteration/reverse_fold.hpp1
-rw-r--r--boost/fusion/algorithm/iteration/reverse_iter_fold.hpp1
-rw-r--r--boost/fusion/container/deque/detail/cpp03/deque.hpp8
-rw-r--r--boost/fusion/container/deque/detail/cpp03/deque_keyed_values.hpp1
-rw-r--r--boost/fusion/container/deque/detail/cpp03/limits.hpp2
-rw-r--r--boost/fusion/container/deque/detail/cpp03/preprocessed/deque10.hpp8
-rw-r--r--boost/fusion/container/deque/detail/cpp03/preprocessed/deque20.hpp8
-rw-r--r--boost/fusion/container/deque/detail/cpp03/preprocessed/deque30.hpp8
-rw-r--r--boost/fusion/container/deque/detail/cpp03/preprocessed/deque40.hpp8
-rw-r--r--boost/fusion/container/deque/detail/cpp03/preprocessed/deque50.hpp8
-rw-r--r--boost/fusion/container/generation/detail/pp_list_tie.hpp102
-rw-r--r--boost/fusion/container/generation/detail/pp_make_list.hpp115
-rw-r--r--boost/fusion/container/generation/detail/pp_make_set.hpp134
-rw-r--r--boost/fusion/container/generation/detail/pp_make_vector.hpp115
-rw-r--r--boost/fusion/container/generation/detail/pp_vector_tie.hpp100
-rw-r--r--boost/fusion/container/generation/ignore.hpp6
-rw-r--r--boost/fusion/container/generation/list_tie.hpp98
-rw-r--r--boost/fusion/container/generation/make_list.hpp105
-rw-r--r--boost/fusion/container/generation/make_set.hpp126
-rw-r--r--boost/fusion/container/generation/make_vector.hpp109
-rw-r--r--boost/fusion/container/generation/vector_tie.hpp95
-rw-r--r--boost/fusion/container/list.hpp1
-rw-r--r--boost/fusion/container/list/cons.hpp4
-rw-r--r--boost/fusion/container/list/detail/cpp03/limits.hpp (renamed from boost/fusion/container/list/limits.hpp)0
-rw-r--r--boost/fusion/container/list/detail/cpp03/list.hpp102
-rw-r--r--boost/fusion/container/list/detail/cpp03/list_forward_ctor.hpp (renamed from boost/fusion/container/list/detail/list_forward_ctor.hpp)2
-rw-r--r--boost/fusion/container/list/detail/cpp03/list_fwd.hpp51
-rw-r--r--boost/fusion/container/list/detail/cpp03/list_to_cons.hpp76
-rw-r--r--boost/fusion/container/list/detail/cpp03/list_to_cons_call.hpp (renamed from boost/fusion/container/list/detail/list_to_cons_call.hpp)2
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list.hpp)10
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list10.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list10.hpp)4
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list10_fwd.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list10_fwd.hpp)0
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list20.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list20.hpp)4
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list20_fwd.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list20_fwd.hpp)0
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list30.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list30.hpp)4
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list30_fwd.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list30_fwd.hpp)0
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list40.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list40.hpp)4
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list40_fwd.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list40_fwd.hpp)0
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list50.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list50.hpp)4
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list50_fwd.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list50_fwd.hpp)0
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list_fwd.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list_fwd.hpp)10
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list_to_cons.hpp)10
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons10.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list_to_cons10.hpp)0
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons20.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list_to_cons20.hpp)0
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons30.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list_to_cons30.hpp)0
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons40.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list_to_cons40.hpp)0
-rw-r--r--boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons50.hpp (renamed from boost/fusion/container/list/detail/preprocessed/list_to_cons50.hpp)0
-rw-r--r--boost/fusion/container/list/detail/list_to_cons.hpp89
-rw-r--r--boost/fusion/container/list/list.hpp136
-rw-r--r--boost/fusion/container/list/list_fwd.hpp52
-rw-r--r--boost/fusion/container/map/detail/cpp03/limits.hpp2
-rw-r--r--boost/fusion/container/map/detail/cpp03/map.hpp2
-rw-r--r--boost/fusion/container/map/detail/cpp03/preprocessed/map10.hpp2
-rw-r--r--boost/fusion/container/map/detail/cpp03/preprocessed/map20.hpp2
-rw-r--r--boost/fusion/container/map/detail/cpp03/preprocessed/map30.hpp2
-rw-r--r--boost/fusion/container/map/detail/cpp03/preprocessed/map40.hpp2
-rw-r--r--boost/fusion/container/map/detail/cpp03/preprocessed/map50.hpp2
-rw-r--r--boost/fusion/container/map/map.hpp8
-rw-r--r--boost/fusion/container/set.hpp1
-rw-r--r--boost/fusion/container/set/detail/as_set.hpp136
-rw-r--r--boost/fusion/container/set/detail/cpp03/as_set.hpp139
-rw-r--r--boost/fusion/container/set/detail/cpp03/limits.hpp (renamed from boost/fusion/container/set/limits.hpp)2
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/as_set.hpp (renamed from boost/fusion/container/set/detail/preprocessed/as_set.hpp)10
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/as_set10.hpp (renamed from boost/fusion/container/set/detail/preprocessed/as_set10.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/as_set20.hpp (renamed from boost/fusion/container/set/detail/preprocessed/as_set20.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/as_set30.hpp (renamed from boost/fusion/container/set/detail/preprocessed/as_set30.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/as_set40.hpp (renamed from boost/fusion/container/set/detail/preprocessed/as_set40.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/as_set50.hpp (renamed from boost/fusion/container/set/detail/preprocessed/as_set50.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/set.hpp (renamed from boost/fusion/container/set/detail/preprocessed/set.hpp)10
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/set10.hpp (renamed from boost/fusion/container/set/detail/preprocessed/set10.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/set10_fwd.hpp (renamed from boost/fusion/container/set/detail/preprocessed/set10_fwd.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/set20.hpp (renamed from boost/fusion/container/set/detail/preprocessed/set20.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/set20_fwd.hpp (renamed from boost/fusion/container/set/detail/preprocessed/set20_fwd.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/set30.hpp (renamed from boost/fusion/container/set/detail/preprocessed/set30.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/set30_fwd.hpp (renamed from boost/fusion/container/set/detail/preprocessed/set30_fwd.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/set40.hpp (renamed from boost/fusion/container/set/detail/preprocessed/set40.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/set40_fwd.hpp (renamed from boost/fusion/container/set/detail/preprocessed/set40_fwd.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/set50.hpp (renamed from boost/fusion/container/set/detail/preprocessed/set50.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/set50_fwd.hpp (renamed from boost/fusion/container/set/detail/preprocessed/set50_fwd.hpp)0
-rw-r--r--boost/fusion/container/set/detail/cpp03/preprocessed/set_fwd.hpp (renamed from boost/fusion/container/set/detail/preprocessed/set_fwd.hpp)10
-rw-r--r--boost/fusion/container/set/detail/cpp03/set.hpp106
-rw-r--r--boost/fusion/container/set/detail/cpp03/set_forward_ctor.hpp (renamed from boost/fusion/container/set/detail/set_forward_ctor.hpp)2
-rw-r--r--boost/fusion/container/set/detail/cpp03/set_fwd.hpp53
-rw-r--r--boost/fusion/container/set/set.hpp100
-rw-r--r--boost/fusion/container/set/set_fwd.hpp50
-rw-r--r--boost/fusion/container/vector.hpp2
-rw-r--r--boost/fusion/container/vector/detail/as_vector.hpp134
-rw-r--r--boost/fusion/container/vector/detail/cpp03/as_vector.hpp139
-rw-r--r--boost/fusion/container/vector/detail/cpp03/limits.hpp (renamed from boost/fusion/container/vector/limits.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/as_vector.hpp)10
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector10.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/as_vector10.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector20.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/as_vector20.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector30.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/as_vector30.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector40.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/as_vector40.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector50.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/as_vector50.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector.hpp)10
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector10.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector10.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector10_fwd.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector10_fwd.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector20.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector20.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector20_fwd.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector20_fwd.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector30.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector30.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector30_fwd.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector30_fwd.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector40.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector40.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector40_fwd.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector40_fwd.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector50.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector50.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector50_fwd.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector50_fwd.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector_chooser.hpp)10
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser10.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector_chooser10.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser20.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector_chooser20.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser30.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector_chooser30.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser40.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector_chooser40.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser50.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector_chooser50.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vector_fwd.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vector_fwd.hpp)10
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vvector10.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vvector10.hpp)4
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vvector10_fwd.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vvector10_fwd.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vvector20.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vvector20.hpp)4
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vvector20_fwd.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vvector20_fwd.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vvector30.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vvector30.hpp)4
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vvector30_fwd.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vvector30_fwd.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vvector40.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vvector40.hpp)4
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vvector40_fwd.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vvector40_fwd.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vvector50.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vvector50.hpp)4
-rw-r--r--boost/fusion/container/vector/detail/cpp03/preprocessed/vvector50_fwd.hpp (renamed from boost/fusion/container/vector/detail/preprocessed/vvector50_fwd.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/value_at_impl.hpp34
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector.hpp247
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector10.hpp105
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector10_fwd.hpp (renamed from boost/fusion/container/vector/vector10_fwd.hpp)6
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector20.hpp81
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector20_fwd.hpp (renamed from boost/fusion/container/vector/vector20_fwd.hpp)6
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector30.hpp80
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector30_fwd.hpp (renamed from boost/fusion/container/vector/vector30_fwd.hpp)6
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector40.hpp81
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector40_fwd.hpp (renamed from boost/fusion/container/vector/vector40_fwd.hpp)6
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector50.hpp80
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector50_fwd.hpp (renamed from boost/fusion/container/vector/vector50_fwd.hpp)6
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector_forward_ctor.hpp (renamed from boost/fusion/container/vector/detail/vector_forward_ctor.hpp)2
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector_fwd.hpp66
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector_n.hpp (renamed from boost/fusion/container/vector/detail/vector_n.hpp)0
-rw-r--r--boost/fusion/container/vector/detail/cpp03/vector_n_chooser.hpp (renamed from boost/fusion/container/vector/detail/vector_n_chooser.hpp)16
-rw-r--r--boost/fusion/container/vector/detail/value_at_impl.hpp35
-rw-r--r--boost/fusion/container/vector/vector.hpp253
-rw-r--r--boost/fusion/container/vector/vector10.hpp102
-rw-r--r--boost/fusion/container/vector/vector20.hpp78
-rw-r--r--boost/fusion/container/vector/vector30.hpp77
-rw-r--r--boost/fusion/container/vector/vector40.hpp78
-rw-r--r--boost/fusion/container/vector/vector50.hpp77
-rw-r--r--boost/fusion/container/vector/vector_fwd.hpp63
-rw-r--r--boost/fusion/functional/adapter/limits.hpp2
-rw-r--r--boost/fusion/functional/invocation/detail/that_ptr.hpp11
-rw-r--r--boost/fusion/sequence/comparison/less_equal.hpp32
-rw-r--r--boost/fusion/sequence/intrinsic/at.hpp8
-rw-r--r--boost/fusion/sequence/intrinsic/at_key.hpp23
-rw-r--r--boost/fusion/sequence/intrinsic/value_at.hpp23
-rw-r--r--boost/fusion/sequence/intrinsic/value_at_key.hpp25
-rw-r--r--boost/fusion/support/category_of.hpp9
-rw-r--r--boost/fusion/support/config.hpp13
-rw-r--r--boost/fusion/support/detail/index_sequence.hpp59
-rw-r--r--boost/fusion/support/pair.hpp2
-rw-r--r--boost/fusion/support/unused.hpp6
-rw-r--r--boost/fusion/tuple/detail/make_tuple.hpp86
-rw-r--r--boost/fusion/tuple/detail/preprocessed/tuple10.hpp4
-rw-r--r--boost/fusion/tuple/detail/preprocessed/tuple20.hpp4
-rw-r--r--boost/fusion/tuple/detail/preprocessed/tuple30.hpp4
-rw-r--r--boost/fusion/tuple/detail/preprocessed/tuple40.hpp4
-rw-r--r--boost/fusion/tuple/detail/preprocessed/tuple50.hpp4
-rw-r--r--boost/fusion/tuple/detail/tuple.hpp122
-rw-r--r--boost/fusion/tuple/detail/tuple_fwd.hpp52
-rw-r--r--boost/fusion/tuple/detail/tuple_tie.hpp76
-rw-r--r--boost/fusion/tuple/make_tuple.hpp83
-rw-r--r--boost/fusion/tuple/tuple.hpp117
-rw-r--r--boost/fusion/tuple/tuple_fwd.hpp49
-rw-r--r--boost/fusion/tuple/tuple_tie.hpp73
-rw-r--r--boost/fusion/view/nview/detail/cpp03/nview_impl.hpp78
-rw-r--r--boost/fusion/view/nview/detail/nview_impl.hpp72
-rw-r--r--boost/geometry/algorithms/append.hpp2
-rw-r--r--boost/geometry/algorithms/assign.hpp6
-rw-r--r--boost/geometry/algorithms/buffer.hpp13
-rw-r--r--boost/geometry/algorithms/centroid.hpp20
-rw-r--r--boost/geometry/algorithms/clear.hpp2
-rw-r--r--boost/geometry/algorithms/convert.hpp2
-rw-r--r--boost/geometry/algorithms/convex_hull.hpp13
-rw-r--r--boost/geometry/algorithms/crosses.hpp53
-rw-r--r--boost/geometry/algorithms/detail/andoyer_inverse.hpp163
-rw-r--r--boost/geometry/algorithms/detail/azimuth.hpp4
-rw-r--r--boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp104
-rw-r--r--boost/geometry/algorithms/detail/buffer/buffer_policies.hpp35
-rw-r--r--boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp192
-rw-r--r--boost/geometry/algorithms/detail/buffer/buffered_ring.hpp9
-rw-r--r--boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp51
-rw-r--r--boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp244
-rw-r--r--boost/geometry/algorithms/detail/check_iterator_range.hpp4
-rw-r--r--boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp5
-rw-r--r--boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp6
-rw-r--r--boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp15
-rw-r--r--boost/geometry/algorithms/detail/comparable_distance/interface.hpp8
-rw-r--r--boost/geometry/algorithms/detail/disjoint/interface.hpp2
-rw-r--r--boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp140
-rw-r--r--boost/geometry/algorithms/detail/disjoint/point_geometry.hpp47
-rw-r--r--boost/geometry/algorithms/detail/disjoint/point_point.hpp165
-rw-r--r--boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp24
-rw-r--r--boost/geometry/algorithms/detail/distance/interface.hpp8
-rw-r--r--boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp5
-rw-r--r--boost/geometry/algorithms/detail/distance/segment_to_box.hpp8
-rw-r--r--boost/geometry/algorithms/detail/envelope/box.hpp167
-rw-r--r--boost/geometry/algorithms/detail/envelope/implementation.hpp106
-rw-r--r--boost/geometry/algorithms/detail/envelope/initialize.hpp86
-rw-r--r--boost/geometry/algorithms/detail/envelope/interface.hpp126
-rw-r--r--boost/geometry/algorithms/detail/envelope/intersects_antimeridian.hpp78
-rw-r--r--boost/geometry/algorithms/detail/envelope/linear.hpp96
-rw-r--r--boost/geometry/algorithms/detail/envelope/multipoint.hpp378
-rw-r--r--boost/geometry/algorithms/detail/envelope/point.hpp127
-rw-r--r--boost/geometry/algorithms/detail/envelope/range.hpp179
-rw-r--r--boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp326
-rw-r--r--boost/geometry/algorithms/detail/envelope/segment.hpp386
-rw-r--r--boost/geometry/algorithms/detail/envelope/transform_units.hpp103
-rw-r--r--boost/geometry/algorithms/detail/expand/box.hpp126
-rw-r--r--boost/geometry/algorithms/detail/expand/implementation.hpp27
-rw-r--r--boost/geometry/algorithms/detail/expand/indexed.hpp144
-rw-r--r--boost/geometry/algorithms/detail/expand/interface.hpp128
-rw-r--r--boost/geometry/algorithms/detail/expand/point.hpp303
-rw-r--r--boost/geometry/algorithms/detail/expand/segment.hpp115
-rw-r--r--boost/geometry/algorithms/detail/get_left_turns.hpp18
-rw-r--r--boost/geometry/algorithms/detail/intersection/interface.hpp28
-rw-r--r--boost/geometry/algorithms/detail/intersection/multi.hpp6
-rw-r--r--boost/geometry/algorithms/detail/is_simple/linear.hpp12
-rw-r--r--boost/geometry/algorithms/detail/is_valid/box.hpp5
-rw-r--r--boost/geometry/algorithms/detail/is_valid/complement_graph.hpp18
-rw-r--r--boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp15
-rw-r--r--boost/geometry/algorithms/detail/is_valid/has_spikes.hpp40
-rw-r--r--boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp7
-rw-r--r--boost/geometry/algorithms/detail/is_valid/interface.hpp6
-rw-r--r--boost/geometry/algorithms/detail/is_valid/linear.hpp5
-rw-r--r--boost/geometry/algorithms/detail/is_valid/multipolygon.hpp18
-rw-r--r--boost/geometry/algorithms/detail/is_valid/pointlike.hpp10
-rw-r--r--boost/geometry/algorithms/detail/is_valid/polygon.hpp15
-rw-r--r--boost/geometry/algorithms/detail/is_valid/ring.hpp9
-rw-r--r--boost/geometry/algorithms/detail/is_valid/segment.hpp5
-rw-r--r--boost/geometry/algorithms/detail/max_interval_gap.hpp278
-rw-r--r--boost/geometry/algorithms/detail/normalize.hpp294
-rw-r--r--boost/geometry/algorithms/detail/occupation_info.hpp31
-rw-r--r--boost/geometry/algorithms/detail/overlay/add_rings.hpp2
-rw-r--r--boost/geometry/algorithms/detail/overlay/assign_parents.hpp2
-rw-r--r--boost/geometry/algorithms/detail/overlay/check_enrich.hpp4
-rw-r--r--boost/geometry/algorithms/detail/overlay/clip_linestring.hpp9
-rw-r--r--boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp14
-rw-r--r--boost/geometry/algorithms/detail/overlay/copy_segments.hpp47
-rw-r--r--boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp5
-rw-r--r--boost/geometry/algorithms/detail/overlay/enrichment_info.hpp6
-rw-r--r--boost/geometry/algorithms/detail/overlay/follow.hpp14
-rw-r--r--boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp20
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp3
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_ring.hpp6
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info.hpp6
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp25
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp93
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp6
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp8
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turns.hpp27
-rw-r--r--boost/geometry/algorithms/detail/overlay/intersection_insert.hpp132
-rw-r--r--boost/geometry/algorithms/detail/overlay/linear_linear.hpp30
-rw-r--r--boost/geometry/algorithms/detail/overlay/overlay.hpp23
-rw-r--r--boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp343
-rw-r--r--boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp8
-rw-r--r--boost/geometry/algorithms/detail/overlay/ring_properties.hpp7
-rw-r--r--boost/geometry/algorithms/detail/overlay/segment_identifier.hpp18
-rw-r--r--boost/geometry/algorithms/detail/overlay/self_turn_points.hpp1
-rw-r--r--boost/geometry/algorithms/detail/overlay/traverse.hpp9
-rw-r--r--boost/geometry/algorithms/detail/partition.hpp456
-rw-r--r--boost/geometry/algorithms/detail/recalculate.hpp1
-rw-r--r--boost/geometry/algorithms/detail/relate/areal_areal.hpp28
-rw-r--r--boost/geometry/algorithms/detail/relate/boundary_checker.hpp2
-rw-r--r--boost/geometry/algorithms/detail/relate/de9im.hpp439
-rw-r--r--boost/geometry/algorithms/detail/relate/follow_helpers.hpp22
-rw-r--r--boost/geometry/algorithms/detail/relate/implementation.hpp110
-rw-r--r--boost/geometry/algorithms/detail/relate/interface.hpp348
-rw-r--r--boost/geometry/algorithms/detail/relate/less.hpp4
-rw-r--r--boost/geometry/algorithms/detail/relate/linear_areal.hpp71
-rw-r--r--boost/geometry/algorithms/detail/relate/linear_linear.hpp16
-rw-r--r--boost/geometry/algorithms/detail/relate/point_geometry.hpp17
-rw-r--r--boost/geometry/algorithms/detail/relate/point_point.hpp39
-rw-r--r--boost/geometry/algorithms/detail/relate/relate.hpp339
-rw-r--r--boost/geometry/algorithms/detail/relate/relate_impl.hpp80
-rw-r--r--boost/geometry/algorithms/detail/relate/result.hpp648
-rw-r--r--boost/geometry/algorithms/detail/relate/turns.hpp33
-rw-r--r--boost/geometry/algorithms/detail/relation/implementation.hpp18
-rw-r--r--boost/geometry/algorithms/detail/relation/interface.hpp186
-rw-r--r--boost/geometry/algorithms/detail/result_inverse.hpp44
-rw-r--r--boost/geometry/algorithms/detail/ring_identifier.hpp14
-rw-r--r--boost/geometry/algorithms/detail/sections/range_by_section.hpp4
-rw-r--r--boost/geometry/algorithms/detail/sections/sectionalize.hpp33
-rw-r--r--boost/geometry/algorithms/detail/signed_size_type.hpp (renamed from boost/geometry/algorithms/detail/signed_index_type.hpp)11
-rw-r--r--boost/geometry/algorithms/detail/single_geometry.hpp12
-rw-r--r--boost/geometry/algorithms/detail/sub_range.hpp12
-rw-r--r--boost/geometry/algorithms/detail/sweep.hpp87
-rw-r--r--boost/geometry/algorithms/detail/thomas_inverse.hpp191
-rw-r--r--boost/geometry/algorithms/detail/throw_on_empty_input.hpp15
-rw-r--r--boost/geometry/algorithms/detail/turns/compare_turns.hpp16
-rw-r--r--boost/geometry/algorithms/detail/turns/print_turns.hpp4
-rw-r--r--boost/geometry/algorithms/detail/vincenty_direct.hpp121
-rw-r--r--boost/geometry/algorithms/detail/vincenty_inverse.hpp166
-rw-r--r--boost/geometry/algorithms/detail/within/point_in_geometry.hpp8
-rw-r--r--boost/geometry/algorithms/dispatch/envelope.hpp49
-rw-r--r--boost/geometry/algorithms/dispatch/expand.hpp58
-rw-r--r--boost/geometry/algorithms/envelope.hpp294
-rw-r--r--boost/geometry/algorithms/equals.hpp13
-rw-r--r--boost/geometry/algorithms/expand.hpp348
-rw-r--r--boost/geometry/algorithms/is_convex.hpp160
-rw-r--r--boost/geometry/algorithms/is_empty.hpp207
-rw-r--r--boost/geometry/algorithms/length.hpp2
-rw-r--r--boost/geometry/algorithms/overlaps.hpp7
-rw-r--r--boost/geometry/algorithms/relate.hpp17
-rw-r--r--boost/geometry/algorithms/relation.hpp17
-rw-r--r--boost/geometry/algorithms/simplify.hpp2
-rw-r--r--boost/geometry/algorithms/sym_difference.hpp201
-rw-r--r--boost/geometry/algorithms/touches.hpp17
-rw-r--r--boost/geometry/algorithms/transform.hpp31
-rw-r--r--boost/geometry/algorithms/within.hpp30
-rw-r--r--boost/geometry/arithmetic/arithmetic.hpp101
-rw-r--r--boost/geometry/core/assert.hpp43
-rw-r--r--boost/geometry/core/exception.hpp38
-rw-r--r--boost/geometry/core/radian_access.hpp16
-rw-r--r--boost/geometry/geometries/box.hpp89
-rw-r--r--boost/geometry/geometries/concepts/point_concept.hpp2
-rw-r--r--boost/geometry/geometries/helper_geometry.hpp162
-rw-r--r--boost/geometry/geometries/linestring.hpp5
-rw-r--r--boost/geometry/geometries/multi_linestring.hpp11
-rw-r--r--boost/geometry/geometries/multi_point.hpp6
-rw-r--r--boost/geometry/geometries/multi_polygon.hpp11
-rw-r--r--boost/geometry/geometries/point.hpp62
-rw-r--r--boost/geometry/geometries/point_xy.hpp10
-rw-r--r--boost/geometry/geometries/pointing_segment.hpp13
-rw-r--r--boost/geometry/geometries/polygon.hpp10
-rw-r--r--boost/geometry/geometries/ring.hpp5
-rw-r--r--boost/geometry/geometries/segment.hpp21
-rw-r--r--boost/geometry/geometry.hpp7
-rw-r--r--boost/geometry/index/detail/assert.hpp10
-rw-r--r--boost/geometry/index/detail/bounded_view.hpp64
-rw-r--r--boost/geometry/index/detail/predicates.hpp10
-rw-r--r--boost/geometry/index/detail/rtree/iterators.hpp122
-rw-r--r--boost/geometry/index/detail/rtree/node/node.hpp6
-rw-r--r--boost/geometry/index/detail/rtree/pack_create.hpp66
-rw-r--r--boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp5
-rw-r--r--boost/geometry/index/detail/rtree/query_iterators.hpp27
-rw-r--r--boost/geometry/index/detail/rtree/visitors/distance_query.hpp8
-rw-r--r--boost/geometry/index/detail/rtree/visitors/iterator.hpp134
-rw-r--r--boost/geometry/index/detail/rtree/visitors/spatial_query.hpp10
-rw-r--r--boost/geometry/index/rtree.hpp341
-rw-r--r--boost/geometry/io/svg/svg_mapper.hpp21
-rw-r--r--boost/geometry/io/wkt/read.hpp146
-rw-r--r--boost/geometry/io/wkt/write.hpp19
-rw-r--r--boost/geometry/iterators/concatenate_iterator.hpp1
-rw-r--r--boost/geometry/iterators/detail/segment_iterator/value_type.hpp38
-rw-r--r--boost/geometry/iterators/flatten_iterator.hpp19
-rw-r--r--boost/geometry/iterators/point_iterator.hpp1
-rw-r--r--boost/geometry/multi/multi.hpp73
-rw-r--r--boost/geometry/policies/is_valid/failing_reason_policy.hpp12
-rw-r--r--boost/geometry/policies/relate/de9im.hpp168
-rw-r--r--boost/geometry/policies/relate/intersection_points.hpp32
-rw-r--r--boost/geometry/policies/robustness/get_rescale_policy.hpp56
-rw-r--r--boost/geometry/policies/robustness/rescale_policy.hpp17
-rw-r--r--boost/geometry/policies/robustness/segment_ratio.hpp38
-rw-r--r--boost/geometry/strategies/agnostic/hull_graham_andrew.hpp3
-rw-r--r--boost/geometry/strategies/agnostic/relate.hpp30
-rw-r--r--boost/geometry/strategies/agnostic/side_by_azimuth.hpp87
-rw-r--r--boost/geometry/strategies/buffer.hpp14
-rw-r--r--boost/geometry/strategies/cartesian/buffer_end_round.hpp10
-rw-r--r--boost/geometry/strategies/cartesian/buffer_join_miter.hpp4
-rw-r--r--boost/geometry/strategies/cartesian/buffer_join_round.hpp16
-rw-r--r--boost/geometry/strategies/cartesian/buffer_join_round_by_divide.hpp1
-rw-r--r--boost/geometry/strategies/cartesian/buffer_point_circle.hpp3
-rw-r--r--boost/geometry/strategies/cartesian/buffer_side_straight.hpp39
-rw-r--r--boost/geometry/strategies/cartesian/cart_intersect.hpp27
-rw-r--r--boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp24
-rw-r--r--boost/geometry/strategies/cartesian/centroid_weighted_length.hpp41
-rw-r--r--boost/geometry/strategies/cartesian/side_of_intersection.hpp248
-rw-r--r--boost/geometry/strategies/geographic/distance_thomas.hpp156
-rw-r--r--boost/geometry/strategies/geographic/distance_vincenty.hpp13
-rw-r--r--boost/geometry/strategies/geographic/side_andoyer.hpp55
-rw-r--r--boost/geometry/strategies/geographic/side_detail.hpp139
-rw-r--r--boost/geometry/strategies/geographic/side_thomas.hpp55
-rw-r--r--boost/geometry/strategies/geographic/side_vincenty.hpp55
-rw-r--r--boost/geometry/strategies/intersection_result.hpp143
-rw-r--r--boost/geometry/strategies/spherical/area_huiller.hpp58
-rw-r--r--boost/geometry/strategies/spherical/distance_cross_track.hpp19
-rw-r--r--boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp293
-rw-r--r--boost/geometry/strategies/strategies.hpp12
-rw-r--r--boost/geometry/strategies/strategy_transform.hpp33
-rw-r--r--boost/geometry/strategies/transform/matrix_transformers.hpp15
-rw-r--r--boost/geometry/util/math.hpp171
-rw-r--r--boost/geometry/util/normalize_spheroidal_box_coordinates.hpp160
-rw-r--r--boost/geometry/util/normalize_spheroidal_coordinates.hpp218
-rw-r--r--boost/geometry/util/range.hpp28
-rw-r--r--boost/geometry/views/detail/boundary_view.hpp16
-rw-r--r--boost/geometry/views/detail/boundary_view/implementation.hpp466
-rw-r--r--boost/geometry/views/detail/boundary_view/interface.hpp70
-rw-r--r--boost/geometry/views/detail/indexed_point_view.hpp33
-rw-r--r--boost/geometry/views/detail/two_dimensional_view.hpp196
-rw-r--r--boost/get_pointer.hpp28
-rw-r--r--boost/heap/detail/tree_iterator.hpp18
-rw-r--r--boost/heap/fibonacci_heap.hpp14
-rw-r--r--boost/heap/pairing_heap.hpp2
-rw-r--r--boost/interprocess/detail/std_fwd.hpp6
-rw-r--r--boost/interprocess/detail/xsi_shared_memory_device.hpp401
-rw-r--r--boost/interprocess/exceptions.hpp53
-rw-r--r--boost/interprocess/streams/bufferstream.hpp4
-rw-r--r--boost/interprocess/streams/vectorstream.hpp4
-rw-r--r--boost/interprocess/sync/xsi/advanced_xsi_semaphore.hpp201
-rw-r--r--boost/interprocess/sync/xsi/simple_xsi_semaphore.hpp124
-rw-r--r--boost/interprocess/sync/xsi/xsi_named_mutex.hpp238
-rw-r--r--boost/intrusive/avl_set.hpp390
-rw-r--r--boost/intrusive/avltree.hpp232
-rw-r--r--boost/intrusive/bs_set.hpp390
-rw-r--r--boost/intrusive/bstree.hpp648
-rw-r--r--boost/intrusive/bstree_algorithms.hpp4
-rw-r--r--boost/intrusive/detail/common_slist_algorithms.hpp2
-rw-r--r--boost/intrusive/detail/default_header_holder.hpp8
-rw-r--r--boost/intrusive/detail/ebo_functor_holder.hpp1
-rw-r--r--boost/intrusive/detail/get_value_traits.hpp6
-rw-r--r--boost/intrusive/detail/hashtable_node.hpp69
-rw-r--r--boost/intrusive/detail/is_stateful_value_traits.hpp2
-rw-r--r--boost/intrusive/detail/iterator.hpp8
-rw-r--r--boost/intrusive/detail/key_nodeptr_comp.hpp28
-rw-r--r--boost/intrusive/detail/list_iterator.hpp2
-rw-r--r--boost/intrusive/detail/math.hpp8
-rw-r--r--boost/intrusive/detail/mpl.hpp320
-rw-r--r--boost/intrusive/detail/node_cloner_disposer.hpp41
-rw-r--r--boost/intrusive/detail/reverse_iterator.hpp33
-rw-r--r--boost/intrusive/detail/slist_iterator.hpp2
-rw-r--r--boost/intrusive/detail/std_fwd.hpp6
-rw-r--r--boost/intrusive/detail/transform_iterator.hpp13
-rw-r--r--boost/intrusive/detail/tree_iterator.hpp6
-rw-r--r--boost/intrusive/detail/tree_value_compare.hpp78
-rw-r--r--boost/intrusive/hashtable.hpp2320
-rw-r--r--boost/intrusive/intrusive_fwd.hpp18
-rw-r--r--boost/intrusive/list.hpp167
-rw-r--r--boost/intrusive/options.hpp11
-rw-r--r--boost/intrusive/rbtree.hpp236
-rw-r--r--boost/intrusive/rbtree_algorithms.hpp4
-rw-r--r--boost/intrusive/set.hpp390
-rw-r--r--boost/intrusive/sg_set.hpp390
-rw-r--r--boost/intrusive/sgtree.hpp287
-rw-r--r--boost/intrusive/slist.hpp206
-rw-r--r--boost/intrusive/splay_set.hpp416
-rw-r--r--boost/intrusive/splaytree.hpp255
-rw-r--r--boost/intrusive/treap.hpp395
-rw-r--r--boost/intrusive/treap_set.hpp398
-rw-r--r--boost/intrusive/unordered_set.hpp1917
-rw-r--r--boost/iterator/is_lvalue_iterator.hpp26
-rw-r--r--boost/iterator/is_readable_iterator.hpp16
-rw-r--r--boost/iterator/iterator_categories.hpp7
-rw-r--r--boost/iterator/iterator_facade.hpp11
-rw-r--r--boost/lambda/detail/lambda_config.hpp7
-rw-r--r--boost/lambda/detail/lambda_traits.hpp5
-rw-r--r--boost/lambda/detail/operator_return_type_traits.hpp39
-rw-r--r--boost/lambda/detail/operators.hpp18
-rw-r--r--boost/lambda/detail/return_type_traits.hpp25
-rw-r--r--boost/lambda/detail/suppress_unused.hpp4
-rw-r--r--boost/lambda/lambda.hpp5
-rw-r--r--boost/lexical_cast.hpp7
-rw-r--r--boost/lexical_cast/detail/converter_lexical.hpp38
-rw-r--r--boost/lexical_cast/detail/converter_lexical_streams.hpp1
-rw-r--r--boost/lexical_cast/detail/converter_numeric.hpp42
-rw-r--r--boost/lexical_cast/detail/is_character.hpp19
-rw-r--r--boost/lexical_cast/detail/lcast_unsigned_converters.hpp1
-rw-r--r--boost/lexical_cast/try_lexical_convert.hpp53
-rw-r--r--boost/lockfree/detail/copy_payload.hpp9
-rw-r--r--boost/lockfree/detail/freelist.hpp1
-rw-r--r--boost/lockfree/spsc_queue.hpp10
-rw-r--r--boost/log/attributes/attribute_value.hpp8
-rw-r--r--boost/log/attributes/attribute_value_impl.hpp3
-rw-r--r--boost/log/attributes/current_thread_id.hpp2
-rw-r--r--boost/log/attributes/fallback_policy.hpp8
-rw-r--r--boost/log/core/record_view.hpp4
-rw-r--r--boost/log/detail/code_conversion.hpp57
-rw-r--r--boost/log/detail/config.hpp7
-rw-r--r--boost/log/detail/event.hpp44
-rw-r--r--boost/log/detail/is_character_type.hpp75
-rw-r--r--boost/log/detail/is_ostream.hpp (renamed from boost/log/detail/visible_type.hpp)25
-rw-r--r--boost/log/exceptions.hpp6
-rw-r--r--boost/log/expressions/formatters/c_decorator.hpp13
-rw-r--r--boost/log/expressions/formatters/csv_decorator.hpp2
-rw-r--r--boost/log/expressions/formatters/xml_decorator.hpp2
-rw-r--r--boost/log/sinks/event_log_backend.hpp4
-rw-r--r--boost/log/sources/global_logger_storage.hpp42
-rw-r--r--boost/log/support/exception.hpp4
-rw-r--r--boost/log/utility/empty_deleter.hpp42
-rw-r--r--boost/log/utility/explicit_operator_bool.hpp42
-rw-r--r--boost/log/utility/formatting_ostream.hpp126
-rw-r--r--boost/log/utility/intrusive_ref_counter.hpp55
-rw-r--r--boost/log/utility/manipulators/to_log.hpp24
-rw-r--r--boost/log/utility/type_dispatch/date_time_types.hpp94
-rw-r--r--boost/log/utility/type_dispatch/dynamic_type_dispatcher.hpp12
-rw-r--r--boost/log/utility/type_dispatch/standard_types.hpp122
-rw-r--r--boost/log/utility/type_dispatch/static_type_dispatcher.hpp34
-rw-r--r--boost/log/utility/type_dispatch/type_dispatcher.hpp7
-rw-r--r--boost/log/utility/type_info_wrapper.hpp6
-rw-r--r--boost/make_default.hpp40
-rw-r--r--boost/math/cstdfloat/cstdfloat_limits.hpp2
-rw-r--r--boost/math/special_functions/detail/bernoulli_details.hpp2
-rw-r--r--boost/math/tools/big_constant.hpp2
-rw-r--r--boost/math/tools/config.hpp8
-rw-r--r--boost/move/core.hpp61
-rw-r--r--boost/move/detail/meta_utils.hpp196
-rw-r--r--boost/move/detail/meta_utils_core.hpp26
-rw-r--r--boost/move/detail/move_helpers.hpp53
-rw-r--r--boost/move/detail/type_traits.hpp125
-rw-r--r--boost/move/detail/workaround.hpp10
-rw-r--r--boost/move/unique_ptr.hpp22
-rw-r--r--boost/move/utility_core.hpp76
-rw-r--r--boost/mpi/collectives.hpp138
-rw-r--r--boost/mpi/collectives/gatherv.hpp164
-rw-r--r--boost/mpi/collectives/reduce.hpp44
-rw-r--r--boost/mpi/collectives/scatterv.hpp166
-rw-r--r--boost/mpi/communicator.hpp64
-rw-r--r--boost/mpi/config.hpp25
-rw-r--r--boost/mpi/datatype.hpp12
-rw-r--r--boost/mpi/detail/forward_skeleton_iarchive.hpp17
-rw-r--r--boost/mpi/detail/forward_skeleton_oarchive.hpp17
-rw-r--r--boost/mpi/detail/ignore_skeleton_oarchive.hpp18
-rw-r--r--boost/mpi/detail/mpi_datatype_oarchive.hpp9
-rw-r--r--boost/mpi/nonblocking.hpp12
-rw-r--r--boost/mpi/packed_iarchive.hpp22
-rw-r--r--boost/mpi/packed_oarchive.hpp20
-rw-r--r--boost/mpl/aux_/insert_range_impl.hpp35
-rw-r--r--boost/mpl/empty_base.hpp16
-rw-r--r--boost/mpl/empty_sequence.hpp3
-rw-r--r--boost/mpl/map/aux_/insert_range_impl.hpp41
-rw-r--r--boost/mpl/map/aux_/item.hpp3
-rw-r--r--boost/mpl/map/map0.hpp1
-rw-r--r--boost/mpl/set/aux_/insert_range_impl.hpp41
-rw-r--r--boost/mpl/set/aux_/item.hpp2
-rw-r--r--boost/mpl/set/set0.hpp1
-rw-r--r--boost/multi_index/composite_key.hpp18
-rw-r--r--boost/multi_index/detail/archive_constructed.hpp4
-rw-r--r--boost/multi_index/detail/bucket_array.hpp5
-rw-r--r--boost/multi_index/detail/copy_map.hpp15
-rw-r--r--boost/multi_index/detail/hash_index_node.hpp22
-rw-r--r--boost/multi_index/detail/index_loader.hpp5
-rw-r--r--boost/multi_index/detail/index_matcher.hpp5
-rw-r--r--boost/multi_index/detail/index_node_base.hpp8
-rw-r--r--boost/multi_index/detail/ord_index_impl.hpp1567
-rw-r--r--boost/multi_index/detail/ord_index_impl_fwd.hpp128
-rw-r--r--boost/multi_index/detail/ord_index_node.hpp104
-rw-r--r--boost/multi_index/detail/raw_ptr.hpp52
-rw-r--r--boost/multi_index/detail/rnd_index_node.hpp13
-rw-r--r--boost/multi_index/detail/rnd_index_ops.hpp10
-rw-r--r--boost/multi_index/detail/rnk_index_ops.hpp300
-rw-r--r--boost/multi_index/detail/seq_index_node.hpp15
-rw-r--r--boost/multi_index/detail/seq_index_ops.hpp6
-rw-r--r--boost/multi_index/detail/value_compare.hpp9
-rw-r--r--boost/multi_index/global_fun.hpp4
-rw-r--r--boost/multi_index/identity.hpp4
-rw-r--r--boost/multi_index/mem_fun.hpp4
-rw-r--r--boost/multi_index/member.hpp4
-rw-r--r--boost/multi_index/ordered_index.hpp1461
-rw-r--r--boost/multi_index/ordered_index_fwd.hpp93
-rw-r--r--boost/multi_index/random_access_index.hpp7
-rw-r--r--boost/multi_index/ranked_index.hpp382
-rw-r--r--boost/multi_index/ranked_index_fwd.hpp35
-rw-r--r--boost/multi_index/sequenced_index.hpp6
-rw-r--r--boost/multiprecision/concepts/mp_number_archetypes.hpp20
-rw-r--r--boost/multiprecision/cpp_bin_float.hpp50
-rw-r--r--boost/multiprecision/cpp_bin_float/io.hpp10
-rw-r--r--boost/multiprecision/cpp_dec_float.hpp213
-rw-r--r--boost/multiprecision/cpp_int.hpp91
-rw-r--r--boost/multiprecision/cpp_int/add.hpp44
-rw-r--r--boost/multiprecision/cpp_int/bitwise.hpp82
-rw-r--r--boost/multiprecision/cpp_int/checked.hpp4
-rw-r--r--boost/multiprecision/cpp_int/cpp_int_config.hpp10
-rw-r--r--boost/multiprecision/cpp_int/divide.hpp2
-rw-r--r--boost/multiprecision/cpp_int/misc.hpp14
-rw-r--r--boost/multiprecision/cpp_int/multiply.hpp30
-rw-r--r--boost/multiprecision/cpp_int/serialize.hpp2
-rw-r--r--boost/multiprecision/detail/bitscan.hpp10
-rw-r--r--boost/multiprecision/detail/default_ops.hpp44
-rw-r--r--boost/multiprecision/detail/functions/pow.hpp10
-rw-r--r--boost/multiprecision/detail/functions/trig.hpp20
-rw-r--r--boost/multiprecision/detail/generic_interconvert.hpp10
-rw-r--r--boost/multiprecision/detail/number_base.hpp24
-rw-r--r--boost/multiprecision/detail/number_compare.hpp156
-rw-r--r--boost/multiprecision/float128.hpp52
-rw-r--r--boost/multiprecision/gmp.hpp153
-rw-r--r--boost/multiprecision/integer.hpp6
-rw-r--r--boost/multiprecision/mpfi.hpp33
-rw-r--r--boost/multiprecision/mpfr.hpp73
-rw-r--r--boost/multiprecision/number.hpp36
-rw-r--r--boost/multiprecision/rational_adaptor.hpp14
-rw-r--r--boost/multiprecision/tommath.hpp19
-rw-r--r--boost/multiprecision/traits/is_backend.hpp63
-rw-r--r--boost/numeric/odeint/external/openmp/openmp_range_algebra.hpp2
-rw-r--r--boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp2
-rw-r--r--boost/numeric/odeint/integrate/detail/integrate_times.hpp4
-rw-r--r--boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp6
-rw-r--r--boost/numeric/odeint/util/detail/less_with_sign.hpp4
-rw-r--r--boost/numeric/ublas/storage.hpp6
-rw-r--r--boost/optional/optional.hpp54
-rw-r--r--boost/parameter/aux_/arg_list.hpp31
-rw-r--r--boost/parameter/aux_/cast.hpp6
-rw-r--r--[-rwxr-xr-x]boost/parameter/aux_/parenthesized_type.hpp84
-rw-r--r--boost/parameter/aux_/set.hpp3
-rw-r--r--boost/parameter/aux_/tagged_argument.hpp4
-rw-r--r--[-rwxr-xr-x]boost/parameter/aux_/unwrap_cv_reference.hpp6
-rw-r--r--[-rwxr-xr-x]boost/parameter/binding.hpp30
-rw-r--r--[-rwxr-xr-x]boost/parameter/keyword.hpp30
-rw-r--r--boost/parameter/name.hpp20
-rw-r--r--boost/parameter/preprocessor.hpp113
-rw-r--r--[-rwxr-xr-x]boost/parameter/value_type.hpp30
-rw-r--r--boost/phoenix/scope/let.hpp6
-rw-r--r--boost/polygon/detail/voronoi_ctypes.hpp6
-rw-r--r--boost/polygon/voronoi_diagram.hpp4
-rw-r--r--boost/predef.h6
-rw-r--r--boost/predef/architecture.h4
-rw-r--r--boost/predef/architecture/alpha.h7
-rw-r--r--boost/predef/architecture/arm.h7
-rw-r--r--boost/predef/architecture/blackfin.h7
-rw-r--r--boost/predef/architecture/convex.h8
-rw-r--r--boost/predef/architecture/ia64.h6
-rw-r--r--boost/predef/architecture/m68k.h7
-rw-r--r--boost/predef/architecture/mips.h7
-rw-r--r--boost/predef/architecture/parisc.h7
-rw-r--r--boost/predef/architecture/ppc.h7
-rw-r--r--boost/predef/architecture/pyramid.h7
-rw-r--r--boost/predef/architecture/rs6k.h8
-rw-r--r--boost/predef/architecture/sparc.h7
-rw-r--r--boost/predef/architecture/superh.h7
-rw-r--r--boost/predef/architecture/sys370.h7
-rw-r--r--boost/predef/architecture/sys390.h7
-rw-r--r--boost/predef/architecture/x86.h12
-rw-r--r--boost/predef/architecture/x86/32.h8
-rw-r--r--boost/predef/architecture/x86/64.h8
-rw-r--r--boost/predef/architecture/z.h7
-rw-r--r--boost/predef/compiler.h4
-rw-r--r--boost/predef/compiler/borland.h7
-rw-r--r--boost/predef/compiler/clang.h7
-rw-r--r--boost/predef/compiler/comeau.h9
-rw-r--r--boost/predef/compiler/compaq.h7
-rw-r--r--boost/predef/compiler/diab.h7
-rw-r--r--boost/predef/compiler/digitalmars.h7
-rw-r--r--boost/predef/compiler/dignus.h7
-rw-r--r--boost/predef/compiler/edg.h7
-rw-r--r--boost/predef/compiler/ekopath.h7
-rw-r--r--boost/predef/compiler/gcc.h7
-rw-r--r--boost/predef/compiler/gcc_xml.h6
-rw-r--r--boost/predef/compiler/greenhills.h7
-rw-r--r--boost/predef/compiler/hp_acc.h7
-rw-r--r--boost/predef/compiler/iar.h7
-rw-r--r--boost/predef/compiler/ibm.h7
-rw-r--r--boost/predef/compiler/intel.h7
-rw-r--r--boost/predef/compiler/kai.h7
-rw-r--r--boost/predef/compiler/llvm.h7
-rw-r--r--boost/predef/compiler/metaware.h7
-rw-r--r--boost/predef/compiler/metrowerks.h7
-rw-r--r--boost/predef/compiler/microtec.h7
-rw-r--r--boost/predef/compiler/mpw.h7
-rw-r--r--boost/predef/compiler/palm.h7
-rw-r--r--boost/predef/compiler/pgi.h7
-rw-r--r--boost/predef/compiler/sgi_mipspro.h7
-rw-r--r--boost/predef/compiler/sunpro.h25
-rw-r--r--boost/predef/compiler/tendra.h7
-rw-r--r--boost/predef/compiler/visualc.h7
-rw-r--r--boost/predef/compiler/watcom.h7
-rw-r--r--boost/predef/detail/test_def.h71
-rw-r--r--boost/predef/language.h4
-rw-r--r--boost/predef/language/objc.h7
-rw-r--r--boost/predef/language/stdc.h7
-rw-r--r--boost/predef/language/stdcpp.h19
-rw-r--r--boost/predef/library.h4
-rw-r--r--boost/predef/library/c.h4
-rw-r--r--boost/predef/library/c/gnu.h7
-rw-r--r--boost/predef/library/c/uc.h7
-rw-r--r--boost/predef/library/c/vms.h7
-rw-r--r--boost/predef/library/c/zos.h7
-rw-r--r--boost/predef/library/std.h4
-rw-r--r--boost/predef/library/std/cxx.h7
-rw-r--r--boost/predef/library/std/dinkumware.h7
-rw-r--r--boost/predef/library/std/libcomo.h7
-rw-r--r--boost/predef/library/std/modena.h7
-rw-r--r--boost/predef/library/std/msl.h7
-rw-r--r--boost/predef/library/std/roguewave.h7
-rw-r--r--boost/predef/library/std/sgi.h7
-rw-r--r--boost/predef/library/std/stdcpp3.h7
-rw-r--r--boost/predef/library/std/stlport.h7
-rw-r--r--boost/predef/library/std/vacpp.h7
-rw-r--r--boost/predef/make.h4
-rw-r--r--boost/predef/os.h4
-rw-r--r--boost/predef/os/aix.h7
-rw-r--r--boost/predef/os/amigaos.h7
-rw-r--r--boost/predef/os/android.h7
-rw-r--r--boost/predef/os/beos.h7
-rw-r--r--boost/predef/os/bsd.h14
-rw-r--r--boost/predef/os/bsd/bsdi.h6
-rw-r--r--boost/predef/os/bsd/dragonfly.h6
-rw-r--r--boost/predef/os/bsd/free.h6
-rw-r--r--boost/predef/os/bsd/net.h6
-rw-r--r--boost/predef/os/bsd/open.h6
-rw-r--r--boost/predef/os/cygwin.h7
-rw-r--r--boost/predef/os/haiku.h7
-rw-r--r--boost/predef/os/hpux.h7
-rw-r--r--boost/predef/os/ios.h6
-rw-r--r--boost/predef/os/irix.h7
-rw-r--r--boost/predef/os/linux.h7
-rw-r--r--boost/predef/os/macos.h7
-rw-r--r--boost/predef/os/os400.h7
-rw-r--r--boost/predef/os/qnxnto.h7
-rw-r--r--boost/predef/os/solaris.h7
-rw-r--r--boost/predef/os/unix.h6
-rw-r--r--boost/predef/os/vms.h7
-rw-r--r--boost/predef/os/windows.h6
-rw-r--r--boost/predef/other.h4
-rw-r--r--boost/predef/other/endian.h9
-rw-r--r--boost/predef/platform.h4
-rw-r--r--boost/predef/platform/mingw.h7
-rw-r--r--boost/predef/platform/windows_desktop.h5
-rw-r--r--boost/predef/platform/windows_phone.h5
-rw-r--r--boost/predef/platform/windows_runtime.h5
-rw-r--r--boost/predef/platform/windows_store.h5
-rw-r--r--boost/predef/version.h4
-rw-r--r--boost/predef/version_number.h3
-rw-r--r--boost/preprocessor/arithmetic/dec.hpp1
-rw-r--r--boost/preprocessor/config/config.hpp7
-rw-r--r--boost/preprocessor/library.hpp1
-rw-r--r--boost/preprocessor/repetition/for.hpp20
-rw-r--r--boost/preprocessor/seq/detail/is_empty.hpp49
-rw-r--r--boost/preprocessor/seq/for_each.hpp67
-rw-r--r--boost/preprocessor/seq/for_each_i.hpp68
-rw-r--r--boost/preprocessor/seq/replace.hpp20
-rw-r--r--boost/preprocessor/seq/rest_n.hpp20
-rw-r--r--boost/preprocessor/seq/size.hpp1
-rw-r--r--boost/program_options/detail/config_file.hpp16
-rw-r--r--boost/program_options/detail/parsers.hpp3
-rw-r--r--boost/program_options/environment_iterator.hpp5
-rw-r--r--boost/program_options/eof_iterator.hpp34
-rw-r--r--boost/program_options/option.hpp2
-rw-r--r--boost/program_options/options_description.hpp9
-rw-r--r--boost/program_options/parsers.hpp74
-rw-r--r--boost/program_options/value_semantic.hpp28
-rw-r--r--boost/program_options/variables_map.hpp40
-rw-r--r--boost/property_tree/detail/json_parser/narrow_encoding.hpp159
-rw-r--r--boost/property_tree/detail/json_parser/parser.hpp524
-rw-r--r--boost/property_tree/detail/json_parser/read.hpp55
-rw-r--r--boost/property_tree/detail/json_parser/standard_callbacks.hpp152
-rw-r--r--boost/property_tree/detail/json_parser/wide_encoding.hpp171
-rw-r--r--boost/property_tree/detail/json_parser_read.hpp332
-rw-r--r--boost/property_tree/detail/rapidxml.hpp2
-rw-r--r--boost/property_tree/json_parser.hpp9
-rw-r--r--boost/property_tree/ptree_serialization.hpp51
-rw-r--r--boost/python.hpp3
-rw-r--r--boost/python/args.hpp26
-rw-r--r--boost/python/back_reference.hpp31
-rw-r--r--boost/python/bases.hpp18
-rw-r--r--boost/python/class.hpp45
-rw-r--r--[-rwxr-xr-x]boost/python/converter/arg_from_python.hpp4
-rw-r--r--[-rwxr-xr-x]boost/python/converter/arg_to_python_base.hpp8
-rw-r--r--[-rwxr-xr-x]boost/python/converter/object_manager.hpp74
-rw-r--r--boost/python/converter/registered.hpp3
-rw-r--r--boost/python/converter/registered_pointee.hpp32
-rw-r--r--boost/python/copy_const_reference.hpp2
-rw-r--r--boost/python/copy_non_const_reference.hpp2
-rw-r--r--boost/python/data_members.hpp4
-rw-r--r--boost/python/default_call_policies.hpp2
-rw-r--r--[-rwxr-xr-x]boost/python/detail/borrowed_ptr.hpp30
-rw-r--r--boost/python/detail/config.hpp3
-rw-r--r--boost/python/detail/construct.hpp8
-rw-r--r--boost/python/detail/cv_category.hpp2
-rw-r--r--boost/python/detail/destroy.hpp49
-rw-r--r--[-rwxr-xr-x]boost/python/detail/enable_if.hpp35
-rw-r--r--[-rwxr-xr-x]boost/python/detail/force_instantiate.hpp14
-rw-r--r--boost/python/detail/if_else.hpp39
-rw-r--r--boost/python/detail/msvc_typeinfo.hpp19
-rw-r--r--boost/python/detail/referent_storage.hpp10
-rw-r--r--boost/python/detail/result.hpp4
-rw-r--r--boost/python/detail/string_literal.hpp38
-rw-r--r--boost/python/detail/type_list.hpp4
-rw-r--r--boost/python/detail/type_list_impl_no_pts.hpp107
-rw-r--r--boost/python/detail/value_is_xxx.hpp30
-rw-r--r--boost/python/extract.hpp3
-rw-r--r--[-rwxr-xr-x]boost/python/handle.hpp27
-rw-r--r--boost/python/init.hpp22
-rw-r--r--boost/python/make_constructor.hpp9
-rw-r--r--boost/python/manage_new_object.hpp2
-rw-r--r--boost/python/object/class_metadata.hpp4
-rw-r--r--boost/python/object/forward.hpp101
-rw-r--r--boost/python/object/iterator.hpp28
-rw-r--r--boost/python/object/pointer_holder.hpp6
-rw-r--r--boost/python/object/value_holder.hpp6
-rw-r--r--boost/python/object_core.hpp113
-rw-r--r--[-rwxr-xr-x]boost/python/object_items.hpp3
-rw-r--r--boost/python/object_slices.hpp4
-rw-r--r--boost/python/opaque_pointer_converter.hpp13
-rw-r--r--[-rwxr-xr-x]boost/python/other.hpp62
-rw-r--r--[-rwxr-xr-x]boost/python/proxy.hpp4
-rw-r--r--boost/python/ptr.hpp63
-rw-r--r--[-rwxr-xr-x]boost/python/pure_virtual.hpp2
-rw-r--r--boost/python/reference_existing_object.hpp2
-rw-r--r--boost/python/register_ptr_to_python.hpp2
-rw-r--r--[-rwxr-xr-x]boost/python/return_arg.hpp2
-rw-r--r--boost/python/return_internal_reference.hpp2
-rw-r--r--boost/python/suite/indexing/indexing_suite.hpp4
-rw-r--r--boost/python/to_python_converter.hpp5
-rw-r--r--boost/python/to_python_value.hpp5
-rw-r--r--boost/python/type_id.hpp28
-rw-r--r--boost/python/with_custodian_and_ward.hpp4
-rw-r--r--boost/range/adaptor/filtered.hpp43
-rw-r--r--boost/range/adaptor/strided.hpp2
-rw-r--r--boost/range/detail/common.hpp5
-rw-r--r--boost/range/difference_type.hpp22
-rw-r--r--boost/range/iterator.hpp32
-rw-r--r--boost/range/iterator_range_core.hpp4
-rw-r--r--boost/range/size.hpp9
-rw-r--r--boost/range/size_type.hpp33
-rw-r--r--boost/range/sub_range.hpp4
-rw-r--r--boost/serialization/access.hpp8
-rw-r--r--boost/serialization/array.hpp19
-rw-r--r--boost/serialization/base_object.hpp11
-rw-r--r--boost/serialization/binary_object.hpp5
-rw-r--r--boost/serialization/collections_load_imp.hpp153
-rw-r--r--boost/serialization/config.hpp17
-rw-r--r--boost/serialization/deque.hpp22
-rw-r--r--boost/serialization/detail/is_default_constructible.hpp5
-rw-r--r--boost/serialization/detail/shared_count_132.hpp26
-rw-r--r--boost/serialization/detail/shared_ptr_132.hpp9
-rw-r--r--boost/serialization/detail/stack_constructor.hpp6
-rw-r--r--boost/serialization/ephemeral.hpp5
-rw-r--r--boost/serialization/export.hpp13
-rw-r--r--boost/serialization/extended_type_info.hpp16
-rw-r--r--boost/serialization/extended_type_info_no_rtti.hpp10
-rw-r--r--boost/serialization/extended_type_info_typeid.hpp16
-rw-r--r--boost/serialization/factory.hpp1
-rw-r--r--boost/serialization/force_include.hpp6
-rw-r--r--boost/serialization/forward_list.hpp70
-rw-r--r--boost/serialization/level.hpp8
-rw-r--r--boost/serialization/list.hpp20
-rw-r--r--boost/serialization/nvp.hpp5
-rw-r--r--boost/serialization/pfto.hpp78
-rw-r--r--boost/serialization/serialization.hpp31
-rw-r--r--boost/serialization/shared_ptr.hpp8
-rw-r--r--boost/serialization/shared_ptr_132.hpp2
-rw-r--r--boost/serialization/shared_ptr_helper.hpp8
-rw-r--r--boost/serialization/singleton.hpp2
-rw-r--r--boost/serialization/slist.hpp51
-rw-r--r--boost/serialization/smart_cast.hpp88
-rw-r--r--boost/serialization/static_warning.hpp8
-rw-r--r--boost/serialization/strong_typedef.hpp54
-rw-r--r--boost/serialization/type_info_implementation.hpp13
-rw-r--r--boost/serialization/vector.hpp25
-rw-r--r--boost/serialization/void_cast.hpp22
-rw-r--r--boost/signals2/connection.hpp125
-rw-r--r--boost/signals2/deconstruct_ptr.hpp8
-rw-r--r--boost/signals2/detail/auto_buffer.hpp1
-rw-r--r--boost/signals2/detail/lwm_win32_cs.hpp2
-rw-r--r--boost/signals2/detail/signal_template.hpp109
-rw-r--r--boost/signals2/detail/slot_call_iterator.hpp67
-rw-r--r--boost/signals2/detail/variadic_slot_invoker.hpp33
-rw-r--r--boost/signals2/last_value.hpp5
-rw-r--r--boost/signals2/preprocessed_signal.hpp2
-rw-r--r--boost/signals2/signal.hpp1
-rw-r--r--boost/signals2/slot_base.hpp3
-rw-r--r--boost/signals2/variadic_signal.hpp2
-rw-r--r--boost/smart_ptr/detail/shared_count.hpp38
-rw-r--r--boost/smart_ptr/detail/spinlock_gcc_arm.hpp1
-rw-r--r--boost/smart_ptr/shared_ptr.hpp39
-rw-r--r--boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp3
-rw-r--r--boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp11
-rw-r--r--boost/spirit/home/classic/core/non_terminal/impl/static.hpp4
-rw-r--r--boost/spirit/home/classic/core/primitives/primitives.hpp1
-rw-r--r--boost/spirit/home/classic/meta/refactoring.hpp4
-rw-r--r--boost/spirit/home/classic/phoenix/closures.hpp4
-rw-r--r--boost/spirit/home/classic/phoenix/statements.hpp2
-rw-r--r--boost/spirit/home/classic/utility/functor_parser.hpp2
-rw-r--r--boost/spirit/home/classic/utility/impl/chset.ipp6
-rw-r--r--boost/spirit/home/classic/utility/scoped_lock.hpp3
-rw-r--r--boost/spirit/home/karma/detail/output_iterator.hpp12
-rw-r--r--boost/spirit/home/karma/detail/string_generate.hpp34
-rw-r--r--boost/spirit/home/karma/nonterminal/rule.hpp11
-rw-r--r--boost/spirit/home/karma/numeric/detail/real_utils.hpp2
-rw-r--r--boost/spirit/home/lex/argument.hpp10
-rw-r--r--boost/spirit/home/lex/lexer/lexertl/functor_data.hpp2
-rw-r--r--boost/spirit/home/lex/lexer/string_token_def.hpp1
-rw-r--r--boost/spirit/home/qi/nonterminal/rule.hpp10
-rw-r--r--boost/spirit/home/qi/numeric/detail/numeric_utils.hpp35
-rw-r--r--boost/spirit/home/qi/numeric/detail/real_impl.hpp125
-rw-r--r--boost/spirit/home/qi/numeric/numeric_utils.hpp5
-rw-r--r--boost/spirit/home/qi/numeric/real_policies.hpp18
-rw-r--r--boost/spirit/home/support/char_class.hpp1
-rw-r--r--boost/spirit/home/support/detail/lexer/parser/parser.hpp2
-rw-r--r--boost/spirit/home/support/detail/lexer/state_machine.hpp2
-rw-r--r--boost/spirit/home/support/extended_variant.hpp42
-rw-r--r--boost/spirit/home/support/nonterminal/extract_param.hpp39
-rw-r--r--boost/spirit/home/x3.hpp4
-rw-r--r--boost/spirit/home/x3/auxiliary.hpp6
-rw-r--r--boost/spirit/home/x3/auxiliary/any_parser.hpp4
-rw-r--r--boost/spirit/home/x3/auxiliary/attr.hpp12
-rw-r--r--boost/spirit/home/x3/auxiliary/eoi.hpp6
-rw-r--r--boost/spirit/home/x3/auxiliary/eol.hpp6
-rw-r--r--boost/spirit/home/x3/auxiliary/eps.hpp16
-rw-r--r--boost/spirit/home/x3/auxiliary/guard.hpp4
-rw-r--r--boost/spirit/home/x3/binary.hpp (renamed from boost/spirit/home/x3/support/utility/detail/testing.hpp)14
-rw-r--r--boost/spirit/home/x3/binary/binary.hpp175
-rw-r--r--boost/spirit/home/x3/char.hpp5
-rw-r--r--boost/spirit/home/x3/char/any_char.hpp41
-rw-r--r--boost/spirit/home/x3/char/char.hpp105
-rw-r--r--boost/spirit/home/x3/char/char_class.hpp26
-rw-r--r--boost/spirit/home/x3/char/char_class_tags.hpp29
-rw-r--r--boost/spirit/home/x3/char/char_parser.hpp6
-rw-r--r--boost/spirit/home/x3/char/char_set.hpp136
-rw-r--r--boost/spirit/home/x3/char/detail/cast_char.hpp4
-rw-r--r--boost/spirit/home/x3/char/literal_char.hpp10
-rw-r--r--boost/spirit/home/x3/char/negated_char_parser.hpp6
-rw-r--r--boost/spirit/home/x3/char/unicode.hpp6
-rw-r--r--boost/spirit/home/x3/core.hpp4
-rw-r--r--boost/spirit/home/x3/core/action.hpp6
-rw-r--r--boost/spirit/home/x3/core/call.hpp9
-rw-r--r--boost/spirit/home/x3/core/detail/parse_into_container.hpp77
-rw-r--r--boost/spirit/home/x3/core/parse.hpp4
-rw-r--r--boost/spirit/home/x3/core/parser.hpp12
-rw-r--r--boost/spirit/home/x3/core/proxy.hpp4
-rw-r--r--boost/spirit/home/x3/core/skip_over.hpp4
-rw-r--r--boost/spirit/home/x3/directive.hpp14
-rw-r--r--boost/spirit/home/x3/directive/confix.hpp83
-rw-r--r--boost/spirit/home/x3/directive/expect.hpp8
-rw-r--r--boost/spirit/home/x3/directive/lexeme.hpp12
-rw-r--r--boost/spirit/home/x3/directive/matches.hpp51
-rw-r--r--boost/spirit/home/x3/directive/no_case.hpp54
-rw-r--r--boost/spirit/home/x3/directive/no_skip.hpp8
-rw-r--r--boost/spirit/home/x3/directive/omit.hpp8
-rw-r--r--boost/spirit/home/x3/directive/raw.hpp4
-rw-r--r--boost/spirit/home/x3/directive/repeat.hpp157
-rw-r--r--boost/spirit/home/x3/directive/seek.hpp (renamed from boost/spirit/home/x3/extensions/seek.hpp)8
-rw-r--r--boost/spirit/home/x3/directive/skip.hpp16
-rw-r--r--boost/spirit/home/x3/directive/with.hpp6
-rw-r--r--boost/spirit/home/x3/extensions.hpp18
-rw-r--r--boost/spirit/home/x3/nonterminal.hpp4
-rw-r--r--boost/spirit/home/x3/nonterminal/debug_handler_state.hpp4
-rw-r--r--boost/spirit/home/x3/nonterminal/detail/rule.hpp63
-rw-r--r--boost/spirit/home/x3/nonterminal/rule.hpp35
-rw-r--r--boost/spirit/home/x3/nonterminal/simple_trace.hpp4
-rw-r--r--boost/spirit/home/x3/numeric.hpp4
-rw-r--r--boost/spirit/home/x3/numeric/bool.hpp93
-rw-r--r--boost/spirit/home/x3/numeric/bool_policies.hpp16
-rw-r--r--boost/spirit/home/x3/numeric/int.hpp4
-rw-r--r--boost/spirit/home/x3/numeric/real_policies.hpp4
-rw-r--r--boost/spirit/home/x3/numeric/uint.hpp4
-rw-r--r--boost/spirit/home/x3/operator.hpp4
-rw-r--r--boost/spirit/home/x3/operator/alternative.hpp15
-rw-r--r--boost/spirit/home/x3/operator/and_predicate.hpp6
-rw-r--r--boost/spirit/home/x3/operator/detail/alternative.hpp35
-rw-r--r--boost/spirit/home/x3/operator/detail/sequence.hpp62
-rw-r--r--boost/spirit/home/x3/operator/difference.hpp8
-rw-r--r--boost/spirit/home/x3/operator/kleene.hpp6
-rw-r--r--boost/spirit/home/x3/operator/list.hpp6
-rw-r--r--boost/spirit/home/x3/operator/not_predicate.hpp6
-rw-r--r--boost/spirit/home/x3/operator/optional.hpp6
-rw-r--r--boost/spirit/home/x3/operator/plus.hpp6
-rw-r--r--boost/spirit/home/x3/operator/sequence.hpp15
-rw-r--r--boost/spirit/home/x3/string.hpp4
-rw-r--r--boost/spirit/home/x3/string/detail/no_case_string_parse.hpp60
-rw-r--r--boost/spirit/home/x3/string/detail/string_parse.hpp16
-rw-r--r--boost/spirit/home/x3/string/detail/tst.hpp20
-rw-r--r--boost/spirit/home/x3/string/literal_string.hpp162
-rw-r--r--boost/spirit/home/x3/string/symbols.hpp146
-rw-r--r--boost/spirit/home/x3/string/tst.hpp16
-rw-r--r--boost/spirit/home/x3/string/tst_map.hpp12
-rw-r--r--boost/spirit/home/x3/support/ast/variant.hpp29
-rw-r--r--boost/spirit/home/x3/support/context.hpp46
-rw-r--r--boost/spirit/home/x3/support/no_case.hpp102
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp4
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/extract_int.hpp4
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/extract_real.hpp4
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/pow10.hpp4
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/sign.hpp4
-rw-r--r--boost/spirit/home/x3/support/subcontext.hpp10
-rw-r--r--boost/spirit/home/x3/support/traits/attribute_category.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/attribute_of.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/attribute_type.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/container_traits.hpp34
-rw-r--r--boost/spirit/home/x3/support/traits/handles_container.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/has_attribute.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/is_parser.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/is_substitute.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/is_variant.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/make_attribute.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/move_to.hpp8
-rw-r--r--boost/spirit/home/x3/support/traits/numeric_traits.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/optional_traits.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/print_attribute.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/print_token.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/string_traits.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/transform_attribute.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/tuple_traits.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/value_traits.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/variant_find_substitute.hpp4
-rw-r--r--boost/spirit/home/x3/support/traits/variant_has_substitute.hpp4
-rw-r--r--boost/spirit/home/x3/support/unused.hpp11
-rw-r--r--boost/spirit/home/x3/support/utility/annotate_on_success.hpp51
-rw-r--r--boost/spirit/home/x3/support/utility/error_reporting.hpp110
-rw-r--r--boost/spirit/home/x3/support/utility/integer_sequence.hpp94
-rw-r--r--boost/spirit/home/x3/support/utility/is_callable.hpp16
-rw-r--r--boost/spirit/home/x3/support/utility/sfinae.hpp5
-rw-r--r--boost/spirit/home/x3/support/utility/testing.hpp292
-rw-r--r--boost/spirit/home/x3/support/utility/unrefcv.hpp4
-rw-r--r--boost/spirit/home/x3/support/utility/utf8.hpp7
-rw-r--r--boost/spirit/home/x3/version.hpp19
-rw-r--r--boost/spirit/repository/home/karma/nonterminal/subrule.hpp4
-rw-r--r--boost/spirit/repository/home/qi/directive/kwd.hpp2
-rw-r--r--boost/spirit/repository/home/qi/nonterminal/subrule.hpp4
-rw-r--r--boost/spirit/repository/home/qi/operator/keywords.hpp4
-rw-r--r--boost/test/auto_unit_test.hpp12
-rw-r--r--boost/test/data/config.hpp48
-rw-r--r--boost/test/data/dataset.hpp19
-rw-r--r--boost/test/data/generators.hpp19
-rw-r--r--boost/test/data/monomorphic.hpp26
-rw-r--r--boost/test/data/monomorphic/array.hpp113
-rw-r--r--boost/test/data/monomorphic/collection.hpp125
-rw-r--r--boost/test/data/monomorphic/dataset.hpp174
-rw-r--r--boost/test/data/monomorphic/fwd.hpp314
-rw-r--r--boost/test/data/monomorphic/generate.hpp116
-rw-r--r--boost/test/data/monomorphic/generators.hpp20
-rw-r--r--boost/test/data/monomorphic/generators/keywords.hpp39
-rw-r--r--boost/test/data/monomorphic/generators/random.hpp198
-rw-r--r--boost/test/data/monomorphic/generators/xrange.hpp221
-rw-r--r--boost/test/data/monomorphic/grid.hpp226
-rw-r--r--boost/test/data/monomorphic/join.hpp194
-rw-r--r--boost/test/data/monomorphic/singleton.hpp137
-rw-r--r--boost/test/data/monomorphic/zip.hpp240
-rw-r--r--boost/test/data/size.hpp145
-rw-r--r--boost/test/data/test_case.hpp195
-rw-r--r--boost/test/debug.hpp111
-rw-r--r--boost/test/debug_config.hpp14
-rw-r--r--boost/test/detail/config.hpp39
-rw-r--r--boost/test/detail/enable_warnings.hpp19
-rw-r--r--boost/test/detail/fwd_decl.hpp11
-rw-r--r--boost/test/detail/global_typedef.hpp54
-rw-r--r--boost/test/detail/log_level.hpp11
-rw-r--r--boost/test/detail/pp_variadic.hpp49
-rw-r--r--boost/test/detail/suppress_warnings.hpp19
-rw-r--r--boost/test/detail/throw_exception.hpp69
-rw-r--r--boost/test/detail/unit_test_parameters.hpp69
-rw-r--r--boost/test/detail/workaround.hpp19
-rw-r--r--boost/test/exception_safety.hpp187
-rw-r--r--boost/test/execution_monitor.hpp523
-rw-r--r--boost/test/floating_point_comparison.hpp284
-rw-r--r--boost/test/framework.hpp236
-rw-r--r--boost/test/impl/compiler_log_formatter.ipp119
-rw-r--r--boost/test/impl/cpp_main.ipp41
-rw-r--r--boost/test/impl/debug.ipp73
-rw-r--r--boost/test/impl/decorator.ipp202
-rw-r--r--boost/test/impl/exception_safety.ipp537
-rw-r--r--boost/test/impl/execution_monitor.ipp635
-rw-r--r--boost/test/impl/framework.ipp1076
-rw-r--r--boost/test/impl/interaction_based.ipp90
-rw-r--r--boost/test/impl/logged_expectations.ipp246
-rw-r--r--boost/test/impl/plain_report_formatter.ipp103
-rw-r--r--boost/test/impl/progress_monitor.ipp89
-rw-r--r--boost/test/impl/results_collector.ipp126
-rw-r--r--boost/test/impl/results_reporter.ipp22
-rw-r--r--boost/test/impl/test_main.ipp21
-rw-r--r--boost/test/impl/test_tools.ipp431
-rw-r--r--boost/test/impl/test_tree.ipp459
-rw-r--r--boost/test/impl/unit_test_log.ipp89
-rw-r--r--boost/test/impl/unit_test_main.ipp288
-rw-r--r--boost/test/impl/unit_test_monitor.ipp42
-rw-r--r--boost/test/impl/unit_test_parameters.ipp379
-rw-r--r--boost/test/impl/unit_test_suite.ipp346
-rw-r--r--boost/test/impl/xml_log_formatter.ipp82
-rw-r--r--boost/test/impl/xml_report_formatter.ipp29
-rw-r--r--boost/test/included/execution_monitor.hpp21
-rw-r--r--boost/test/included/prg_exec_monitor.hpp4
-rw-r--r--boost/test/included/test_exec_monitor.hpp13
-rw-r--r--boost/test/included/unit_test.hpp17
-rw-r--r--boost/test/included/unit_test_framework.hpp12
-rw-r--r--boost/test/interaction_based.hpp262
-rw-r--r--boost/test/logged_expectations.hpp74
-rw-r--r--boost/test/minimal.hpp39
-rw-r--r--boost/test/mock_object.hpp328
-rw-r--r--boost/test/output/compiler_log_formatter.hpp19
-rw-r--r--boost/test/output/plain_report_formatter.hpp10
-rw-r--r--boost/test/output/xml_log_formatter.hpp22
-rw-r--r--boost/test/output/xml_report_formatter.hpp12
-rw-r--r--boost/test/output_test_stream.hpp76
-rw-r--r--boost/test/parameterized_test.hpp85
-rw-r--r--boost/test/predicate_result.hpp86
-rw-r--r--boost/test/prg_exec_monitor.hpp35
-rw-r--r--boost/test/progress_monitor.hpp42
-rw-r--r--boost/test/results_collector.hpp80
-rw-r--r--boost/test/results_reporter.hpp72
-rw-r--r--boost/test/test_case_template.hpp12
-rw-r--r--boost/test/test_exec_monitor.hpp33
-rw-r--r--boost/test/test_tools.hpp736
-rw-r--r--boost/test/tools/assertion.hpp407
-rw-r--r--boost/test/tools/assertion_result.hpp90
-rw-r--r--boost/test/tools/collection_comparison_op.hpp375
-rw-r--r--boost/test/tools/context.hpp65
-rw-r--r--boost/test/tools/cstring_comparison_op.hpp91
-rw-r--r--boost/test/tools/detail/bitwise_manip.hpp123
-rw-r--r--boost/test/tools/detail/expression_holder.hpp70
-rw-r--r--boost/test/tools/detail/fwd.hpp121
-rw-r--r--boost/test/tools/detail/indirections.hpp94
-rw-r--r--boost/test/tools/detail/it_pair.hpp74
-rw-r--r--boost/test/tools/detail/lexicographic_manip.hpp69
-rw-r--r--boost/test/tools/detail/per_element_manip.hpp69
-rw-r--r--boost/test/tools/detail/print_helper.hpp199
-rw-r--r--boost/test/tools/detail/tolerance_manip.hpp130
-rw-r--r--boost/test/tools/floating_point_comparison.hpp315
-rw-r--r--boost/test/tools/fpc_op.hpp224
-rw-r--r--boost/test/tools/fpc_tolerance.hpp103
-rw-r--r--boost/test/tools/interface.hpp376
-rw-r--r--boost/test/tools/old/impl.hpp358
-rw-r--r--boost/test/tools/old/interface.hpp278
-rw-r--r--boost/test/tools/output_test_stream.hpp96
-rw-r--r--boost/test/tree/auto_registration.hpp53
-rw-r--r--boost/test/tree/decorator.hpp277
-rw-r--r--boost/test/tree/fixture.hpp116
-rw-r--r--boost/test/tree/global_fixture.hpp68
-rw-r--r--boost/test/tree/observer.hpp (renamed from boost/test/test_observer.hpp)33
-rw-r--r--boost/test/tree/test_case_counter.hpp54
-rw-r--r--boost/test/tree/test_case_template.hpp144
-rw-r--r--boost/test/tree/test_unit.hpp275
-rw-r--r--boost/test/tree/traverse.hpp58
-rw-r--r--boost/test/tree/visitor.hpp52
-rw-r--r--boost/test/unit_test.hpp20
-rw-r--r--boost/test/unit_test_log.hpp47
-rw-r--r--boost/test/unit_test_log_formatter.hpp213
-rw-r--r--boost/test/unit_test_monitor.hpp37
-rw-r--r--boost/test/unit_test_parameters.hpp92
-rw-r--r--boost/test/unit_test_suite.hpp230
-rw-r--r--boost/test/unit_test_suite_impl.hpp434
-rw-r--r--boost/test/utils/algorithm.hpp61
-rw-r--r--boost/test/utils/assign_op.hpp12
-rw-r--r--boost/test/utils/basic_cstring/basic_cstring.hpp149
-rw-r--r--boost/test/utils/basic_cstring/basic_cstring_fwd.hpp12
-rw-r--r--boost/test/utils/basic_cstring/bcs_char_traits.hpp18
-rw-r--r--boost/test/utils/basic_cstring/compare.hpp50
-rw-r--r--boost/test/utils/basic_cstring/io.hpp8
-rw-r--r--boost/test/utils/callback.hpp310
-rw-r--r--boost/test/utils/class_properties.hpp38
-rw-r--r--boost/test/utils/custom_manip.hpp14
-rw-r--r--boost/test/utils/fixed_mapping.hpp14
-rw-r--r--boost/test/utils/foreach.hpp61
-rw-r--r--boost/test/utils/is_cstring.hpp58
-rw-r--r--boost/test/utils/is_forward_iterable.hpp152
-rw-r--r--boost/test/utils/iterator/ifstream_line_iterator.hpp13
-rw-r--r--boost/test/utils/iterator/input_iterator_facade.hpp19
-rw-r--r--boost/test/utils/iterator/istream_line_iterator.hpp14
-rw-r--r--boost/test/utils/iterator/token_iterator.hpp28
-rw-r--r--boost/test/utils/lazy_ostream.hpp74
-rw-r--r--boost/test/utils/named_params.hpp101
-rw-r--r--boost/test/utils/nullstream.hpp15
-rw-r--r--boost/test/utils/rtti.hpp15
-rw-r--r--boost/test/utils/runtime/argument.hpp14
-rw-r--r--boost/test/utils/runtime/cla/argument_factory.hpp62
-rw-r--r--boost/test/utils/runtime/cla/argv_traverser.cpp8
-rw-r--r--boost/test/utils/runtime/cla/argv_traverser.hpp24
-rw-r--r--boost/test/utils/runtime/cla/argv_traverser.ipp61
-rw-r--r--boost/test/utils/runtime/cla/basic_parameter.hpp20
-rw-r--r--boost/test/utils/runtime/cla/char_parameter.cpp8
-rw-r--r--boost/test/utils/runtime/cla/char_parameter.hpp28
-rw-r--r--boost/test/utils/runtime/cla/char_parameter.ipp24
-rw-r--r--boost/test/utils/runtime/cla/detail/argument_value_usage.hpp29
-rw-r--r--boost/test/utils/runtime/cla/dual_name_parameter.cpp8
-rw-r--r--boost/test/utils/runtime/cla/dual_name_parameter.hpp26
-rw-r--r--boost/test/utils/runtime/cla/dual_name_parameter.ipp32
-rw-r--r--boost/test/utils/runtime/cla/fwd.hpp16
-rw-r--r--boost/test/utils/runtime/cla/id_policy.cpp8
-rw-r--r--boost/test/utils/runtime/cla/id_policy.hpp30
-rw-r--r--boost/test/utils/runtime/cla/id_policy.ipp34
-rw-r--r--boost/test/utils/runtime/cla/iface/argument_factory.hpp16
-rw-r--r--boost/test/utils/runtime/cla/iface/id_policy.hpp12
-rw-r--r--boost/test/utils/runtime/cla/modifier.hpp16
-rw-r--r--boost/test/utils/runtime/cla/named_parameter.cpp8
-rw-r--r--boost/test/utils/runtime/cla/named_parameter.hpp28
-rw-r--r--boost/test/utils/runtime/cla/named_parameter.ipp40
-rw-r--r--boost/test/utils/runtime/cla/parameter.hpp29
-rw-r--r--boost/test/utils/runtime/cla/parser.cpp10
-rw-r--r--boost/test/utils/runtime/cla/parser.hpp29
-rw-r--r--boost/test/utils/runtime/cla/parser.ipp109
-rw-r--r--boost/test/utils/runtime/cla/positional_parameter.hpp26
-rw-r--r--boost/test/utils/runtime/cla/typed_parameter.hpp24
-rw-r--r--boost/test/utils/runtime/cla/validation.cpp8
-rw-r--r--boost/test/utils/runtime/cla/validation.hpp28
-rw-r--r--boost/test/utils/runtime/cla/validation.ipp40
-rw-r--r--boost/test/utils/runtime/cla/value_generator.hpp16
-rw-r--r--boost/test/utils/runtime/cla/value_handler.hpp16
-rw-r--r--boost/test/utils/runtime/config.hpp66
-rw-r--r--boost/test/utils/runtime/configuration.hpp14
-rw-r--r--boost/test/utils/runtime/env/environment.cpp10
-rw-r--r--boost/test/utils/runtime/env/environment.hpp31
-rw-r--r--boost/test/utils/runtime/env/environment.ipp52
-rw-r--r--boost/test/utils/runtime/env/fwd.hpp21
-rw-r--r--boost/test/utils/runtime/env/modifier.hpp12
-rw-r--r--boost/test/utils/runtime/env/variable.hpp22
-rw-r--r--boost/test/utils/runtime/file/config_file.cpp22
-rw-r--r--boost/test/utils/runtime/file/config_file.hpp22
-rw-r--r--boost/test/utils/runtime/file/config_file_iterator.cpp152
-rw-r--r--boost/test/utils/runtime/file/config_file_iterator.hpp22
-rw-r--r--boost/test/utils/runtime/fwd.hpp14
-rw-r--r--boost/test/utils/runtime/interpret_argument_value.hpp42
-rw-r--r--boost/test/utils/runtime/parameter.hpp14
-rw-r--r--boost/test/utils/runtime/trace.hpp16
-rw-r--r--boost/test/utils/runtime/validation.hpp37
-rw-r--r--boost/test/utils/setcolor.hpp117
-rw-r--r--boost/test/utils/trivial_singleton.hpp33
-rw-r--r--boost/test/utils/wrap_stringstream.hpp16
-rw-r--r--boost/test/utils/xml_printer.hpp34
-rw-r--r--boost/thread/future.hpp164
-rw-r--r--boost/thread/win32/thread_primitives.hpp22
-rw-r--r--boost/type_index/detail/compile_time_type_info.hpp12
-rw-r--r--boost/type_index/stl_type_index.hpp1
-rw-r--r--boost/type_index/type_index_facade.hpp12
-rw-r--r--boost/type_traits/is_virtual_base_of.hpp15
-rw-r--r--boost/units/scaled_base_unit.hpp20
-rw-r--r--boost/uuid/detail/uuid_x86.hpp18
-rw-r--r--boost/uuid/seed_rng.hpp128
-rw-r--r--boost/variant/detail/element_index.hpp4
-rw-r--r--boost/variant/detail/has_result_type.hpp5
-rw-r--r--boost/variant/polymorphic_get.hpp2
-rw-r--r--boost/variant/recursive_wrapper_fwd.hpp18
-rw-r--r--boost/variant/static_visitor.hpp17
-rw-r--r--boost/version.hpp4
-rw-r--r--boost/wave/cpp_exceptions.hpp2
1459 files changed, 52505 insertions, 29848 deletions
diff --git a/boost/align.hpp b/boost/align.hpp
index d5ae6d3704..0b3221dffc 100644
--- a/boost/align.hpp
+++ b/boost/align.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014-2015 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_HPP
#define BOOST_ALIGN_HPP
@@ -15,6 +15,7 @@
#include <boost/align/aligned_allocator_adaptor.hpp>
#include <boost/align/aligned_delete.hpp>
#include <boost/align/alignment_of.hpp>
+#include <boost/align/assume_aligned.hpp>
#include <boost/align/is_aligned.hpp>
#endif
diff --git a/boost/align/align.hpp b/boost/align/align.hpp
index 1600a243c0..b95d673bcd 100644
--- a/boost/align/align.hpp
+++ b/boost/align/align.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGN_HPP
#define BOOST_ALIGN_ALIGN_HPP
diff --git a/boost/align/aligned_alloc.hpp b/boost/align/aligned_alloc.hpp
index 1e4f2b783b..0e3ba60641 100644
--- a/boost/align/aligned_alloc.hpp
+++ b/boost/align/aligned_alloc.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGNED_ALLOC_HPP
#define BOOST_ALIGN_ALIGNED_ALLOC_HPP
diff --git a/boost/align/aligned_allocator.hpp b/boost/align/aligned_allocator.hpp
index 114e37bb1c..a31dfe599f 100644
--- a/boost/align/aligned_allocator.hpp
+++ b/boost/align/aligned_allocator.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGNED_ALLOCATOR_HPP
#define BOOST_ALIGN_ALIGNED_ALLOCATOR_HPP
@@ -26,143 +26,141 @@
#endif
namespace boost {
- namespace alignment {
- template<class T, std::size_t Alignment>
- class aligned_allocator {
- BOOST_STATIC_ASSERT(detail::
- is_alignment_constant<Alignment>::value);
-
- public:
- typedef T value_type;
- typedef T* pointer;
- typedef const T* const_pointer;
- typedef void* void_pointer;
- typedef const void* const_void_pointer;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
- typedef T& reference;
- typedef const T& const_reference;
-
- private:
- typedef detail::max_align<Alignment,
- alignment_of<value_type>::value> MaxAlign;
-
- public:
- template<class U>
- struct rebind {
- typedef aligned_allocator<U, Alignment> other;
- };
+namespace alignment {
+
+template<class T, std::size_t Alignment>
+class aligned_allocator {
+ BOOST_STATIC_ASSERT(detail::
+ is_alignment_constant<Alignment>::value);
+
+public:
+ typedef T value_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef void* void_pointer;
+ typedef const void* const_void_pointer;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+
+private:
+ enum {
+ min_align = detail::max_align<Alignment,
+ alignment_of<value_type>::value>::value
+ };
+
+public:
+ template<class U>
+ struct rebind {
+ typedef aligned_allocator<U, Alignment> other;
+ };
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
- aligned_allocator()
- BOOST_NOEXCEPT = default;
+ aligned_allocator() BOOST_NOEXCEPT = default;
#else
- aligned_allocator()
- BOOST_NOEXCEPT {
- }
+ aligned_allocator() BOOST_NOEXCEPT {
+ }
#endif
- template<class U>
- aligned_allocator(const aligned_allocator<U,
- Alignment>&) BOOST_NOEXCEPT {
- }
-
- pointer address(reference value) const
- BOOST_NOEXCEPT {
- return detail::addressof(value);
- }
-
- const_pointer address(const_reference value) const
- BOOST_NOEXCEPT {
- return detail::addressof(value);
- }
-
- pointer allocate(size_type size,
- const_void_pointer = 0) {
- void* p = aligned_alloc(MaxAlign::value,
- sizeof(T) * size);
- if (!p && size > 0) {
- boost::throw_exception(std::bad_alloc());
- }
- return static_cast<T*>(p);
- }
-
- void deallocate(pointer ptr, size_type) {
- alignment::aligned_free(ptr);
- }
-
- BOOST_CONSTEXPR size_type max_size() const
- BOOST_NOEXCEPT {
- return detail::max_count_of<T>::value;
- }
+ template<class U>
+ aligned_allocator(const aligned_allocator<U, Alignment>&)
+ BOOST_NOEXCEPT {
+ }
+
+ pointer address(reference value) const BOOST_NOEXCEPT {
+ return detail::addressof(value);
+ }
+
+ const_pointer address(const_reference value) const
+ BOOST_NOEXCEPT {
+ return detail::addressof(value);
+ }
+
+ pointer allocate(size_type size, const_void_pointer = 0) {
+ void* p = aligned_alloc(min_align, sizeof(T) * size);
+ if (!p && size > 0) {
+ boost::throw_exception(std::bad_alloc());
+ }
+ return static_cast<T*>(p);
+ }
+
+ void deallocate(pointer ptr, size_type) {
+ alignment::aligned_free(ptr);
+ }
+
+ BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT {
+ return detail::max_count_of<T>::value;
+ }
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- template<class U, class... Args>
- void construct(U* ptr, Args&&... args) {
- void* p = ptr;
- ::new(p) U(std::forward<Args>(args)...);
- }
+ template<class U, class... Args>
+ void construct(U* ptr, Args&&... args) {
+ void* p = ptr;
+ ::new(p) U(std::forward<Args>(args)...);
+ }
#else
- template<class U, class V>
- void construct(U* ptr, V&& value) {
- void* p = ptr;
- ::new(p) U(std::forward<V>(value));
- }
+ template<class U, class V>
+ void construct(U* ptr, V&& value) {
+ void* p = ptr;
+ ::new(p) U(std::forward<V>(value));
+ }
#endif
#else
- template<class U, class V>
- void construct(U* ptr, const V& value) {
- void* p = ptr;
- ::new(p) U(value);
- }
+ template<class U, class V>
+ void construct(U* ptr, const V& value) {
+ void* p = ptr;
+ ::new(p) U(value);
+ }
#endif
- template<class U>
- void construct(U* ptr) {
- void* p = ptr;
- ::new(p) U();
- }
-
- template<class U>
- void destroy(U* ptr) {
- (void)ptr;
- ptr->~U();
- }
- };
-
- template<std::size_t Alignment>
- class aligned_allocator<void, Alignment> {
- BOOST_STATIC_ASSERT(detail::
- is_alignment_constant<Alignment>::value);
-
- public:
- typedef void value_type;
- typedef void* pointer;
- typedef const void* const_pointer;
-
- template<class U>
- struct rebind {
- typedef aligned_allocator<U, Alignment> other;
- };
- };
-
- template<class T1, class T2, std::size_t Alignment>
- inline bool operator==(const aligned_allocator<T1,
- Alignment>&, const aligned_allocator<T2,
- Alignment>&) BOOST_NOEXCEPT
- {
- return true;
- }
+ template<class U>
+ void construct(U* ptr) {
+ void* p = ptr;
+ ::new(p) U();
+ }
- template<class T1, class T2, std::size_t Alignment>
- inline bool operator!=(const aligned_allocator<T1,
- Alignment>&, const aligned_allocator<T2,
- Alignment>&) BOOST_NOEXCEPT
- {
- return false;
- }
+ template<class U>
+ void destroy(U* ptr) {
+ (void)ptr;
+ ptr->~U();
}
+};
+
+template<std::size_t Alignment>
+class aligned_allocator<void, Alignment> {
+ BOOST_STATIC_ASSERT(detail::
+ is_alignment_constant<Alignment>::value);
+
+public:
+ typedef void value_type;
+ typedef void* pointer;
+ typedef const void* const_pointer;
+
+ template<class U>
+ struct rebind {
+ typedef aligned_allocator<U, Alignment> other;
+ };
+};
+
+template<class T1, class T2, std::size_t Alignment>
+inline bool operator==(const aligned_allocator<T1,
+ Alignment>&, const aligned_allocator<T2,
+ Alignment>&) BOOST_NOEXCEPT
+{
+ return true;
}
+template<class T1, class T2, std::size_t Alignment>
+inline bool operator!=(const aligned_allocator<T1,
+ Alignment>&, const aligned_allocator<T2,
+ Alignment>&) BOOST_NOEXCEPT
+{
+ return false;
+}
+
+} /* :alignment */
+} /* :boost */
+
#endif
diff --git a/boost/align/aligned_allocator_adaptor.hpp b/boost/align/aligned_allocator_adaptor.hpp
index f6e0bef8aa..ac77b4ab9e 100644
--- a/boost/align/aligned_allocator_adaptor.hpp
+++ b/boost/align/aligned_allocator_adaptor.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014-2015 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
#define BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
@@ -28,160 +28,163 @@
#endif
namespace boost {
- namespace alignment {
- template<class Allocator, std::size_t Alignment>
- class aligned_allocator_adaptor
- : public Allocator {
- BOOST_STATIC_ASSERT(detail::
- is_alignment_constant<Alignment>::value);
+namespace alignment {
+
+template<class Allocator, std::size_t Alignment>
+class aligned_allocator_adaptor
+ : public Allocator {
+ BOOST_STATIC_ASSERT(detail::
+ is_alignment_constant<Alignment>::value);
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
- typedef std::allocator_traits<Allocator> Traits;
+ typedef std::allocator_traits<Allocator> traits;
- typedef typename Traits::
- template rebind_alloc<char> CharAlloc;
+ typedef typename traits::
+ template rebind_alloc<char> char_alloc;
- typedef typename Traits::
- template rebind_traits<char> CharTraits;
+ typedef typename traits::
+ template rebind_traits<char> char_traits;
- typedef typename CharTraits::pointer CharPtr;
+ typedef typename char_traits::pointer char_ptr;
#else
- typedef typename Allocator::
- template rebind<char>::other CharAlloc;
+ typedef typename Allocator::
+ template rebind<char>::other char_alloc;
- typedef typename CharAlloc::pointer CharPtr;
+ typedef typename char_alloc::pointer char_ptr;
#endif
- public:
+ enum {
+ ptr_align = alignment_of<char_ptr>::value
+ };
+
+public:
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
- typedef typename Traits::value_type value_type;
- typedef typename Traits::size_type size_type;
+ typedef typename traits::value_type value_type;
+ typedef typename traits::size_type size_type;
#else
- typedef typename Allocator::value_type value_type;
- typedef typename Allocator::size_type size_type;
+ typedef typename Allocator::value_type value_type;
+ typedef typename Allocator::size_type size_type;
#endif
- typedef value_type* pointer;
- typedef const value_type* const_pointer;
- typedef void* void_pointer;
- typedef const void* const_void_pointer;
- typedef std::ptrdiff_t difference_type;
-
- private:
- typedef detail::max_align<Alignment,
- detail::max_align<alignment_of<value_type>::value,
- alignment_of<CharPtr>::value>::value> MaxAlign;
-
- public:
- template<class U>
- struct rebind {
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef void* void_pointer;
+ typedef const void* const_void_pointer;
+ typedef std::ptrdiff_t difference_type;
+
+private:
+ enum {
+ min_align = detail::max_align<Alignment,
+ detail::max_align<alignment_of<value_type>::value,
+ alignment_of<char_ptr>::value>::value>::value
+ };
+
+public:
+ template<class U>
+ struct rebind {
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
- typedef aligned_allocator_adaptor<typename Traits::
- template rebind_alloc<U>, Alignment> other;
+ typedef aligned_allocator_adaptor<typename traits::
+ template rebind_alloc<U>, Alignment> other;
#else
- typedef aligned_allocator_adaptor<typename Allocator::
- template rebind<U>::other, Alignment> other;
+ typedef aligned_allocator_adaptor<typename Allocator::
+ template rebind<U>::other, Alignment> other;
#endif
- };
+ };
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
- aligned_allocator_adaptor() = default;
+ aligned_allocator_adaptor() = default;
#else
- aligned_allocator_adaptor()
- : Allocator() {
- }
+ aligned_allocator_adaptor()
+ : Allocator() {
+ }
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
- template<class A>
- explicit aligned_allocator_adaptor(A&& alloc)
- BOOST_NOEXCEPT
- : Allocator(std::forward<A>(alloc)) {
- }
+ template<class A>
+ explicit aligned_allocator_adaptor(A&& alloc) BOOST_NOEXCEPT
+ : Allocator(std::forward<A>(alloc)) {
+ }
#else
- template<class A>
- explicit aligned_allocator_adaptor(const A& alloc)
- BOOST_NOEXCEPT
- : Allocator(alloc) {
- }
+ template<class A>
+ explicit aligned_allocator_adaptor(const A& alloc)
+ BOOST_NOEXCEPT
+ : Allocator(alloc) {
+ }
#endif
- template<class U>
- aligned_allocator_adaptor(const
- aligned_allocator_adaptor<U, Alignment>& other)
- BOOST_NOEXCEPT
- : Allocator(other.base()) {
- }
-
- Allocator& base()
- BOOST_NOEXCEPT {
- return static_cast<Allocator&>(*this);
- }
-
- const Allocator& base() const
- BOOST_NOEXCEPT {
- return static_cast<const Allocator&>(*this);
- }
-
- pointer allocate(size_type size) {
- std::size_t n1 = size * sizeof(value_type);
- std::size_t n2 = n1 + MaxAlign::value - 1;
- CharAlloc a(base());
- CharPtr p1 = a.allocate(sizeof p1 + n2);
- void* p2 = detail::addressof(*p1) + sizeof p1;
- (void)align(MaxAlign::value, n1, p2, n2);
- void* p3 = static_cast<CharPtr*>(p2) - 1;
- ::new(p3) CharPtr(p1);
- return static_cast<pointer>(p2);
- }
-
- pointer allocate(size_type size, const_void_pointer hint) {
- std::size_t n1 = size * sizeof(value_type);
- std::size_t n2 = n1 + MaxAlign::value - 1;
- CharPtr h = CharPtr();
- if (hint) {
- h = *(static_cast<const CharPtr*>(hint) - 1);
- }
- CharAlloc a(base());
+ template<class U>
+ aligned_allocator_adaptor(const aligned_allocator_adaptor<U,
+ Alignment>& other) BOOST_NOEXCEPT
+ : Allocator(other.base()) {
+ }
+
+ Allocator& base() BOOST_NOEXCEPT {
+ return static_cast<Allocator&>(*this);
+ }
+
+ const Allocator& base() const BOOST_NOEXCEPT {
+ return static_cast<const Allocator&>(*this);
+ }
+
+ pointer allocate(size_type size) {
+ std::size_t n1 = size * sizeof(value_type);
+ std::size_t n2 = n1 + min_align - ptr_align;
+ char_alloc a(base());
+ char_ptr p1 = a.allocate(sizeof p1 + n2);
+ void* p2 = detail::addressof(*p1) + sizeof p1;
+ (void)align(min_align, n1, p2, n2);
+ void* p3 = static_cast<char_ptr*>(p2) - 1;
+ ::new(p3) char_ptr(p1);
+ return static_cast<pointer>(p2);
+ }
+
+ pointer allocate(size_type size, const_void_pointer hint) {
+ std::size_t n1 = size * sizeof(value_type);
+ std::size_t n2 = n1 + min_align - ptr_align;
+ char_ptr h = char_ptr();
+ if (hint) {
+ h = *(static_cast<const char_ptr*>(hint) - 1);
+ }
+ char_alloc a(base());
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
- CharPtr p1 = CharTraits::allocate(a, sizeof p1 +
- n2, h);
+ char_ptr p1 = char_traits::allocate(a, sizeof p1 + n2, h);
#else
- CharPtr p1 = a.allocate(sizeof p1 + n2, h);
+ char_ptr p1 = a.allocate(sizeof p1 + n2, h);
#endif
- void* p2 = detail::addressof(*p1) + sizeof p1;
- (void)align(MaxAlign::value, n1, p2, n2);
- void* p3 = static_cast<CharPtr*>(p2) - 1;
- ::new(p3) CharPtr(p1);
- return static_cast<pointer>(p2);
- }
-
- void deallocate(pointer ptr, size_type size) {
- CharPtr* p1 = reinterpret_cast<CharPtr*>(ptr) - 1;
- CharPtr p2 = *p1;
- p1->~CharPtr();
- CharAlloc a(base());
- a.deallocate(p2, size * sizeof(value_type) +
- MaxAlign::value + sizeof p2);
- }
- };
-
- template<class A1, class A2, std::size_t Alignment>
- inline bool operator==(const aligned_allocator_adaptor<A1,
- Alignment>& a, const aligned_allocator_adaptor<A2,
- Alignment>& b) BOOST_NOEXCEPT
- {
- return a.base() == b.base();
- }
+ void* p2 = detail::addressof(*p1) + sizeof p1;
+ (void)align(min_align, n1, p2, n2);
+ void* p3 = static_cast<char_ptr*>(p2) - 1;
+ ::new(p3) char_ptr(p1);
+ return static_cast<pointer>(p2);
+ }
- template<class A1, class A2, std::size_t Alignment>
- inline bool operator!=(const aligned_allocator_adaptor<A1,
- Alignment>& a, const aligned_allocator_adaptor<A2,
- Alignment>& b) BOOST_NOEXCEPT
- {
- return !(a == b);
- }
+ void deallocate(pointer ptr, size_type size) {
+ char_ptr* p1 = reinterpret_cast<char_ptr*>(ptr) - 1;
+ char_ptr p2 = *p1;
+ p1->~char_ptr();
+ char_alloc a(base());
+ a.deallocate(p2, size * sizeof(value_type) +
+ min_align - ptr_align + sizeof p2);
}
+};
+
+template<class A1, class A2, std::size_t Alignment>
+inline bool operator==(const aligned_allocator_adaptor<A1,
+ Alignment>& a, const aligned_allocator_adaptor<A2,
+ Alignment>& b) BOOST_NOEXCEPT
+{
+ return a.base() == b.base();
}
+template<class A1, class A2, std::size_t Alignment>
+inline bool operator!=(const aligned_allocator_adaptor<A1,
+ Alignment>& a, const aligned_allocator_adaptor<A2,
+ Alignment>& b) BOOST_NOEXCEPT
+{
+ return !(a == b);
+}
+
+} /* :alignment */
+} /* :boost */
+
#endif
diff --git a/boost/align/aligned_allocator_adaptor_forward.hpp b/boost/align/aligned_allocator_adaptor_forward.hpp
index 2bd8deecfa..327d7edbf9 100644
--- a/boost/align/aligned_allocator_adaptor_forward.hpp
+++ b/boost/align/aligned_allocator_adaptor_forward.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_FORWARD_HPP
#define BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_FORWARD_HPP
@@ -12,10 +12,12 @@
#include <cstddef>
namespace boost {
- namespace alignment {
- template<class Allocator, std::size_t Alignment = 1>
- class aligned_allocator_adaptor;
- }
-}
+namespace alignment {
+
+template<class Allocator, std::size_t Alignment = 1>
+class aligned_allocator_adaptor;
+
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/aligned_allocator_forward.hpp b/boost/align/aligned_allocator_forward.hpp
index 48120e2e7d..9a3f3635db 100644
--- a/boost/align/aligned_allocator_forward.hpp
+++ b/boost/align/aligned_allocator_forward.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGNED_ALLOCATOR_FORWARD_HPP
#define BOOST_ALIGN_ALIGNED_ALLOCATOR_FORWARD_HPP
@@ -12,10 +12,12 @@
#include <cstddef>
namespace boost {
- namespace alignment {
- template<class T, std::size_t Alignment = 1>
- class aligned_allocator;
- }
-}
+namespace alignment {
+
+template<class T, std::size_t Alignment = 1>
+class aligned_allocator;
+
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/aligned_delete.hpp b/boost/align/aligned_delete.hpp
index 479fbb16be..6d8caed302 100644
--- a/boost/align/aligned_delete.hpp
+++ b/boost/align/aligned_delete.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGNED_DELETE_HPP
#define BOOST_ALIGN_ALIGNED_DELETE_HPP
@@ -14,19 +14,21 @@
#include <boost/align/aligned_delete_forward.hpp>
namespace boost {
- namespace alignment {
- class aligned_delete {
- public:
- template<class T>
- void operator()(T* ptr) const
- BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(ptr->~T())) {
- if (ptr) {
- ptr->~T();
- alignment::aligned_free(ptr);
- }
- }
- };
+namespace alignment {
+
+class aligned_delete {
+public:
+ template<class T>
+ void operator()(T* ptr) const
+ BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(ptr->~T())) {
+ if (ptr) {
+ ptr->~T();
+ alignment::aligned_free(ptr);
+ }
}
-}
+};
+
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/aligned_delete_forward.hpp b/boost/align/aligned_delete_forward.hpp
index 9392025375..530e0970d3 100644
--- a/boost/align/aligned_delete_forward.hpp
+++ b/boost/align/aligned_delete_forward.hpp
@@ -1,18 +1,20 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGNED_DELETE_FORWARD_HPP
#define BOOST_ALIGN_ALIGNED_DELETE_FORWARD_HPP
namespace boost {
- namespace alignment {
- class aligned_delete;
- }
-}
+namespace alignment {
+
+class aligned_delete;
+
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/alignment_of.hpp b/boost/align/alignment_of.hpp
index 1862f0f892..06d22a0259 100644
--- a/boost/align/alignment_of.hpp
+++ b/boost/align/alignment_of.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014-2015 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGNMENT_OF_HPP
#define BOOST_ALIGN_ALIGNMENT_OF_HPP
@@ -13,18 +13,20 @@
#include <boost/align/alignment_of_forward.hpp>
#include <boost/align/detail/remove_traits.hpp>
-#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
-#include <boost/align/detail/alignment_of_cxx11.hpp>
-#elif defined(BOOST_MSVC)
+#if defined(BOOST_MSVC)
#include <boost/align/detail/alignment_of_msvc.hpp>
-#elif defined(BOOST_CLANG)
-#include <boost/align/detail/alignment_of_clang.hpp>
+#elif defined(__GNUC__) && defined(__unix__) && !defined(__LP64__)
+#include <boost/align/detail/alignment_of.hpp>
+#elif defined(BOOST_CLANG) && !defined(__x86_64__)
+#include <boost/align/detail/alignment_of.hpp>
+#elif !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
+#include <boost/align/detail/alignment_of_cxx11.hpp>
#elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
#include <boost/align/detail/alignment_of_gcc.hpp>
#elif defined(__CODEGEARC__)
#include <boost/align/detail/alignment_of_codegear.hpp>
-#elif defined(__GNUC__) && defined(__unix__) && !defined(__LP64__)
-#include <boost/align/detail/alignment_of.hpp>
+#elif defined(BOOST_CLANG)
+#include <boost/align/detail/alignment_of_clang.hpp>
#elif __GNUC__ > 4
#include <boost/align/detail/alignment_of_gcc.hpp>
#elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)
@@ -34,16 +36,18 @@
#endif
namespace boost {
- namespace alignment {
- template<class T>
- struct alignment_of
- : detail::alignment_of<typename
- detail::remove_cv<typename
- detail::remove_all_extents<typename
- detail::remove_reference<T>::
- type>::type>::type>::type {
- };
- }
-}
+namespace alignment {
+
+template<class T>
+struct alignment_of
+ : detail::alignment_of<typename
+ detail::remove_cv<typename
+ detail::remove_all_extents<typename
+ detail::remove_reference<T>::
+ type>::type>::type>::type {
+};
+
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/alignment_of_forward.hpp b/boost/align/alignment_of_forward.hpp
index 47785e24b4..778a9f73b8 100644
--- a/boost/align/alignment_of_forward.hpp
+++ b/boost/align/alignment_of_forward.hpp
@@ -1,19 +1,21 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGNMENT_OF_FORWARD_HPP
#define BOOST_ALIGN_ALIGNMENT_OF_FORWARD_HPP
namespace boost {
- namespace alignment {
- template<class T>
- struct alignment_of;
- }
-}
+namespace alignment {
+
+template<class T>
+struct alignment_of;
+
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/assume_aligned.hpp b/boost/align/assume_aligned.hpp
new file mode 100644
index 0000000000..8d730e6d79
--- /dev/null
+++ b/boost/align/assume_aligned.hpp
@@ -0,0 +1,29 @@
+/*
+(c) 2015 NumScale SAS
+(c) 2015 LRI UMR 8623 CNRS/University Paris Sud XI
+
+(c) 2015 Glen Joseph Fernandes
+glenjofe at gmail dot com
+
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
+*/
+#ifndef BOOST_ALIGN_ASSUME_ALIGNED_HPP
+#define BOOST_ALIGN_ASSUME_ALIGNED_HPP
+
+#include <boost/config.hpp>
+
+#if defined(BOOST_MSVC)
+#include <boost/align/detail/assume_aligned_msvc.hpp>
+#elif defined(BOOST_CLANG)
+#include <boost/align/detail/assume_aligned_clang.hpp>
+#elif BOOST_GCC_VERSION >= 40700
+#include <boost/align/detail/assume_aligned_gcc.hpp>
+#elif defined(__INTEL_COMPILER)
+#include <boost/align/detail/assume_aligned_intel.hpp>
+#else
+#include <boost/align/detail/assume_aligned.hpp>
+#endif
+
+#endif
diff --git a/boost/align/detail/address.hpp b/boost/align/detail/address.hpp
index a4f3a6e84d..63be1a95d0 100644
--- a/boost/align/detail/address.hpp
+++ b/boost/align/detail/address.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ADDRESS_HPP
#define BOOST_ALIGN_DETAIL_ADDRESS_HPP
@@ -13,15 +13,17 @@
#include <cstddef>
namespace boost {
- namespace alignment {
- namespace detail {
+namespace alignment {
+namespace detail {
+
#if defined(BOOST_HAS_INTPTR_T)
- typedef boost::uintptr_t address_t;
+typedef boost::uintptr_t address_t;
#else
- typedef std::size_t address_t;
+typedef std::size_t address_t;
#endif
- }
- }
-}
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/addressof.hpp b/boost/align/detail/addressof.hpp
index d9d6f78ebc..8f0c88204e 100644
--- a/boost/align/detail/addressof.hpp
+++ b/boost/align/detail/addressof.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ADDRESSOF_HPP
#define BOOST_ALIGN_DETAIL_ADDRESSOF_HPP
@@ -18,15 +18,17 @@
#endif
namespace boost {
- namespace alignment {
- namespace detail {
+namespace alignment {
+namespace detail {
+
#if !defined(BOOST_NO_CXX11_ADDRESSOF)
- using std::addressof;
+using std::addressof;
#else
- using boost::addressof;
+using boost::addressof;
#endif
- }
- }
-}
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/align.hpp b/boost/align/detail/align.hpp
index e3a90dffda..00be6fd6aa 100644
--- a/boost/align/detail/align.hpp
+++ b/boost/align/detail/align.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGN_HPP
#define BOOST_ALIGN_DETAIL_ALIGN_HPP
@@ -15,24 +15,26 @@
#include <cstddef>
namespace boost {
- namespace alignment {
- inline void* align(std::size_t alignment, std::size_t size,
- void*& ptr, std::size_t& space)
- {
- BOOST_ASSERT(detail::is_alignment(alignment));
- std::size_t n = detail::address_t(ptr) & (alignment - 1);
- if (n != 0) {
- n = alignment - n;
- }
- void* p = 0;
- if (n <= space && size <= space - n) {
- p = static_cast<char*>(ptr) + n;
- ptr = p;
- space -= n;
- }
- return p;
- }
+namespace alignment {
+
+inline void* align(std::size_t alignment, std::size_t size,
+ void*& ptr, std::size_t& space)
+{
+ BOOST_ASSERT(detail::is_alignment(alignment));
+ std::size_t n = detail::address_t(ptr) & (alignment - 1);
+ if (n != 0) {
+ n = alignment - n;
+ }
+ void* p = 0;
+ if (n <= space && size <= space - n) {
+ p = static_cast<char*>(ptr) + n;
+ ptr = p;
+ space -= n;
}
+ return p;
}
+} /* :alignment */
+} /* :boost */
+
#endif
diff --git a/boost/align/detail/align_cxx11.hpp b/boost/align/detail/align_cxx11.hpp
index 6672a7e0e9..80dc7e36a4 100644
--- a/boost/align/detail/align_cxx11.hpp
+++ b/boost/align/detail/align_cxx11.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGN_CXX11_HPP
#define BOOST_ALIGN_DETAIL_ALIGN_CXX11_HPP
@@ -12,9 +12,11 @@
#include <memory>
namespace boost {
- namespace alignment {
- using std::align;
- }
-}
+namespace alignment {
+
+using std::align;
+
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/aligned_alloc.hpp b/boost/align/detail/aligned_alloc.hpp
index 147b0de0f9..1852ac15a6 100644
--- a/boost/align/detail/aligned_alloc.hpp
+++ b/boost/align/detail/aligned_alloc.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014-2015 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGNED_ALLOC_HPP
#define BOOST_ALIGN_DETAIL_ALIGNED_ALLOC_HPP
@@ -17,34 +17,38 @@
#include <cstdlib>
namespace boost {
- namespace alignment {
- inline void* aligned_alloc(std::size_t alignment,
- std::size_t size) BOOST_NOEXCEPT
- {
- BOOST_ASSERT(detail::is_alignment(alignment));
- if (alignment < alignment_of<void*>::value) {
- alignment = alignment_of<void*>::value;
- }
- std::size_t n = size + alignment - 1;
- void* p1 = 0;
- void* p2 = std::malloc(n + sizeof p1);
- if (p2) {
- p1 = static_cast<char*>(p2) + sizeof p1;
- (void)align(alignment, size, p1, n);
- *(static_cast<void**>(p1) - 1) = p2;
- }
- return p1;
- }
+namespace alignment {
- inline void aligned_free(void* ptr)
- BOOST_NOEXCEPT
- {
- if (ptr) {
- void* p = *(static_cast<void**>(ptr) - 1);
- std::free(p);
- }
- }
+inline void* aligned_alloc(std::size_t alignment, std::size_t size)
+ BOOST_NOEXCEPT
+{
+ BOOST_ASSERT(detail::is_alignment(alignment));
+ enum {
+ N = alignment_of<void*>::value
+ };
+ if (alignment < N) {
+ alignment = N;
}
+ std::size_t n = size + alignment - N;
+ void* p1 = 0;
+ void* p2 = std::malloc(n + sizeof p1);
+ if (p2) {
+ p1 = static_cast<char*>(p2) + sizeof p1;
+ (void)align(alignment, size, p1, n);
+ *(static_cast<void**>(p1) - 1) = p2;
+ }
+ return p1;
}
+inline void aligned_free(void* ptr) BOOST_NOEXCEPT
+{
+ if (ptr) {
+ void* p = *(static_cast<void**>(ptr) - 1);
+ std::free(p);
+ }
+}
+
+} /* :alignment */
+} /* :boost */
+
#endif
diff --git a/boost/align/detail/aligned_alloc_android.hpp b/boost/align/detail/aligned_alloc_android.hpp
index 2b813becae..d97d67989e 100644
--- a/boost/align/detail/aligned_alloc_android.hpp
+++ b/boost/align/detail/aligned_alloc_android.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGNED_ALLOC_ANDROID_HPP
#define BOOST_ALIGN_DETAIL_ALIGNED_ALLOC_ANDROID_HPP
@@ -16,20 +16,21 @@
#include <malloc.h>
namespace boost {
- namespace alignment {
- inline void* aligned_alloc(std::size_t alignment,
- std::size_t size) BOOST_NOEXCEPT
- {
- BOOST_ASSERT(detail::is_alignment(alignment));
- return ::memalign(alignment, size);
- }
+namespace alignment {
- inline void aligned_free(void* ptr)
- BOOST_NOEXCEPT
- {
- ::free(ptr);
- }
- }
+inline void* aligned_alloc(std::size_t alignment, std::size_t size)
+ BOOST_NOEXCEPT
+{
+ BOOST_ASSERT(detail::is_alignment(alignment));
+ return ::memalign(alignment, size);
}
+inline void aligned_free(void* ptr) BOOST_NOEXCEPT
+{
+ ::free(ptr);
+}
+
+} /* :alignment */
+} /* :boost */
+
#endif
diff --git a/boost/align/detail/aligned_alloc_macos.hpp b/boost/align/detail/aligned_alloc_macos.hpp
index 346eabfc58..9b6d235133 100644
--- a/boost/align/detail/aligned_alloc_macos.hpp
+++ b/boost/align/detail/aligned_alloc_macos.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGNED_ALLOC_MACOS_HPP
#define BOOST_ALIGN_DETAIL_ALIGNED_ALLOC_MACOS_HPP
@@ -16,30 +16,31 @@
#include <stdlib.h>
namespace boost {
- namespace alignment {
- inline void* aligned_alloc(std::size_t alignment,
- std::size_t size) BOOST_NOEXCEPT
- {
- BOOST_ASSERT(detail::is_alignment(alignment));
- if (!size) {
- return 0;
- }
- if (alignment < sizeof(void*)) {
- alignment = sizeof(void*);
- }
- void* p;
- if (::posix_memalign(&p, alignment, size) != 0) {
- p = 0;
- }
- return p;
- }
+namespace alignment {
- inline void aligned_free(void* ptr)
- BOOST_NOEXCEPT
- {
- ::free(ptr);
- }
+inline void* aligned_alloc(std::size_t alignment, std::size_t size)
+ BOOST_NOEXCEPT
+{
+ BOOST_ASSERT(detail::is_alignment(alignment));
+ if (!size) {
+ return 0;
}
+ if (alignment < sizeof(void*)) {
+ alignment = sizeof(void*);
+ }
+ void* p;
+ if (::posix_memalign(&p, alignment, size) != 0) {
+ p = 0;
+ }
+ return p;
}
+inline void aligned_free(void* ptr) BOOST_NOEXCEPT
+{
+ ::free(ptr);
+}
+
+} /* :alignment */
+} /* :boost */
+
#endif
diff --git a/boost/align/detail/aligned_alloc_msvc.hpp b/boost/align/detail/aligned_alloc_msvc.hpp
index 570a898c59..1cb7f2a3a1 100644
--- a/boost/align/detail/aligned_alloc_msvc.hpp
+++ b/boost/align/detail/aligned_alloc_msvc.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGNED_ALLOC_MSVC_HPP
#define BOOST_ALIGN_DETAIL_ALIGNED_ALLOC_MSVC_HPP
@@ -16,20 +16,21 @@
#include <malloc.h>
namespace boost {
- namespace alignment {
- inline void* aligned_alloc(std::size_t alignment,
- std::size_t size) BOOST_NOEXCEPT
- {
- BOOST_ASSERT(detail::is_alignment(alignment));
- return ::_aligned_malloc(size, alignment);
- }
+namespace alignment {
- inline void aligned_free(void* ptr)
- BOOST_NOEXCEPT
- {
- ::_aligned_free(ptr);
- }
- }
+inline void* aligned_alloc(std::size_t alignment, std::size_t size)
+ BOOST_NOEXCEPT
+{
+ BOOST_ASSERT(detail::is_alignment(alignment));
+ return ::_aligned_malloc(size, alignment);
}
+inline void aligned_free(void* ptr) BOOST_NOEXCEPT
+{
+ ::_aligned_free(ptr);
+}
+
+} /* :alignment */
+} /* :boost */
+
#endif
diff --git a/boost/align/detail/aligned_alloc_posix.hpp b/boost/align/detail/aligned_alloc_posix.hpp
index ceab4cbe9c..3743652cbd 100644
--- a/boost/align/detail/aligned_alloc_posix.hpp
+++ b/boost/align/detail/aligned_alloc_posix.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGNED_ALLOC_POSIX_HPP
#define BOOST_ALIGN_DETAIL_ALIGNED_ALLOC_POSIX_HPP
@@ -16,27 +16,28 @@
#include <stdlib.h>
namespace boost {
- namespace alignment {
- inline void* aligned_alloc(std::size_t alignment,
- std::size_t size) BOOST_NOEXCEPT
- {
- BOOST_ASSERT(detail::is_alignment(alignment));
- if (alignment < sizeof(void*)) {
- alignment = sizeof(void*);
- }
- void* p;
- if (::posix_memalign(&p, alignment, size) != 0) {
- p = 0;
- }
- return p;
- }
+namespace alignment {
- inline void aligned_free(void* ptr)
- BOOST_NOEXCEPT
- {
- ::free(ptr);
- }
+inline void* aligned_alloc(std::size_t alignment, std::size_t size)
+ BOOST_NOEXCEPT
+{
+ BOOST_ASSERT(detail::is_alignment(alignment));
+ if (alignment < sizeof(void*)) {
+ alignment = sizeof(void*);
}
+ void* p;
+ if (::posix_memalign(&p, alignment, size) != 0) {
+ p = 0;
+ }
+ return p;
+}
+
+inline void aligned_free(void* ptr) BOOST_NOEXCEPT
+{
+ ::free(ptr);
}
+} /* :alignment */
+} /* :boost */
+
#endif
diff --git a/boost/align/detail/aligned_alloc_sunos.hpp b/boost/align/detail/aligned_alloc_sunos.hpp
index a2373bd26b..c5778cdd75 100644
--- a/boost/align/detail/aligned_alloc_sunos.hpp
+++ b/boost/align/detail/aligned_alloc_sunos.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGNED_ALLOC_SUNOS_HPP
#define BOOST_ALIGN_DETAIL_ALIGNED_ALLOC_SUNOS_HPP
@@ -16,20 +16,21 @@
#include <stdlib.h>
namespace boost {
- namespace alignment {
- inline void* aligned_alloc(std::size_t alignment,
- std::size_t size) BOOST_NOEXCEPT
- {
- BOOST_ASSERT(detail::is_alignment(alignment));
- return ::memalign(alignment, size);
- }
+namespace alignment {
- inline void aligned_free(void* ptr)
- BOOST_NOEXCEPT
- {
- ::free(ptr);
- }
- }
+inline void* aligned_alloc(std::size_t alignment, std::size_t size)
+ BOOST_NOEXCEPT
+{
+ BOOST_ASSERT(detail::is_alignment(alignment));
+ return ::memalign(alignment, size);
}
+inline void aligned_free(void* ptr) BOOST_NOEXCEPT
+{
+ ::free(ptr);
+}
+
+} /* :alignment */
+} /* :boost */
+
#endif
diff --git a/boost/align/detail/alignment_of.hpp b/boost/align/detail/alignment_of.hpp
index 1fa3070ce0..b1d2d56920 100644
--- a/boost/align/detail/alignment_of.hpp
+++ b/boost/align/detail/alignment_of.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGNMENT_OF_HPP
#define BOOST_ALIGN_DETAIL_ALIGNMENT_OF_HPP
@@ -13,15 +13,17 @@
#include <boost/align/detail/offset_object.hpp>
namespace boost {
- namespace alignment {
- namespace detail {
- template<class T>
- struct alignment_of
- : min_size<sizeof(T),
- sizeof(offset_object<T>) - sizeof(T)>::type {
- };
- }
- }
-}
+namespace alignment {
+namespace detail {
+
+template<class T>
+struct alignment_of
+ : min_size<sizeof(T),
+ sizeof(offset_object<T>) - sizeof(T)>::type {
+};
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/alignment_of_clang.hpp b/boost/align/detail/alignment_of_clang.hpp
index 18d7c718db..fa96a37d9d 100644
--- a/boost/align/detail/alignment_of_clang.hpp
+++ b/boost/align/detail/alignment_of_clang.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGNMENT_OF_CLANG_HPP
#define BOOST_ALIGN_DETAIL_ALIGNMENT_OF_CLANG_HPP
@@ -13,14 +13,16 @@
#include <cstddef>
namespace boost {
- namespace alignment {
- namespace detail {
- template<class T>
- struct alignment_of
- : integral_constant<std::size_t, __alignof(T)> {
- };
- }
- }
-}
+namespace alignment {
+namespace detail {
+
+template<class T>
+struct alignment_of
+ : integral_constant<std::size_t, __alignof(T)> {
+};
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/alignment_of_codegear.hpp b/boost/align/detail/alignment_of_codegear.hpp
index 9074967f49..e8986cef66 100644
--- a/boost/align/detail/alignment_of_codegear.hpp
+++ b/boost/align/detail/alignment_of_codegear.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGNMENT_OF_CODEGEAR_HPP
#define BOOST_ALIGN_DETAIL_ALIGNMENT_OF_CODEGEAR_HPP
@@ -13,14 +13,16 @@
#include <cstddef>
namespace boost {
- namespace alignment {
- namespace detail {
- template<class T>
- struct alignment_of
- : integral_constant<std::size_t, alignof(T)> {
- };
- }
- }
-}
+namespace alignment {
+namespace detail {
+
+template<class T>
+struct alignment_of
+ : integral_constant<std::size_t, alignof(T)> {
+};
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/alignment_of_cxx11.hpp b/boost/align/detail/alignment_of_cxx11.hpp
index d5d00a08b4..0f66098b67 100644
--- a/boost/align/detail/alignment_of_cxx11.hpp
+++ b/boost/align/detail/alignment_of_cxx11.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGNMENT_OF_CXX11_HPP
#define BOOST_ALIGN_DETAIL_ALIGNMENT_OF_CXX11_HPP
@@ -12,11 +12,13 @@
#include <type_traits>
namespace boost {
- namespace alignment {
- namespace detail {
- using std::alignment_of;
- }
- }
-}
+namespace alignment {
+namespace detail {
+
+using std::alignment_of;
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/alignment_of_gcc.hpp b/boost/align/detail/alignment_of_gcc.hpp
index 3044b2a3ec..615968b477 100644
--- a/boost/align/detail/alignment_of_gcc.hpp
+++ b/boost/align/detail/alignment_of_gcc.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGNMENT_OF_GCC_HPP
#define BOOST_ALIGN_DETAIL_ALIGNMENT_OF_GCC_HPP
@@ -13,14 +13,16 @@
#include <cstddef>
namespace boost {
- namespace alignment {
- namespace detail {
- template<class T>
- struct alignment_of
- : integral_constant<std::size_t, __alignof__(T)> {
- };
- }
- }
-}
+namespace alignment {
+namespace detail {
+
+template<class T>
+struct alignment_of
+ : integral_constant<std::size_t, __alignof__(T)> {
+};
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/alignment_of_msvc.hpp b/boost/align/detail/alignment_of_msvc.hpp
index a86f785ddc..87d6ac8e28 100644
--- a/boost/align/detail/alignment_of_msvc.hpp
+++ b/boost/align/detail/alignment_of_msvc.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGNMENT_OF_MSVC_HPP
#define BOOST_ALIGN_DETAIL_ALIGNMENT_OF_MSVC_HPP
@@ -13,15 +13,16 @@
#include <boost/align/detail/offset_object.hpp>
namespace boost {
- namespace alignment {
- namespace detail {
- template<class T>
- struct alignment_of
- : min_size<sizeof(T),
- offsetof(offset_object<T>, object)>::type {
- };
- }
- }
-}
+namespace alignment {
+namespace detail {
+
+template<class T>
+struct alignment_of
+ : min_size<sizeof(T), offsetof(offset_object<T>, object)>::type {
+};
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/assume_aligned.hpp b/boost/align/detail/assume_aligned.hpp
new file mode 100644
index 0000000000..0ecefa1dd0
--- /dev/null
+++ b/boost/align/detail/assume_aligned.hpp
@@ -0,0 +1,17 @@
+/*
+(c) 2015 NumScale SAS
+(c) 2015 LRI UMR 8623 CNRS/University Paris Sud XI
+
+(c) 2015 Glen Joseph Fernandes
+glenjofe at gmail dot com
+
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
+*/
+#ifndef BOOST_ALIGN_DETAIL_ASSUME_ALIGNED_HPP
+#define BOOST_ALIGN_DETAIL_ASSUME_ALIGNED_HPP
+
+#define BOOST_ALIGN_ASSUME_ALIGNED(ptr, alignment)
+
+#endif
diff --git a/boost/align/detail/assume_aligned_clang.hpp b/boost/align/detail/assume_aligned_clang.hpp
new file mode 100644
index 0000000000..d72b4cae86
--- /dev/null
+++ b/boost/align/detail/assume_aligned_clang.hpp
@@ -0,0 +1,21 @@
+/*
+(c) 2015 Glen Joseph Fernandes
+glenjofe at gmail dot com
+
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
+*/
+#ifndef BOOST_ALIGN_DETAIL_ASSUME_ALIGNED_CLANG_HPP
+#define BOOST_ALIGN_DETAIL_ASSUME_ALIGNED_CLANG_HPP
+
+#include <stdint.h>
+
+#if defined(__has_builtin) && __has_builtin(__builtin_assume)
+#define BOOST_ALIGN_ASSUME_ALIGNED(ptr, alignment) \
+__builtin_assume((uintptr_t(ptr) & ((alignment) - 1)) == 0)
+#else
+#define BOOST_ALIGN_ASSUME_ALIGNED(ptr, alignment)
+#endif
+
+#endif
diff --git a/boost/align/detail/assume_aligned_gcc.hpp b/boost/align/detail/assume_aligned_gcc.hpp
new file mode 100644
index 0000000000..a1e6cb0280
--- /dev/null
+++ b/boost/align/detail/assume_aligned_gcc.hpp
@@ -0,0 +1,18 @@
+/*
+(c) 2015 NumScale SAS
+(c) 2015 LRI UMR 8623 CNRS/University Paris Sud XI
+
+(c) 2015 Glen Joseph Fernandes
+glenjofe at gmail dot com
+
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
+*/
+#ifndef BOOST_ALIGN_DETAIL_ASSUME_ALIGNED_GCC_HPP
+#define BOOST_ALIGN_DETAIL_ASSUME_ALIGNED_GCC_HPP
+
+#define BOOST_ALIGN_ASSUME_ALIGNED(ptr, alignment) \
+(ptr) = __builtin_assume_aligned((ptr), (alignment))
+
+#endif
diff --git a/boost/align/detail/assume_aligned_intel.hpp b/boost/align/detail/assume_aligned_intel.hpp
new file mode 100644
index 0000000000..aaaf331802
--- /dev/null
+++ b/boost/align/detail/assume_aligned_intel.hpp
@@ -0,0 +1,18 @@
+/*
+(c) 2015 NumScale SAS
+(c) 2015 LRI UMR 8623 CNRS/University Paris Sud XI
+
+(c) 2015 Glen Joseph Fernandes
+glenjofe at gmail dot com
+
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
+*/
+#ifndef BOOST_ALIGN_DETAIL_ASSUME_ALIGNED_INTEL_HPP
+#define BOOST_ALIGN_DETAIL_ASSUME_ALIGNED_INTEL_HPP
+
+#define BOOST_ALIGN_ASSUME_ALIGNED(ptr, alignment) \
+__assume_aligned((ptr), (alignment))
+
+#endif
diff --git a/boost/align/detail/assume_aligned_msvc.hpp b/boost/align/detail/assume_aligned_msvc.hpp
new file mode 100644
index 0000000000..fdad429b08
--- /dev/null
+++ b/boost/align/detail/assume_aligned_msvc.hpp
@@ -0,0 +1,20 @@
+/*
+(c) 2015 NumScale SAS
+(c) 2015 LRI UMR 8623 CNRS/University Paris Sud XI
+
+(c) 2015 Glen Joseph Fernandes
+glenjofe at gmail dot com
+
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
+*/
+#ifndef BOOST_ALIGN_DETAIL_ASSUME_ALIGNED_MSVC_HPP
+#define BOOST_ALIGN_DETAIL_ASSUME_ALIGNED_MSVC_HPP
+
+#include <stddef.h>
+
+#define BOOST_ALIGN_ASSUME_ALIGNED(ptr, alignment) \
+__assume((uintptr_t(ptr) & ((alignment) - 1)) == 0)
+
+#endif
diff --git a/boost/align/detail/integral_constant.hpp b/boost/align/detail/integral_constant.hpp
index 332aade943..6116fea5f5 100644
--- a/boost/align/detail/integral_constant.hpp
+++ b/boost/align/detail/integral_constant.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_INTEGRAL_CONSTANT_HPP
#define BOOST_ALIGN_DETAIL_INTEGRAL_CONSTANT_HPP
@@ -16,31 +16,33 @@
#endif
namespace boost {
- namespace alignment {
- namespace detail {
+namespace alignment {
+namespace detail {
+
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
- using std::integral_constant;
+using std::integral_constant;
#else
- template<class T, T Value>
- struct integral_constant {
- typedef T value_type;
- typedef integral_constant<T, Value> type;
+template<class T, T Value>
+struct integral_constant {
+ typedef T value_type;
+ typedef integral_constant<T, Value> type;
#if !defined(BOOST_NO_CXX11_CONSTEXPR)
- constexpr operator value_type() const {
- return Value;
- }
+ constexpr operator value_type() const {
+ return Value;
+ }
- static constexpr T value = Value;
+ static constexpr T value = Value;
#else
- enum {
- value = Value
- };
+ enum {
+ value = Value
+ };
#endif
- };
+};
#endif
- }
- }
-}
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/is_aligned.hpp b/boost/align/detail/is_aligned.hpp
index 41fb80581f..a861e9f4c8 100644
--- a/boost/align/detail/is_aligned.hpp
+++ b/boost/align/detail/is_aligned.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_IS_ALIGNED_HPP
#define BOOST_ALIGN_DETAIL_IS_ALIGNED_HPP
@@ -16,14 +16,16 @@
#include <cstddef>
namespace boost {
- namespace alignment {
- inline bool is_aligned(std::size_t alignment,
- const void* ptr) BOOST_NOEXCEPT
- {
- BOOST_ASSERT(detail::is_alignment(alignment));
- return (detail::address_t(ptr) & (alignment - 1)) == 0;
- }
- }
+namespace alignment {
+
+inline bool is_aligned(std::size_t alignment, const void* ptr)
+ BOOST_NOEXCEPT
+{
+ BOOST_ASSERT(detail::is_alignment(alignment));
+ return (detail::address_t(ptr) & (alignment - 1)) == 0;
}
+} /* :alignment */
+} /* :boost */
+
#endif
diff --git a/boost/align/detail/is_alignment.hpp b/boost/align/detail/is_alignment.hpp
index 532198363f..7ac0bb3d12 100644
--- a/boost/align/detail/is_alignment.hpp
+++ b/boost/align/detail/is_alignment.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_IS_ALIGNMENT_HPP
#define BOOST_ALIGN_DETAIL_IS_ALIGNMENT_HPP
@@ -13,15 +13,17 @@
#include <cstddef>
namespace boost {
- namespace alignment {
- namespace detail {
- BOOST_CONSTEXPR inline bool is_alignment(std::size_t
- value) BOOST_NOEXCEPT
- {
- return (value > 0) && ((value & (value - 1)) == 0);
- }
- }
- }
+namespace alignment {
+namespace detail {
+
+BOOST_CONSTEXPR inline bool is_alignment(std::size_t value)
+ BOOST_NOEXCEPT
+{
+ return (value > 0) && ((value & (value - 1)) == 0);
}
+} /* :detail */
+} /* :alignment */
+} /* :boost */
+
#endif
diff --git a/boost/align/detail/is_alignment_constant.hpp b/boost/align/detail/is_alignment_constant.hpp
index 8f422608ae..4c703cafc0 100644
--- a/boost/align/detail/is_alignment_constant.hpp
+++ b/boost/align/detail/is_alignment_constant.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_IS_ALIGNMENT_CONSTANT_HPP
#define BOOST_ALIGN_DETAIL_IS_ALIGNMENT_CONSTANT_HPP
@@ -13,15 +13,16 @@
#include <cstddef>
namespace boost {
- namespace alignment {
- namespace detail {
- template<std::size_t N>
- struct is_alignment_constant
- : integral_constant<bool,
- (N > 0) && ((N & (N - 1)) == 0)> {
- };
- }
- }
-}
+namespace alignment {
+namespace detail {
+
+template<std::size_t N>
+struct is_alignment_constant
+ : integral_constant<bool, (N > 0) && ((N & (N - 1)) == 0)> {
+};
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/max_align.hpp b/boost/align/detail/max_align.hpp
index 775121d83a..4351a5a2ed 100644
--- a/boost/align/detail/max_align.hpp
+++ b/boost/align/detail/max_align.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_MAX_ALIGN_HPP
#define BOOST_ALIGN_DETAIL_MAX_ALIGN_HPP
@@ -13,15 +13,16 @@
#include <cstddef>
namespace boost {
- namespace alignment {
- namespace detail {
- template<std::size_t A, std::size_t B>
- struct max_align
- : integral_constant<std::size_t,
- (A > B) ? A : B> {
- };
- }
- }
-}
+namespace alignment {
+namespace detail {
+
+template<std::size_t A, std::size_t B>
+struct max_align
+ : integral_constant<std::size_t, (A > B) ? A : B> {
+};
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/max_count_of.hpp b/boost/align/detail/max_count_of.hpp
index 3ba4eae70e..e0ae3bce96 100644
--- a/boost/align/detail/max_count_of.hpp
+++ b/boost/align/detail/max_count_of.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_MAX_COUNT_OF_HPP
#define BOOST_ALIGN_DETAIL_MAX_COUNT_OF_HPP
@@ -13,15 +13,17 @@
#include <cstddef>
namespace boost {
- namespace alignment {
- namespace detail {
- template<class T>
- struct max_count_of
- : integral_constant<std::size_t,
- ~static_cast<std::size_t>(0) / sizeof(T)> {
- };
- }
- }
-}
+namespace alignment {
+namespace detail {
+
+template<class T>
+struct max_count_of
+ : integral_constant<std::size_t,
+ ~static_cast<std::size_t>(0) / sizeof(T)> {
+};
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/min_size.hpp b/boost/align/detail/min_size.hpp
index 80d3a7a6ed..71afe8c686 100644
--- a/boost/align/detail/min_size.hpp
+++ b/boost/align/detail/min_size.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_MIN_SIZE_HPP
#define BOOST_ALIGN_DETAIL_MIN_SIZE_HPP
@@ -13,15 +13,16 @@
#include <cstddef>
namespace boost {
- namespace alignment {
- namespace detail {
- template<std::size_t A, std::size_t B>
- struct min_size
- : integral_constant<std::size_t,
- (A < B) ? A : B> {
- };
- }
- }
-}
+namespace alignment {
+namespace detail {
+
+template<std::size_t A, std::size_t B>
+struct min_size
+ : integral_constant<std::size_t, (A < B) ? A : B> {
+};
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/offset_object.hpp b/boost/align/detail/offset_object.hpp
index 8168595230..2055edfb4a 100644
--- a/boost/align/detail/offset_object.hpp
+++ b/boost/align/detail/offset_object.hpp
@@ -1,24 +1,26 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_OFFSET_OBJECT_HPP
#define BOOST_ALIGN_DETAIL_OFFSET_OBJECT_HPP
namespace boost {
- namespace alignment {
- namespace detail {
- template<class T>
- struct offset_object {
- char offset;
- T object;
- };
- }
- }
-}
+namespace alignment {
+namespace detail {
+
+template<class T>
+struct offset_object {
+ char offset;
+ T object;
+};
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/detail/remove_traits.hpp b/boost/align/detail/remove_traits.hpp
index d44860ed6b..f59d6bf9e8 100644
--- a/boost/align/detail/remove_traits.hpp
+++ b/boost/align/detail/remove_traits.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_REMOVE_TRAITS_HPP
#define BOOST_ALIGN_DETAIL_REMOVE_TRAITS_HPP
@@ -18,73 +18,75 @@
#endif
namespace boost {
- namespace alignment {
- namespace detail {
+namespace alignment {
+namespace detail {
+
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
- using std::remove_reference;
- using std::remove_all_extents;
- using std::remove_cv;
+using std::remove_reference;
+using std::remove_all_extents;
+using std::remove_cv;
#else
- template<class T>
- struct remove_reference {
- typedef T type;
- };
+template<class T>
+struct remove_reference {
+ typedef T type;
+};
- template<class T>
- struct remove_reference<T&> {
- typedef T type;
- };
+template<class T>
+struct remove_reference<T&> {
+ typedef T type;
+};
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
- template<class T>
- struct remove_reference<T&&> {
- typedef T type;
- };
+template<class T>
+struct remove_reference<T&&> {
+ typedef T type;
+};
#endif
- template<class T>
- struct remove_all_extents {
- typedef T type;
- };
-
- template<class T>
- struct remove_all_extents<T[]> {
- typedef typename remove_all_extents<T>::type type;
- };
-
- template<class T, std::size_t N>
- struct remove_all_extents<T[N]> {
- typedef typename remove_all_extents<T>::type type;
- };
-
- template<class T>
- struct remove_const {
- typedef T type;
- };
-
- template<class T>
- struct remove_const<const T> {
- typedef T type;
- };
-
- template<class T>
- struct remove_volatile {
- typedef T type;
- };
-
- template<class T>
- struct remove_volatile<volatile T> {
- typedef T type;
- };
-
- template<class T>
- struct remove_cv {
- typedef typename remove_volatile<typename
- remove_const<T>::type>::type type;
- };
+template<class T>
+struct remove_all_extents {
+ typedef T type;
+};
+
+template<class T>
+struct remove_all_extents<T[]> {
+ typedef typename remove_all_extents<T>::type type;
+};
+
+template<class T, std::size_t N>
+struct remove_all_extents<T[N]> {
+ typedef typename remove_all_extents<T>::type type;
+};
+
+template<class T>
+struct remove_const {
+ typedef T type;
+};
+
+template<class T>
+struct remove_const<const T> {
+ typedef T type;
+};
+
+template<class T>
+struct remove_volatile {
+ typedef T type;
+};
+
+template<class T>
+struct remove_volatile<volatile T> {
+ typedef T type;
+};
+
+template<class T>
+struct remove_cv {
+ typedef typename remove_volatile<typename
+ remove_const<T>::type>::type type;
+};
#endif
- }
- }
-}
+
+} /* :detail */
+} /* :alignment */
+} /* :boost */
#endif
diff --git a/boost/align/is_aligned.hpp b/boost/align/is_aligned.hpp
index de286655af..7473864ca7 100644
--- a/boost/align/is_aligned.hpp
+++ b/boost/align/is_aligned.hpp
@@ -1,10 +1,10 @@
/*
- (c) 2014 Glen Joseph Fernandes
- glenjofe at gmail dot com
+(c) 2014 Glen Joseph Fernandes
+glenjofe at gmail dot com
- Distributed under the Boost Software
- License, Version 1.0.
- http://boost.org/LICENSE_1_0.txt
+Distributed under the Boost Software
+License, Version 1.0.
+http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_IS_ALIGNED_HPP
#define BOOST_ALIGN_IS_ALIGNED_HPP
diff --git a/boost/archive/archive_exception.hpp b/boost/archive/archive_exception.hpp
index ffb430c6a8..1159d27755 100644
--- a/boost/archive/archive_exception.hpp
+++ b/boost/archive/archive_exception.hpp
@@ -21,7 +21,6 @@
#include <string>
#include <boost/config.hpp>
-#include <boost/preprocessor/empty.hpp>
#include <boost/archive/detail/decl.hpp>
// note: the only reason this is in here is that windows header
@@ -40,11 +39,16 @@ namespace archive {
//////////////////////////////////////////////////////////////////////
// exceptions thrown by archives
//
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) archive_exception :
+class BOOST_SYMBOL_VISIBLE archive_exception :
public virtual std::exception
{
-protected:
+private:
char m_buffer[128];
+protected:
+ BOOST_ARCHIVE_DECL unsigned int
+ append(unsigned int l, const char * a);
+ BOOST_ARCHIVE_DECL
+ archive_exception() BOOST_NOEXCEPT;
public:
typedef enum {
no_exception, // initialized without code
@@ -76,19 +80,15 @@ public:
// type has been instantiated in more than one module.
output_stream_error // error on input stream
} exception_code;
-public:
exception_code code;
- archive_exception(
+
+ BOOST_ARCHIVE_DECL archive_exception(
exception_code c,
const char * e1 = NULL,
const char * e2 = NULL
- );
- virtual ~archive_exception() throw();
- virtual const char *what() const throw();
-protected:
- unsigned int
- append(unsigned int l, const char * a);
- archive_exception();
+ ) BOOST_NOEXCEPT;
+ virtual BOOST_ARCHIVE_DECL ~archive_exception() BOOST_NOEXCEPT_OR_NOTHROW ;
+ virtual BOOST_ARCHIVE_DECL const char * what() const BOOST_NOEXCEPT_OR_NOTHROW ;
};
}// namespace archive
diff --git a/boost/archive/basic_archive.hpp b/boost/archive/basic_archive.hpp
index 0412112352..ce7ac99a6d 100644
--- a/boost/archive/basic_archive.hpp
+++ b/boost/archive/basic_archive.hpp
@@ -69,7 +69,7 @@ public:
}
};
-BOOST_ARCHIVE_DECL(library_version_type)
+BOOST_ARCHIVE_DECL library_version_type
BOOST_ARCHIVE_VERSION();
class version_type {
@@ -242,7 +242,7 @@ enum archive_flags {
flags_last = 8
};
-BOOST_ARCHIVE_DECL(const char *)
+BOOST_ARCHIVE_DECL const char *
BOOST_ARCHIVE_SIGNATURE();
/* NOTE : Warning : Warning : Warning : Warning : Warning
diff --git a/boost/archive/basic_binary_iarchive.hpp b/boost/archive/basic_binary_iarchive.hpp
index a649d5e919..c0cc655c99 100644
--- a/boost/archive/basic_binary_iarchive.hpp
+++ b/boost/archive/basic_binary_iarchive.hpp
@@ -25,7 +25,6 @@
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/archive/basic_archive.hpp>
#include <boost/archive/detail/common_iarchive.hpp>
@@ -51,7 +50,7 @@ namespace detail {
/////////////////////////////////////////////////////////////////////////
// class basic_binary_iarchive - read serialized objects from a input binary stream
template<class Archive>
-class basic_binary_iarchive :
+class BOOST_SYMBOL_VISIBLE basic_binary_iarchive :
public detail::common_iarchive<Archive>
{
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
@@ -72,8 +71,8 @@ protected:
// note extra nonsense to sneak it pass the borland compiers
typedef detail::common_iarchive<Archive> detail_common_iarchive;
template<class T>
- void load_override(T & t, BOOST_PFTO int version){
- this->detail_common_iarchive::load_override(t, static_cast<int>(version));
+ void load_override(T & t){
+ this->detail_common_iarchive::load_override(t);
}
// include these to trap a change in binary format which
@@ -86,7 +85,7 @@ protected:
BOOST_STATIC_ASSERT(sizeof(object_reference_type) == sizeof(uint_least32_t));
// binary files don't include the optional information
- void load_override(class_id_optional_type & /* t */, int){}
+ void load_override(class_id_optional_type & /* t */){}
void load_override(tracking_type & t, int /*version*/){
library_version_type lvt = this->get_library_version();
@@ -101,10 +100,10 @@ protected:
t = boost::archive::tracking_type(x);
}
}
- void load_override(class_id_type & t, int version){
+ void load_override(class_id_type & t){
library_version_type lvt = this->get_library_version();
if(boost::archive::library_version_type(7) < lvt){
- this->detail_common_iarchive::load_override(t, version);
+ this->detail_common_iarchive::load_override(t);
}
else
if(boost::archive::library_version_type(6) < lvt){
@@ -118,37 +117,14 @@ protected:
t = boost::archive::class_id_type(x);
}
}
- void load_override(class_id_reference_type & t, int version){
- load_override(static_cast<class_id_type &>(t), version);
+ void load_override(class_id_reference_type & t){
+ load_override(static_cast<class_id_type &>(t));
}
-#if 0
- void load_override(class_id_reference_type & t, int version){
- library_version_type lvt = this->get_library_version();
- if(boost::archive::library_version_type(7) < lvt){
- this->detail_common_iarchive::load_override(t, version);
- }
- else
- if(boost::archive::library_version_type(6) < lvt){
- int_least16_t x=0;
- * this->This() >> x;
- t = boost::archive::class_id_reference_type(
- boost::archive::class_id_type(x)
- );
- }
- else{
- int x=0;
- * this->This() >> x;
- t = boost::archive::class_id_reference_type(
- boost::archive::class_id_type(x)
- );
- }
- }
-#endif
- void load_override(version_type & t, int version){
+ void load_override(version_type & t){
library_version_type lvt = this->get_library_version();
if(boost::archive::library_version_type(7) < lvt){
- this->detail_common_iarchive::load_override(t, version);
+ this->detail_common_iarchive::load_override(t);
}
else
if(boost::archive::library_version_type(6) < lvt){
@@ -176,11 +152,11 @@ protected:
}
}
- void load_override(boost::serialization::item_version_type & t, int version){
+ void load_override(boost::serialization::item_version_type & t){
library_version_type lvt = this->get_library_version();
// if(boost::archive::library_version_type(7) < lvt){
if(boost::archive::library_version_type(6) < lvt){
- this->detail_common_iarchive::load_override(t, version);
+ this->detail_common_iarchive::load_override(t);
}
else
if(boost::archive::library_version_type(6) < lvt){
@@ -195,9 +171,9 @@ protected:
}
}
- void load_override(serialization::collection_size_type & t, int version){
+ void load_override(serialization::collection_size_type & t){
if(boost::archive::library_version_type(5) < this->get_library_version()){
- this->detail_common_iarchive::load_override(t, version);
+ this->detail_common_iarchive::load_override(t);
}
else{
unsigned int x=0;
@@ -206,9 +182,9 @@ protected:
}
}
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
- load_override(class_name_type & t, int);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+ load_override(class_name_type & t);
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
init();
basic_binary_iarchive(unsigned int flags) :
diff --git a/boost/archive/basic_binary_iprimitive.hpp b/boost/archive/basic_binary_iprimitive.hpp
index 4b4199126b..5e826310d7 100644
--- a/boost/archive/basic_binary_iprimitive.hpp
+++ b/boost/archive/basic_binary_iprimitive.hpp
@@ -67,8 +67,7 @@ class codecvt_null;
/////////////////////////////////////////////////////////////////////////////
// class binary_iarchive - read serialized objects from a input binary stream
template<class Archive, class Elem, class Tr>
-class basic_binary_iprimitive
-{
+class BOOST_SYMBOL_VISIBLE basic_binary_iprimitive {
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
friend class load_access;
protected:
@@ -103,25 +102,25 @@ public:
BOOST_ASSERT(0 == i || 1 == i);
(void)i; // warning suppression for release builds.
}
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
load(std::string &s);
#ifndef BOOST_NO_STD_WSTRING
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
load(std::wstring &ws);
#endif
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
load(char * t);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
load(wchar_t * t);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
init();
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_binary_iprimitive(
std::basic_streambuf<Elem, Tr> & sb,
bool no_codecvt
);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL
~basic_binary_iprimitive();
public:
// we provide an optimized load for all fundamental types
diff --git a/boost/archive/basic_binary_oarchive.hpp b/boost/archive/basic_binary_oarchive.hpp
index f8b53e9d7c..f05f2f86d5 100644
--- a/boost/archive/basic_binary_oarchive.hpp
+++ b/boost/archive/basic_binary_oarchive.hpp
@@ -26,7 +26,6 @@
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/integer.hpp>
#include <boost/integer_traits.hpp>
@@ -59,8 +58,8 @@ namespace detail {
// does have the virtue of buiding the smalles archive in the minimum amount
// of time. So under some circumstances it may be he right choice.
template<class Archive>
-class basic_binary_oarchive :
- public archive::detail::common_oarchive<Archive>
+class BOOST_SYMBOL_VISIBLE basic_binary_oarchive :
+ public detail::common_oarchive<Archive>
{
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
@@ -77,8 +76,8 @@ protected:
// any datatype not specifed below will be handled by base class
typedef detail::common_oarchive<Archive> detail_common_oarchive;
template<class T>
- void save_override(const T & t, BOOST_PFTO int version){
- this->detail_common_oarchive::save_override(t, static_cast<int>(version));
+ void save_override(const T & t){
+ this->detail_common_oarchive::save_override(t);
}
// include these to trap a change in binary format which
@@ -92,14 +91,14 @@ protected:
BOOST_STATIC_ASSERT(sizeof(object_reference_type) == sizeof(uint_least32_t));
// binary files don't include the optional information
- void save_override(const class_id_optional_type & /* t */, int){}
+ void save_override(const class_id_optional_type & /* t */){}
// enable this if we decide to support generation of previous versions
#if 0
- void save_override(const boost::archive::version_type & t, int version){
+ void save_override(const boost::archive::version_type & t){
library_version_type lvt = this->get_library_version();
if(boost::archive::library_version_type(7) < lvt){
- this->detail_common_oarchive::save_override(t, version);
+ this->detail_common_oarchive::save_override(t);
}
else
if(boost::archive::library_version_type(6) < lvt){
@@ -111,10 +110,10 @@ protected:
* this->This() << x;
}
}
- void save_override(const boost::serialization::item_version_type & t, int version){
+ void save_override(const boost::serialization::item_version_type & t){
library_version_type lvt = this->get_library_version();
if(boost::archive::library_version_type(7) < lvt){
- this->detail_common_oarchive::save_override(t, version);
+ this->detail_common_oarchive::save_override(t);
}
else
if(boost::archive::library_version_type(6) < lvt){
@@ -127,10 +126,10 @@ protected:
}
}
- void save_override(class_id_type & t, int version){
+ void save_override(class_id_type & t){
library_version_type lvt = this->get_library_version();
if(boost::archive::library_version_type(7) < lvt){
- this->detail_common_oarchive::save_override(t, version);
+ this->detail_common_oarchive::save_override(t);
}
else
if(boost::archive::library_version_type(6) < lvt){
@@ -142,20 +141,20 @@ protected:
* this->This() << x;
}
}
- void save_override(class_id_reference_type & t, int version){
- save_override(static_cast<class_id_type &>(t), version);
+ void save_override(class_id_reference_type & t){
+ save_override(static_cast<class_id_type &>(t));
}
#endif
// explicitly convert to char * to avoid compile ambiguities
- void save_override(const class_name_type & t, int){
+ void save_override(const class_name_type & t){
const std::string s(t);
* this->This() << s;
}
#if 0
- void save_override(const serialization::collection_size_type & t, int){
+ void save_override(const serialization::collection_size_type & t){
if (get_library_version() < boost::archive::library_version_type(6)){
unsigned int x=0;
* this->This() >> x;
@@ -166,7 +165,7 @@ protected:
}
}
#endif
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
init();
basic_binary_oarchive(unsigned int flags) :
diff --git a/boost/archive/basic_binary_oprimitive.hpp b/boost/archive/basic_binary_oprimitive.hpp
index a79cd1dacb..077d705ef1 100644
--- a/boost/archive/basic_binary_oprimitive.hpp
+++ b/boost/archive/basic_binary_oprimitive.hpp
@@ -61,7 +61,7 @@ class codecvt_null;
// class basic_binary_oprimitive - binary output of prmitives
template<class Archive, class Elem, class Tr>
-class basic_binary_oprimitive {
+class BOOST_SYMBOL_VISIBLE basic_binary_oprimitive {
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
friend class save_access;
protected:
@@ -94,26 +94,26 @@ public:
BOOST_ASSERT(0 == static_cast<int>(t) || 1 == static_cast<int>(t));
save_binary(& t, sizeof(t));
}
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
save(const std::string &s);
#ifndef BOOST_NO_STD_WSTRING
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
save(const std::wstring &ws);
#endif
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
save(const char * t);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
save(const wchar_t * t);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
init();
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_binary_oprimitive(
std::basic_streambuf<Elem, Tr> & sb,
bool no_codecvt
);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL
~basic_binary_oprimitive();
public:
diff --git a/boost/archive/basic_text_iarchive.hpp b/boost/archive/basic_text_iarchive.hpp
index 0e78ff6d14..583041d8b4 100644
--- a/boost/archive/basic_text_iarchive.hpp
+++ b/boost/archive/basic_text_iarchive.hpp
@@ -25,7 +25,6 @@
// use two template parameters
#include <boost/config.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/archive/detail/common_iarchive.hpp>
@@ -47,7 +46,7 @@ namespace detail {
/////////////////////////////////////////////////////////////////////////
// class basic_text_iarchive - read serialized objects from a input text stream
template<class Archive>
-class basic_text_iarchive :
+class BOOST_SYMBOL_VISIBLE basic_text_iarchive :
public detail::common_iarchive<Archive>
{
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
@@ -67,16 +66,16 @@ protected:
// template ordering
typedef detail::common_iarchive<Archive> detail_common_iarchive;
template<class T>
- void load_override(T & t, BOOST_PFTO int){
- this->detail_common_iarchive::load_override(t, 0);
+ void load_override(T & t){
+ this->detail_common_iarchive::load_override(t);
}
// text file don't include the optional information
- void load_override(class_id_optional_type & /*t*/, int){}
+ void load_override(class_id_optional_type & /*t*/){}
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
- load_override(class_name_type & t, int);
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+ load_override(class_name_type & t);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
init(void);
basic_text_iarchive(unsigned int flags) :
diff --git a/boost/archive/basic_text_iprimitive.hpp b/boost/archive/basic_text_iprimitive.hpp
index dabc3c8710..08da95c36e 100644
--- a/boost/archive/basic_text_iprimitive.hpp
+++ b/boost/archive/basic_text_iprimitive.hpp
@@ -64,7 +64,7 @@ namespace archive {
#endif
template<class IStream>
-class basic_text_iprimitive {
+class BOOST_SYMBOL_VISIBLE basic_text_iprimitive {
protected:
IStream &is;
io::ios_flags_saver flags_saver;
@@ -116,12 +116,12 @@ protected:
t = i;
}
#endif
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_text_iprimitive(IStream &is, bool no_codecvt);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL
~basic_text_iprimitive();
public:
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
load_binary(void *address, std::size_t count);
};
diff --git a/boost/archive/basic_text_oarchive.hpp b/boost/archive/basic_text_oarchive.hpp
index 0c60a310f0..6f7f8fb167 100644
--- a/boost/archive/basic_text_oarchive.hpp
+++ b/boost/archive/basic_text_oarchive.hpp
@@ -25,7 +25,6 @@
// use two template parameters
#include <boost/config.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/archive/detail/common_oarchive.hpp>
#include <boost/serialization/string.hpp>
@@ -47,7 +46,7 @@ namespace detail {
/////////////////////////////////////////////////////////////////////////
// class basic_text_oarchive
template<class Archive>
-class basic_text_oarchive :
+class BOOST_SYMBOL_VISIBLE basic_text_oarchive :
public detail::common_oarchive<Archive>
{
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
@@ -69,7 +68,7 @@ protected:
space
} delimiter;
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
newtoken();
void newline(){
@@ -80,25 +79,25 @@ protected:
// extra stuff to get it passed borland compilers
typedef detail::common_oarchive<Archive> detail_common_oarchive;
template<class T>
- void save_override(T & t, BOOST_PFTO int){
- this->detail_common_oarchive::save_override(t, 0);
+ void save_override(T & t){
+ this->detail_common_oarchive::save_override(t);
}
// start new objects on a new line
- void save_override(const object_id_type & t, int){
+ void save_override(const object_id_type & t){
this->This()->newline();
- this->detail_common_oarchive::save_override(t, 0);
+ this->detail_common_oarchive::save_override(t);
}
// text file don't include the optional information
- void save_override(const class_id_optional_type & /* t */, int){}
+ void save_override(const class_id_optional_type & /* t */){}
- void save_override(const class_name_type & t, int){
+ void save_override(const class_name_type & t){
const std::string s(t);
* this->This() << s;
}
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
init();
basic_text_oarchive(unsigned int flags) :
diff --git a/boost/archive/basic_text_oprimitive.hpp b/boost/archive/basic_text_oprimitive.hpp
index 3c4cb5bddb..86330921d2 100644
--- a/boost/archive/basic_text_oprimitive.hpp
+++ b/boost/archive/basic_text_oprimitive.hpp
@@ -64,7 +64,7 @@ namespace archive {
/////////////////////////////////////////////////////////////////////////
// class basic_text_oprimitive - output of prmitives to stream
template<class OStream>
-class basic_text_oprimitive
+class BOOST_SYMBOL_VISIBLE basic_text_oprimitive
{
protected:
OStream &os;
@@ -174,9 +174,9 @@ protected:
save_impl(t, tf);
}
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_text_oprimitive(OStream & os, bool no_codecvt);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL
~basic_text_oprimitive();
public:
// unformatted append of one character
@@ -192,7 +192,7 @@ public:
while('\0' != *s)
os.put(*s++);
}
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
save_binary(const void *address, std::size_t count);
};
diff --git a/boost/archive/basic_xml_archive.hpp b/boost/archive/basic_xml_archive.hpp
index a4ad3a2f06..bef368b973 100644
--- a/boost/archive/basic_xml_archive.hpp
+++ b/boost/archive/basic_xml_archive.hpp
@@ -27,35 +27,35 @@ namespace archive {
// constant strings used in xml i/o
extern
-BOOST_ARCHIVE_DECL(const char *)
+BOOST_ARCHIVE_DECL const char *
BOOST_ARCHIVE_XML_OBJECT_ID();
extern
-BOOST_ARCHIVE_DECL(const char *)
+BOOST_ARCHIVE_DECL const char *
BOOST_ARCHIVE_XML_OBJECT_REFERENCE();
extern
-BOOST_ARCHIVE_DECL(const char *)
+BOOST_ARCHIVE_DECL const char *
BOOST_ARCHIVE_XML_CLASS_ID();
extern
-BOOST_ARCHIVE_DECL(const char *)
+BOOST_ARCHIVE_DECL const char *
BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE();
extern
-BOOST_ARCHIVE_DECL(const char *)
+BOOST_ARCHIVE_DECL const char *
BOOST_ARCHIVE_XML_CLASS_NAME();
extern
-BOOST_ARCHIVE_DECL(const char *)
+BOOST_ARCHIVE_DECL const char *
BOOST_ARCHIVE_XML_TRACKING();
extern
-BOOST_ARCHIVE_DECL(const char *)
+BOOST_ARCHIVE_DECL const char *
BOOST_ARCHIVE_XML_VERSION();
extern
-BOOST_ARCHIVE_DECL(const char *)
+BOOST_ARCHIVE_DECL const char *
BOOST_ARCHIVE_XML_SIGNATURE();
}// namespace archive
diff --git a/boost/archive/basic_xml_iarchive.hpp b/boost/archive/basic_xml_iarchive.hpp
index 5047fef26c..7834d8a100 100644
--- a/boost/archive/basic_xml_iarchive.hpp
+++ b/boost/archive/basic_xml_iarchive.hpp
@@ -17,7 +17,6 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/archive/detail/common_iarchive.hpp>
@@ -44,7 +43,7 @@ namespace detail {
/////////////////////////////////////////////////////////////////////////
// class xml_iarchive - read serialized objects from a input text stream
template<class Archive>
-class basic_xml_iarchive :
+class BOOST_SYMBOL_VISIBLE basic_xml_iarchive :
public detail::common_iarchive<Archive>
{
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
@@ -60,21 +59,21 @@ protected:
#endif
#endif
unsigned int depth;
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
load_start(const char *name);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
load_end(const char *name);
// Anything not an attribute and not a name-value pair is an
// should be trapped here.
template<class T>
- void load_override(T & t, BOOST_PFTO int)
+ void load_override(T & t)
{
// If your program fails to compile here, its most likely due to
// not specifying an nvp wrapper around the variable to
// be serialized.
BOOST_MPL_ASSERT((serialization::is_wrapper< T >));
- this->detail_common_iarchive::load_override(t, 0);
+ this->detail_common_iarchive::load_override(t);
}
// Anything not an attribute - see below - should be a name value
@@ -82,14 +81,10 @@ protected:
typedef detail::common_iarchive<Archive> detail_common_iarchive;
template<class T>
void load_override(
- #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
- const
- #endif
- boost::serialization::nvp< T > & t,
- int
+ const boost::serialization::nvp< T > & t
){
this->This()->load_start(t.name());
- this->detail_common_iarchive::load_override(t.value(), 0);
+ this->detail_common_iarchive::load_override(t.value());
this->This()->load_end(t.name());
}
@@ -101,23 +96,23 @@ protected:
// an xml archive. So we can skip it here. Note: we MUST override
// it otherwise it will be loaded as a normal primitive w/o tag and
// leaving the archive in an undetermined state
- void load_override(class_id_optional_type & /* t */, int){}
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
- load_override(object_id_type & t, int);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
- load_override(version_type & t, int);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
- load_override(class_id_type & t, int);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
- load_override(tracking_type & t, int);
+ void load_override(class_id_optional_type & /* t */){}
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+ load_override(object_id_type & t);
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+ load_override(version_type & t);
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+ load_override(class_id_type & t);
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+ load_override(tracking_type & t);
// class_name_type can't be handled here as it depends upon the
// char type used by the stream. So require the derived implementation
// handle this.
- // void load_override(class_name_type & t, int);
+ // void load_override(class_name_type & t);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_xml_iarchive(unsigned int flags);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL
~basic_xml_iarchive();
};
diff --git a/boost/archive/basic_xml_oarchive.hpp b/boost/archive/basic_xml_oarchive.hpp
index 8a039fa16d..0325eee653 100644
--- a/boost/archive/basic_xml_oarchive.hpp
+++ b/boost/archive/basic_xml_oarchive.hpp
@@ -18,7 +18,6 @@
#include <boost/config.hpp>
#include <boost/mpl/assert.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/archive/detail/common_oarchive.hpp>
@@ -45,7 +44,7 @@ namespace detail {
//////////////////////////////////////////////////////////////////////
// class basic_xml_oarchive - write serialized objects to a xml output stream
template<class Archive>
-class basic_xml_oarchive :
+class BOOST_SYMBOL_VISIBLE basic_xml_oarchive :
public detail::common_oarchive<Archive>
{
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
@@ -65,78 +64,74 @@ protected:
unsigned int depth;
bool indent_next;
bool pending_preamble;
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
indent();
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
init();
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
write_attribute(
const char *attribute_name,
int t,
const char *conjunction = "=\""
);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
write_attribute(
const char *attribute_name,
const char *key
);
// helpers used below
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
save_start(const char *name);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
save_end(const char *name);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
end_preamble();
// Anything not an attribute and not a name-value pair is an
// error and should be trapped here.
template<class T>
- void save_override(T & t, BOOST_PFTO int)
+ void save_override(T & t)
{
// If your program fails to compile here, its most likely due to
// not specifying an nvp wrapper around the variable to
// be serialized.
BOOST_MPL_ASSERT((serialization::is_wrapper< T >));
- this->detail_common_oarchive::save_override(t, 0);
+ this->detail_common_oarchive::save_override(t);
}
// special treatment for name-value pairs.
typedef detail::common_oarchive<Archive> detail_common_oarchive;
template<class T>
void save_override(
- #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
- const
- #endif
- ::boost::serialization::nvp< T > & t,
- int
+ const ::boost::serialization::nvp< T > & t
){
this->This()->save_start(t.name());
- this->detail_common_oarchive::save_override(t.const_value(), 0);
+ this->detail_common_oarchive::save_override(t.const_value());
this->This()->save_end(t.name());
}
// specific overrides for attributes - not name value pairs so we
// want to trap them before the above "fall through"
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
- save_override(const object_id_type & t, int);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
- save_override(const object_reference_type & t, int);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
- save_override(const version_type & t, int);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
- save_override(const class_id_type & t, int);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
- save_override(const class_id_optional_type & t, int);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
- save_override(const class_id_reference_type & t, int);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
- save_override(const class_name_type & t, int);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
- save_override(const tracking_type & t, int);
-
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+ save_override(const object_id_type & t);
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+ save_override(const object_reference_type & t);
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+ save_override(const version_type & t);
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+ save_override(const class_id_type & t);
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+ save_override(const class_id_optional_type & t);
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+ save_override(const class_id_reference_type & t);
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+ save_override(const class_name_type & t);
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+ save_override(const tracking_type & t);
+
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_xml_oarchive(unsigned int flags);
- BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_OR_WARCHIVE_DECL
~basic_xml_oarchive();
};
diff --git a/boost/archive/binary_iarchive.hpp b/boost/archive/binary_iarchive.hpp
index ce67ccabd0..785ce7610b 100644
--- a/boost/archive/binary_iarchive.hpp
+++ b/boost/archive/binary_iarchive.hpp
@@ -31,7 +31,7 @@ namespace archive {
// do not derive from this class. If you want to extend this functionality
// via inhertance, derived from binary_iarchive_impl instead. This will
// preserve correct static polymorphism.
-class binary_iarchive :
+class BOOST_SYMBOL_VISIBLE binary_iarchive :
public binary_iarchive_impl<
boost::archive::binary_iarchive,
std::istream::char_type,
diff --git a/boost/archive/binary_iarchive_impl.hpp b/boost/archive/binary_iarchive_impl.hpp
index a9afe61688..3ff994ad83 100644
--- a/boost/archive/binary_iarchive_impl.hpp
+++ b/boost/archive/binary_iarchive_impl.hpp
@@ -17,7 +17,6 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <istream>
-#include <boost/serialization/pfto.hpp>
#include <boost/archive/basic_binary_iprimitive.hpp>
#include <boost/archive/basic_binary_iarchive.hpp>
@@ -54,12 +53,9 @@ protected:
friend class load_access;
#endif
#endif
- // note: the following should not needed - but one compiler (vc 7.1)
- // fails to compile one test (test_shared_ptr) without it !!!
- // make this protected so it can be called from a derived archive
template<class T>
- void load_override(T & t, BOOST_PFTO int){
- this->basic_binary_iarchive<Archive>::load_override(t, 0L);
+ void load_override(T & t){
+ this->basic_binary_iarchive<Archive>::load_override(t);
}
void init(unsigned int flags){
if(0 != (flags & no_header))
diff --git a/boost/archive/binary_oarchive.hpp b/boost/archive/binary_oarchive.hpp
index 89a86da418..e8313fd7c9 100644
--- a/boost/archive/binary_oarchive.hpp
+++ b/boost/archive/binary_oarchive.hpp
@@ -32,7 +32,7 @@ namespace archive {
// do not derive from this class. If you want to extend this functionality
// via inhertance, derived from binary_oarchive_impl instead. This will
// preserve correct static polymorphism.
-class binary_oarchive :
+class BOOST_SYMBOL_VISIBLE binary_oarchive :
public binary_oarchive_impl<
binary_oarchive, std::ostream::char_type, std::ostream::traits_type
>
diff --git a/boost/archive/binary_oarchive_impl.hpp b/boost/archive/binary_oarchive_impl.hpp
index a8c97333ec..76e3a6565b 100644
--- a/boost/archive/binary_oarchive_impl.hpp
+++ b/boost/archive/binary_oarchive_impl.hpp
@@ -18,7 +18,6 @@
#include <ostream>
#include <boost/config.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/archive/basic_binary_oprimitive.hpp>
#include <boost/archive/basic_binary_oarchive.hpp>
@@ -55,12 +54,9 @@ protected:
friend class save_access;
#endif
#endif
- // note: the following should not needed - but one compiler (vc 7.1)
- // fails to compile one test (test_shared_ptr) without it !!!
- // make this protected so it can be called from a derived archive
template<class T>
- void save_override(T & t, BOOST_PFTO int){
- this->basic_binary_oarchive<Archive>::save_override(t, 0L);
+ void save_override(T & t){
+ this->basic_binary_oarchive<Archive>::save_override(t);
}
void init(unsigned int flags) {
if(0 != (flags & no_header))
diff --git a/boost/archive/codecvt_null.hpp b/boost/archive/codecvt_null.hpp
index 75387a970e..324122b78a 100644
--- a/boost/archive/codecvt_null.hpp
+++ b/boost/archive/codecvt_null.hpp
@@ -61,7 +61,7 @@ public:
template<>
class codecvt_null<wchar_t> : public std::codecvt<wchar_t, char, std::mbstate_t>
{
- virtual BOOST_WARCHIVE_DECL(std::codecvt_base::result)
+ virtual BOOST_WARCHIVE_DECL std::codecvt_base::result
do_out(
std::mbstate_t & state,
const wchar_t * first1,
@@ -71,7 +71,7 @@ class codecvt_null<wchar_t> : public std::codecvt<wchar_t, char, std::mbstate_t>
char * last2,
char * & next2
) const;
- virtual BOOST_WARCHIVE_DECL(std::codecvt_base::result)
+ virtual BOOST_WARCHIVE_DECL std::codecvt_base::result
do_in(
std::mbstate_t & state,
const char * first1,
diff --git a/boost/archive/detail/abi_prefix.hpp b/boost/archive/detail/abi_prefix.hpp
index e39ef11f18..debf79e9f0 100644
--- a/boost/archive/detail/abi_prefix.hpp
+++ b/boost/archive/detail/abi_prefix.hpp
@@ -14,7 +14,3 @@
# pragma warning(disable : 4251 4231 4660 4275)
#endif
-#if defined( __BORLANDC__ )
-#pragma nopushoptwarn
-#endif
-
diff --git a/boost/archive/detail/abi_suffix.hpp b/boost/archive/detail/abi_suffix.hpp
index a283b36cf3..4e054d6621 100644
--- a/boost/archive/detail/abi_suffix.hpp
+++ b/boost/archive/detail/abi_suffix.hpp
@@ -13,7 +13,3 @@
#endif
#include <boost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
-#if defined( __BORLANDC__ )
-#pragma nopushoptwarn
-#endif
-
diff --git a/boost/archive/detail/archive_serializer_map.hpp b/boost/archive/detail/archive_serializer_map.hpp
index 53fcae4045..5432bfc73e 100644
--- a/boost/archive/detail/archive_serializer_map.hpp
+++ b/boost/archive/detail/archive_serializer_map.hpp
@@ -36,12 +36,11 @@ namespace detail {
class basic_serializer;
template<class Archive>
-class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
-archive_serializer_map {
+class BOOST_SYMBOL_VISIBLE archive_serializer_map {
public:
- static bool insert(const basic_serializer * bs);
- static void erase(const basic_serializer * bs);
- static const basic_serializer * find(
+ static BOOST_ARCHIVE_OR_WARCHIVE_DECL bool insert(const basic_serializer * bs);
+ static BOOST_ARCHIVE_OR_WARCHIVE_DECL void erase(const basic_serializer * bs);
+ static BOOST_ARCHIVE_OR_WARCHIVE_DECL const basic_serializer * find(
const boost::serialization::extended_type_info & type_
);
};
diff --git a/boost/archive/detail/basic_archive_impl.hpp b/boost/archive/detail/basic_archive_impl.hpp
deleted file mode 100644
index 860066f89f..0000000000
--- a/boost/archive/detail/basic_archive_impl.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef BOOST_ARCHIVE_DETAIL_BASIC_ARCHIVE_IMPL_HPP
-#define BOOST_ARCHIVE_DETAIL_BASIC_ARCHIVE_IMPL_HPP
-
-// MS compatible compilers support #pragma once
-#if defined(_MSC_VER)
-# pragma once
-#endif
-
-/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
-// basic_archive_impl.hpp:
-
-// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
-// Use, modification and distribution is subject to the Boost Software
-// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-// See http://www.boost.org for updates, documentation, and revision history.
-
-#include <set>
-
-#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
-
-namespace boost {
-namespace serialization {
- class extended_type_info;
-} // namespace serialization
-
-namespace archive {
-namespace detail {
-
-//////////////////////////////////////////////////////////////////////
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_archive_impl
-{
-};
-
-} // namespace detail
-} // namespace serialization
-} // namespace boost
-
-#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
-
-#endif //BOOST_ARCHIVE_DETAIL_BASIC_ARCHIVE_IMPL_HPP
-
-
-
diff --git a/boost/archive/detail/basic_config.hpp b/boost/archive/detail/basic_config.hpp
deleted file mode 100644
index 4bd2723eb2..0000000000
--- a/boost/archive/detail/basic_config.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef BOOST_ARCHIVE_DETAIL_BASIC_CONFIG_HPP
-#define BOOST_ARCHIVE_DETAIL_BASIC_CONFIG_HPP
-
-// MS compatible compilers support #pragma once
-#if defined(_MSC_VER)
-# pragma once
-#endif
-
-// basic_config.hpp ---------------------------------------------//
-
-// (c) Copyright Robert Ramey 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)
-
-// See library home page at http://www.boost.org/libs/serialization
-
-//----------------------------------------------------------------------------//
-
-// This header implements separate compilation features as described in
-// http://www.boost.org/more/separate_compilation.html
-
-#include <boost/config.hpp>
-
-#ifdef BOOST_HAS_DECLSPEC // defined in config system
-// 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_ARCHIVE_DYN_LINK
-// if they want just this one to be dynamically linked:
-#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ARCHIVE_DYN_LINK)
-// export if this is our own source, otherwise import:
-#ifdef BOOST_ARCHIVE_SOURCE
-# define BOOST_ARCHIVE_DECL __declspec(dllexport)
-#else
-# define BOOST_ARCHIVE_DECL __declspec(dllimport)
-#endif // BOOST_ARCHIVE_SOURCE
-#endif // DYN_LINK
-#endif // BOOST_HAS_DECLSPEC
-//
-// if BOOST_ARCHIVE_DECL isn't defined yet define it now:
-#ifndef BOOST_ARCHIVE_DECL
-#define BOOST_ARCHIVE_DECL
-#endif
-
-#endif // BOOST_ARCHIVE_DETAIL_BASIC_CONFIG_HPP
diff --git a/boost/archive/detail/basic_iarchive.hpp b/boost/archive/detail/basic_iarchive.hpp
index ce8dbc0793..befd0c75f2 100644
--- a/boost/archive/detail/basic_iarchive.hpp
+++ b/boost/archive/detail/basic_iarchive.hpp
@@ -37,11 +37,12 @@ namespace archive {
namespace detail {
class basic_iarchive_impl;
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iserializer;
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer;
+class basic_iserializer;
+class basic_pointer_iserializer;
+
//////////////////////////////////////////////////////////////////////
// class basic_iarchive - read serialized objects from a input stream
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iarchive :
+class BOOST_SYMBOL_VISIBLE basic_iarchive :
private boost::noncopyable,
public boost::archive::detail::helper_collection
{
@@ -56,41 +57,46 @@ class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iarchive :
virtual void vload(class_name_type &t) = 0;
virtual void vload(tracking_type &t) = 0;
protected:
- basic_iarchive(unsigned int flags);
+ BOOST_ARCHIVE_DECL basic_iarchive(unsigned int flags);
+ boost::archive::detail::helper_collection &
+ get_helper_collection(){
+ return *this;
+ }
public:
+ // some msvc versions require that the following function be public
+ // otherwise it should really protected.
// account for bogus gcc warning
#if defined(__GNUC__)
virtual
#endif
- ~basic_iarchive();
+ BOOST_ARCHIVE_DECL ~basic_iarchive();
// note: NOT part of the public API.
- void next_object_pointer(void *t);
- void register_basic_serializer(
+ BOOST_ARCHIVE_DECL void next_object_pointer(void *t);
+ BOOST_ARCHIVE_DECL void register_basic_serializer(
const basic_iserializer & bis
);
- void load_object(
+ BOOST_ARCHIVE_DECL void load_object(
void *t,
const basic_iserializer & bis
);
- const basic_pointer_iserializer *
+ BOOST_ARCHIVE_DECL const basic_pointer_iserializer *
load_pointer(
void * & t,
const basic_pointer_iserializer * bpis_ptr,
const basic_pointer_iserializer * (*finder)(
const boost::serialization::extended_type_info & eti
)
-
);
// real public API starts here
- void
+ BOOST_ARCHIVE_DECL void
set_library_version(library_version_type archive_library_version);
- library_version_type
+ BOOST_ARCHIVE_DECL library_version_type
get_library_version() const;
- unsigned int
+ BOOST_ARCHIVE_DECL unsigned int
get_flags() const;
- void
+ BOOST_ARCHIVE_DECL void
reset_object_address(const void * new_address, const void * old_address);
- void
+ BOOST_ARCHIVE_DECL void
delete_created_pointers();
};
diff --git a/boost/archive/detail/basic_iserializer.hpp b/boost/archive/detail/basic_iserializer.hpp
index 3bff3e1256..240f0bc06e 100644
--- a/boost/archive/detail/basic_iserializer.hpp
+++ b/boost/archive/detail/basic_iserializer.hpp
@@ -39,23 +39,23 @@ namespace serialization {
namespace archive {
namespace detail {
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iarchive;
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer;
+class basic_iarchive;
+class basic_pointer_iserializer;
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iserializer :
+class BOOST_SYMBOL_VISIBLE basic_iserializer :
public basic_serializer
{
private:
basic_pointer_iserializer *m_bpis;
protected:
- explicit basic_iserializer(
+ explicit BOOST_ARCHIVE_DECL basic_iserializer(
const boost::serialization::extended_type_info & type
);
// account for bogus gcc warning
#if defined(__GNUC__)
virtual
#endif
- ~basic_iserializer();
+ BOOST_ARCHIVE_DECL ~basic_iserializer();
public:
bool serialized_as_pointer() const {
return m_bpis != NULL;
diff --git a/boost/archive/detail/basic_oarchive.hpp b/boost/archive/detail/basic_oarchive.hpp
index fe192f0ab3..702c5604bc 100644
--- a/boost/archive/detail/basic_oarchive.hpp
+++ b/boost/archive/detail/basic_oarchive.hpp
@@ -35,12 +35,12 @@ namespace archive {
namespace detail {
class basic_oarchive_impl;
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer;
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer;
+class basic_oserializer;
+class basic_pointer_oserializer;
//////////////////////////////////////////////////////////////////////
// class basic_oarchive - write serialized objects to an output stream
-class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oarchive :
+class BOOST_SYMBOL_VISIBLE basic_oarchive :
private boost::noncopyable,
public boost::archive::detail::helper_collection
{
@@ -59,22 +59,26 @@ class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oarchive :
virtual void vsave(const class_name_type & t) = 0;
virtual void vsave(const tracking_type t) = 0;
protected:
- basic_oarchive(unsigned int flags = 0);
+ BOOST_ARCHIVE_DECL basic_oarchive(unsigned int flags = 0);
+ BOOST_ARCHIVE_DECL boost::archive::detail::helper_collection &
+ get_helper_collection(){
+ return *this;
+ }
// account for bogus gcc warning
#if defined(__GNUC__)
virtual
#endif
- ~basic_oarchive();
+ BOOST_ARCHIVE_DECL ~basic_oarchive();
public:
// note: NOT part of the public interface
- void register_basic_serializer(
+ BOOST_ARCHIVE_DECL void register_basic_serializer(
const basic_oserializer & bos
);
- void save_object(
+ BOOST_ARCHIVE_DECL void save_object(
const void *x,
const basic_oserializer & bos
);
- void save_pointer(
+ BOOST_ARCHIVE_DECL void save_pointer(
const void * t,
const basic_pointer_oserializer * bpos_ptr
);
@@ -82,9 +86,9 @@ public:
vsave(NULL_POINTER_TAG);
}
// real public interface starts here
- void end_preamble(); // default implementation does nothing
- library_version_type get_library_version() const;
- unsigned int get_flags() const;
+ BOOST_ARCHIVE_DECL void end_preamble(); // default implementation does nothing
+ BOOST_ARCHIVE_DECL library_version_type get_library_version() const;
+ BOOST_ARCHIVE_DECL unsigned int get_flags() const;
};
} // namespace detail
diff --git a/boost/archive/detail/basic_oserializer.hpp b/boost/archive/detail/basic_oserializer.hpp
index 6ae063f55d..7a710ba6bc 100644
--- a/boost/archive/detail/basic_oserializer.hpp
+++ b/boost/archive/detail/basic_oserializer.hpp
@@ -40,23 +40,23 @@ namespace serialization {
namespace archive {
namespace detail {
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oarchive;
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer;
+class basic_oarchive;
+class basic_pointer_oserializer;
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer :
+class BOOST_SYMBOL_VISIBLE basic_oserializer :
public basic_serializer
{
private:
basic_pointer_oserializer *m_bpos;
protected:
- explicit basic_oserializer(
+ explicit BOOST_ARCHIVE_DECL basic_oserializer(
const boost::serialization::extended_type_info & type_
);
// account for bogus gcc warning
#if defined(__GNUC__)
virtual
#endif
- ~basic_oserializer();
+ BOOST_ARCHIVE_DECL ~basic_oserializer();
public:
bool serialized_as_pointer() const {
return m_bpos != NULL;
diff --git a/boost/archive/detail/basic_pointer_iserializer.hpp b/boost/archive/detail/basic_pointer_iserializer.hpp
index 86badc1937..23b9f906dc 100644
--- a/boost/archive/detail/basic_pointer_iserializer.hpp
+++ b/boost/archive/detail/basic_pointer_iserializer.hpp
@@ -37,20 +37,20 @@ namespace serialization {
namespace archive {
namespace detail {
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iarchive;
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iserializer;
+class basic_iarchive;
+class basic_iserializer;
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer
+class BOOST_SYMBOL_VISIBLE basic_pointer_iserializer
: public basic_serializer {
protected:
- explicit basic_pointer_iserializer(
+ explicit BOOST_ARCHIVE_DECL basic_pointer_iserializer(
const boost::serialization::extended_type_info & type_
);
// account for bogus gcc warning
#if defined(__GNUC__)
virtual
#endif
- ~basic_pointer_iserializer();
+ BOOST_ARCHIVE_DECL ~basic_pointer_iserializer();
public:
virtual void * heap_allocation() const = 0;
virtual const basic_iserializer & get_basic_serializer() const = 0;
diff --git a/boost/archive/detail/basic_pointer_oserializer.hpp b/boost/archive/detail/basic_pointer_oserializer.hpp
index bafc46a1d7..868e2fa580 100644
--- a/boost/archive/detail/basic_pointer_oserializer.hpp
+++ b/boost/archive/detail/basic_pointer_oserializer.hpp
@@ -36,14 +36,14 @@ namespace serialization {
namespace archive {
namespace detail {
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oarchive;
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer;
+class basic_oarchive;
+class basic_oserializer;
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer :
+class BOOST_SYMBOL_VISIBLE basic_pointer_oserializer :
public basic_serializer
{
protected:
- explicit basic_pointer_oserializer(
+ explicit BOOST_ARCHIVE_DECL basic_pointer_oserializer(
const boost::serialization::extended_type_info & type_
);
public:
@@ -51,7 +51,7 @@ public:
#if defined(__GNUC__)
virtual
#endif
- ~basic_pointer_oserializer();
+ BOOST_ARCHIVE_DECL ~basic_pointer_oserializer();
virtual const basic_oserializer & get_basic_serializer() const = 0;
virtual void save_object_ptr(
basic_oarchive & ar,
diff --git a/boost/archive/detail/basic_serializer_map.hpp b/boost/archive/detail/basic_serializer_map.hpp
index 202c20e1ff..7934180336 100644
--- a/boost/archive/detail/basic_serializer_map.hpp
+++ b/boost/archive/detail/basic_serializer_map.hpp
@@ -34,7 +34,7 @@ namespace detail {
class basic_serializer;
-class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+class BOOST_SYMBOL_VISIBLE
basic_serializer_map : public
boost::noncopyable
{
@@ -50,9 +50,9 @@ basic_serializer_map : public
> map_type;
map_type m_map;
public:
- bool insert(const basic_serializer * bs);
- void erase(const basic_serializer * bs);
- const basic_serializer * find(
+ BOOST_ARCHIVE_DECL bool insert(const basic_serializer * bs);
+ BOOST_ARCHIVE_DECL void erase(const basic_serializer * bs);
+ BOOST_ARCHIVE_DECL const basic_serializer * find(
const boost::serialization::extended_type_info & type_
) const;
private:
diff --git a/boost/archive/detail/common_iarchive.hpp b/boost/archive/detail/common_iarchive.hpp
index 45e6d34b3e..b4c44d2767 100644
--- a/boost/archive/detail/common_iarchive.hpp
+++ b/boost/archive/detail/common_iarchive.hpp
@@ -62,7 +62,7 @@ private:
protected:
// default processing - invoke serialization library
template<class T>
- void load_override(T & t, BOOST_PFTO int){
+ void load_override(T & t){
archive::load(* this->This(), t);
}
// default implementations of functions which emit start/end tags for
diff --git a/boost/archive/detail/common_oarchive.hpp b/boost/archive/detail/common_oarchive.hpp
index 0d7474bcdc..13c71bc5a8 100644
--- a/boost/archive/detail/common_oarchive.hpp
+++ b/boost/archive/detail/common_oarchive.hpp
@@ -65,7 +65,7 @@ private:
protected:
// default processing - invoke serialization library
template<class T>
- void save_override(T & t, BOOST_PFTO int){
+ void save_override(T & t){
archive::save(* this->This(), t);
}
void save_start(const char * /*name*/){}
diff --git a/boost/archive/detail/decl.hpp b/boost/archive/detail/decl.hpp
index 44e22be96b..bb386d86f8 100644
--- a/boost/archive/detail/decl.hpp
+++ b/boost/archive/detail/decl.hpp
@@ -22,58 +22,38 @@
// http://www.boost.org/more/separate_compilation.html
#include <boost/config.hpp>
-#include <boost/preprocessor/facilities/empty.hpp>
-#if defined(BOOST_HAS_DECLSPEC)
- #if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK))
- #if defined(BOOST_ARCHIVE_SOURCE)
- #if defined(__BORLANDC__)
- #define BOOST_ARCHIVE_DECL(T) T __export
- #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) T __export
- #else
- #define BOOST_ARCHIVE_DECL(T) __declspec(dllexport) T
- #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) __declspec(dllexport) T
- #endif
- #else
- #if defined(__BORLANDC__)
- #define BOOST_ARCHIVE_DECL(T) T __import
- #else
- #define BOOST_ARCHIVE_DECL(T) __declspec(dllimport) T
- #endif
- #endif
- #if defined(BOOST_WARCHIVE_SOURCE)
- #if defined(__BORLANDC__)
- #define BOOST_WARCHIVE_DECL(T) T __export
- #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) T __export
- #else
- #define BOOST_WARCHIVE_DECL(T) __declspec(dllexport) T
- #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) __declspec(dllexport) T
- #endif
- #else
- #if defined(__BORLANDC__)
- #define BOOST_WARCHIVE_DECL(T) T __import
- #else
- #define BOOST_WARCHIVE_DECL(T) __declspec(dllimport) T
- #endif
- #endif
- #if !defined(BOOST_WARCHIVE_SOURCE) && !defined(BOOST_ARCHIVE_SOURCE)
- #if defined(__BORLANDC__)
- #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) T __import
- #else
- #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) __declspec(dllimport) T
- #endif
- #endif
+#if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK))
+ #if defined(BOOST_ARCHIVE_SOURCE)
+ #define BOOST_ARCHIVE_DECL BOOST_SYMBOL_EXPORT
+ #else
+ #define BOOST_ARCHIVE_DECL BOOST_SYMBOL_IMPORT
#endif
-#endif // BOOST_HAS_DECLSPEC
+ #if defined(BOOST_WARCHIVE_SOURCE)
+ #define BOOST_WARCHIVE_DECL BOOST_SYMBOL_EXPORT
+ #else
+ #define BOOST_WARCHIVE_DECL BOOST_SYMBOL_IMPORT
+ #endif
+ #if !defined(BOOST_WARCHIVE_SOURCE) && !defined(BOOST_ARCHIVE_SOURCE)
+ #define BOOST_ARCHIVE_OR_WARCHIVE_DECL BOOST_SYMBOL_IMPORT
+ #endif
+
+ #if defined(BOOST_WARCHIVE_SOURCE) || defined(BOOST_ARCHIVE_SOURCE)
+ #define BOOST_ARCHIVE_OR_WARCHIVE_DECL BOOST_SYMBOL_EXPORT
+ #else
+ #define BOOST_ARCHIVE_OR_WARCHIVE_DECL BOOST_SYMBOL_IMPORT
+ #endif
+
+#endif
#if ! defined(BOOST_ARCHIVE_DECL)
- #define BOOST_ARCHIVE_DECL(T) T
+ #define BOOST_ARCHIVE_DECL
#endif
#if ! defined(BOOST_WARCHIVE_DECL)
- #define BOOST_WARCHIVE_DECL(T) T
+ #define BOOST_WARCHIVE_DECL
#endif
#if ! defined(BOOST_ARCHIVE_OR_WARCHIVE_DECL)
- #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) T
+ #define BOOST_ARCHIVE_OR_WARCHIVE_DECL
#endif
#endif // BOOST_ARCHIVE_DETAIL_DECL_HPP
diff --git a/boost/archive/detail/helper_collection.hpp b/boost/archive/detail/helper_collection.hpp
index cfa644f7d4..edb4125e30 100644
--- a/boost/archive/detail/helper_collection.hpp
+++ b/boost/archive/detail/helper_collection.hpp
@@ -55,11 +55,12 @@ class helper_collection
collection m_collection;
struct predicate {
+ BOOST_DELETED_FUNCTION(predicate & operator=(const predicate & rhs))
+ public:
const void * const m_ti;
bool operator()(helper_value_type const &rhs) const {
return m_ti == rhs.first;
}
- predicate & operator=(const void * ti); // to suppress warning
predicate(const void * ti) :
m_ti(ti)
{}
@@ -69,7 +70,7 @@ protected:
~helper_collection(){}
public:
template<typename Helper>
- Helper& get_helper(void * const id = 0) {
+ Helper& find_helper(void * const id = 0) {
collection::const_iterator it =
std::find_if(
m_collection.begin(),
diff --git a/boost/archive/detail/interface_iarchive.hpp b/boost/archive/detail/interface_iarchive.hpp
index b7bd1659f3..4a99e28b59 100644
--- a/boost/archive/detail/interface_iarchive.hpp
+++ b/boost/archive/detail/interface_iarchive.hpp
@@ -20,6 +20,7 @@
#include <boost/mpl/bool.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/detail/iserializer.hpp>
+#include <boost/archive/detail/helper_collection.hpp>
#include <boost/serialization/singleton.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
@@ -27,7 +28,7 @@ namespace boost {
namespace archive {
namespace detail {
-class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer;
+class basic_pointer_iserializer;
template<class Archive>
class interface_iarchive
@@ -55,9 +56,16 @@ public:
this->This()->register_basic_serializer(bpis.get_basic_serializer());
return & bpis;
}
+ template<class Helper>
+ Helper &
+ get_helper(void * const id = 0){
+ helper_collection & hc = this->This()->get_helper_collection();
+ return hc.template find_helper<Helper>(id);
+ }
+
template<class T>
Archive & operator>>(T & t){
- this->This()->load_override(t, 0);
+ this->This()->load_override(t);
return * this->This();
}
diff --git a/boost/archive/detail/interface_oarchive.hpp b/boost/archive/detail/interface_oarchive.hpp
index 7ae71768a8..187013b6cd 100644
--- a/boost/archive/detail/interface_oarchive.hpp
+++ b/boost/archive/detail/interface_oarchive.hpp
@@ -29,7 +29,7 @@ namespace boost {
namespace archive {
namespace detail {
-class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer;
+class BOOST_ARCHIVE_OR_WARCHIVE_DECL basic_pointer_oserializer;
template<class Archive>
class interface_oarchive
@@ -57,22 +57,25 @@ public:
this->This()->register_basic_serializer(bpos.get_basic_serializer());
return & bpos;
}
+
+ template<class Helper>
+ Helper &
+ get_helper(void * const id = 0){
+ helper_collection & hc = this->This()->get_helper_collection();
+ return hc.template find_helper<Helper>(id);
+ }
template<class T>
- Archive & operator<<(T & t){
- this->This()->save_override(t, 0);
+ Archive & operator<<(const T & t){
+ this->This()->save_override(t);
return * this->This();
}
// the & operator
template<class T>
- Archive & operator&(T & t){
- #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
- return * this->This() << const_cast<const T &>(t);
- #else
- return * this->This() << t;
- #endif
- }
+ Archive & operator&(const T & t){
+ return * this ->This() << t;
+ };
};
} // namespace detail
diff --git a/boost/archive/detail/iserializer.hpp b/boost/archive/detail/iserializer.hpp
index 65dfe8e305..d6d3f42f6e 100644
--- a/boost/archive/detail/iserializer.hpp
+++ b/boost/archive/detail/iserializer.hpp
@@ -58,8 +58,7 @@ namespace std{
#include <boost/serialization/assume_abstract.hpp>
#define DONT_USE_HAS_NEW_OPERATOR ( \
- defined(__BORLANDC__) \
- || BOOST_WORKAROUND(__IBMCPP__, < 1210) \
+ BOOST_WORKAROUND(__IBMCPP__, < 1210) \
|| defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x590) \
)
#if ! DONT_USE_HAS_NEW_OPERATOR
@@ -618,40 +617,6 @@ inline void load(Archive & ar, T &t){
typex::invoke(ar, t);
}
-#if 0
-
-// BORLAND
-#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560))
-// borland has a couple of problems
-// a) if function is partially specialized - see below
-// const paramters are transformed to non-const ones
-// b) implementation of base_object can't be made to work
-// correctly which results in all base_object s being const.
-// So, strip off the const for borland. This breaks the trap
-// for loading const objects - but I see no alternative
-template<class Archive, class T>
-inline void load(Archive &ar, const T & t){
- load(ar, const_cast<T &>(t));
-}
-#endif
-
-// let wrappers through.
-#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-template<class Archive, class T>
-inline void load_wrapper(Archive &ar, const T&t, mpl::true_){
- boost::archive::load(ar, const_cast<T&>(t));
-}
-
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560))
-template<class Archive, class T>
-inline void load(Archive &ar, const T&t){
- load_wrapper(ar,t,serialization::is_wrapper< T >());
-}
-#endif
-#endif
-
-#endif
-
} // namespace archive
} // namespace boost
diff --git a/boost/archive/detail/polymorphic_iarchive_route.hpp b/boost/archive/detail/polymorphic_iarchive_route.hpp
index a8eb7aa94a..2c57a3f51c 100644
--- a/boost/archive/detail/polymorphic_iarchive_route.hpp
+++ b/boost/archive/detail/polymorphic_iarchive_route.hpp
@@ -39,8 +39,8 @@ namespace serialization {
namespace archive {
namespace detail{
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iserializer;
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer;
+class BOOST_ARCHIVE_DECL basic_iserializer;
+class BOOST_ARCHIVE_DECL basic_pointer_iserializer;
#ifdef BOOST_MSVC
# pragma warning(push)
@@ -166,10 +166,13 @@ private:
virtual void load_end(const char * name){
ArchiveImplementation::load_end(name);
}
-
virtual void register_basic_serializer(const basic_iserializer & bis){
ArchiveImplementation::register_basic_serializer(bis);
}
+ virtual helper_collection &
+ get_helper_collection(){
+ return ArchiveImplementation::get_helper_collection();
+ }
public:
// this can't be inheriteded because they appear in mulitple
// parents
diff --git a/boost/archive/detail/polymorphic_oarchive_route.hpp b/boost/archive/detail/polymorphic_oarchive_route.hpp
index 9211df2aa7..ae750133a8 100644
--- a/boost/archive/detail/polymorphic_oarchive_route.hpp
+++ b/boost/archive/detail/polymorphic_oarchive_route.hpp
@@ -39,8 +39,8 @@ namespace serialization {
namespace archive {
namespace detail{
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer;
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer;
+class BOOST_ARCHIVE_DECL basic_oserializer;
+class BOOST_ARCHIVE_DECL basic_pointer_oserializer;
#ifdef BOOST_MSVC
# pragma warning(push)
@@ -160,6 +160,10 @@ private:
virtual void register_basic_serializer(const detail::basic_oserializer & bos){
ArchiveImplementation::register_basic_serializer(bos);
}
+ virtual helper_collection &
+ get_helper_collection(){
+ return ArchiveImplementation::get_helper_collection();
+ }
public:
// this can't be inheriteded because they appear in mulitple
// parents
diff --git a/boost/archive/impl/archive_serializer_map.ipp b/boost/archive/impl/archive_serializer_map.ipp
index c8ad96b3d7..8dabf0d08f 100644
--- a/boost/archive/impl/archive_serializer_map.ipp
+++ b/boost/archive/impl/archive_serializer_map.ipp
@@ -37,7 +37,7 @@ namespace extra_detail { // anon
#endif
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(bool)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL bool
archive_serializer_map<Archive>::insert(const basic_serializer * bs){
return boost::serialization::singleton<
extra_detail::map<Archive>
@@ -45,7 +45,7 @@ archive_serializer_map<Archive>::insert(const basic_serializer * bs){
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
archive_serializer_map<Archive>::erase(const basic_serializer * bs){
if(boost::serialization::singleton<
extra_detail::map<Archive>
@@ -57,7 +57,7 @@ archive_serializer_map<Archive>::erase(const basic_serializer * bs){
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(const basic_serializer *)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL const basic_serializer *
archive_serializer_map<Archive>::find(
const boost::serialization::extended_type_info & eti
) {
diff --git a/boost/archive/impl/basic_binary_iarchive.ipp b/boost/archive/impl/basic_binary_iarchive.ipp
index 5067b09819..d5619ab6cf 100644
--- a/boost/archive/impl/basic_binary_iarchive.ipp
+++ b/boost/archive/impl/basic_binary_iarchive.ipp
@@ -32,11 +32,11 @@ namespace archive {
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// implementation of binary_binary_archive
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-basic_binary_iarchive<Archive>::load_override(class_name_type & t, int){
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+basic_binary_iarchive<Archive>::load_override(class_name_type & t){
std::string cn;
cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
- load_override(cn, 0);
+ load_override(cn);
if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1))
boost::serialization::throw_exception(
archive_exception(archive_exception::invalid_class_name)
@@ -47,8 +47,8 @@ basic_binary_iarchive<Archive>::load_override(class_name_type & t, int){
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-basic_binary_iarchive<Archive>::init(){
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+basic_binary_iarchive<Archive>::init(void){
// read signature in an archive version independent manner
std::string file_signature;
diff --git a/boost/archive/impl/basic_binary_iprimitive.ipp b/boost/archive/impl/basic_binary_iprimitive.ipp
index e22c3bd66b..bee7bafea9 100644
--- a/boost/archive/impl/basic_binary_iprimitive.ipp
+++ b/boost/archive/impl/basic_binary_iprimitive.ipp
@@ -37,7 +37,7 @@ namespace archive {
// implementation of basic_binary_iprimitive
template<class Archive, class Elem, class Tr>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_iprimitive<Archive, Elem, Tr>::init()
{
// Detect attempts to pass native binary archives across
@@ -90,7 +90,7 @@ basic_binary_iprimitive<Archive, Elem, Tr>::init()
}
template<class Archive, class Elem, class Tr>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_iprimitive<Archive, Elem, Tr>::load(wchar_t * ws)
{
std::size_t l; // number of wchar_t !!!
@@ -100,7 +100,7 @@ basic_binary_iprimitive<Archive, Elem, Tr>::load(wchar_t * ws)
}
template<class Archive, class Elem, class Tr>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_iprimitive<Archive, Elem, Tr>::load(std::string & s)
{
std::size_t l;
@@ -117,7 +117,7 @@ basic_binary_iprimitive<Archive, Elem, Tr>::load(std::string & s)
#ifndef BOOST_NO_CWCHAR
template<class Archive, class Elem, class Tr>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_iprimitive<Archive, Elem, Tr>::load(char * s)
{
std::size_t l;
@@ -129,7 +129,7 @@ basic_binary_iprimitive<Archive, Elem, Tr>::load(char * s)
#ifndef BOOST_NO_STD_WSTRING
template<class Archive, class Elem, class Tr>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_iprimitive<Archive, Elem, Tr>::load(std::wstring & ws)
{
std::size_t l;
@@ -145,7 +145,7 @@ basic_binary_iprimitive<Archive, Elem, Tr>::load(std::wstring & ws)
#endif
template<class Archive, class Elem, class Tr>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_binary_iprimitive<Archive, Elem, Tr>::basic_binary_iprimitive(
std::basic_streambuf<Elem, Tr> & sb,
bool no_codecvt
@@ -194,7 +194,7 @@ class input_streambuf_access : public std::basic_streambuf<Elem, Tr> {
// scoped_ptr requires that archive_locale be a complete type at time of
// destruction so define destructor here rather than in the header
template<class Archive, class Elem, class Tr>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_binary_iprimitive<Archive, Elem, Tr>::~basic_binary_iprimitive(){
// push back unread characters
//destructor can't throw !
diff --git a/boost/archive/impl/basic_binary_oarchive.ipp b/boost/archive/impl/basic_binary_oarchive.ipp
index 467fd6fe96..d5a019d32b 100644
--- a/boost/archive/impl/basic_binary_oarchive.ipp
+++ b/boost/archive/impl/basic_binary_oarchive.ipp
@@ -28,11 +28,7 @@ namespace archive {
// implementation of binary_binary_oarchive
template<class Archive>
-#if !defined(__BORLANDC__)
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-#else
-void
-#endif
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_oarchive<Archive>::init(){
// write signature in an archive version independent manner
const std::string file_signature(BOOST_ARCHIVE_SIGNATURE());
diff --git a/boost/archive/impl/basic_binary_oprimitive.ipp b/boost/archive/impl/basic_binary_oprimitive.ipp
index 238617d5ed..88cc12433c 100644
--- a/boost/archive/impl/basic_binary_oprimitive.ipp
+++ b/boost/archive/impl/basic_binary_oprimitive.ipp
@@ -41,7 +41,7 @@ namespace archive {
// implementation of basic_binary_oprimitive
template<class Archive, class Elem, class Tr>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_oprimitive<Archive, Elem, Tr>::init()
{
// record native sizes of fundamental types
@@ -57,7 +57,7 @@ basic_binary_oprimitive<Archive, Elem, Tr>::init()
}
template<class Archive, class Elem, class Tr>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_oprimitive<Archive, Elem, Tr>::save(const char * s)
{
std::size_t l = std::strlen(s);
@@ -66,7 +66,7 @@ basic_binary_oprimitive<Archive, Elem, Tr>::save(const char * s)
}
template<class Archive, class Elem, class Tr>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_oprimitive<Archive, Elem, Tr>::save(const std::string &s)
{
std::size_t l = static_cast<std::size_t>(s.size());
@@ -76,7 +76,7 @@ basic_binary_oprimitive<Archive, Elem, Tr>::save(const std::string &s)
#ifndef BOOST_NO_CWCHAR
template<class Archive, class Elem, class Tr>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_oprimitive<Archive, Elem, Tr>::save(const wchar_t * ws)
{
std::size_t l = std::wcslen(ws);
@@ -87,7 +87,7 @@ basic_binary_oprimitive<Archive, Elem, Tr>::save(const wchar_t * ws)
#ifndef BOOST_NO_STD_WSTRING
template<class Archive, class Elem, class Tr>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_oprimitive<Archive, Elem, Tr>::save(const std::wstring &ws)
{
std::size_t l = ws.size();
@@ -97,7 +97,7 @@ basic_binary_oprimitive<Archive, Elem, Tr>::save(const std::wstring &ws)
#endif
template<class Archive, class Elem, class Tr>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_binary_oprimitive<Archive, Elem, Tr>::basic_binary_oprimitive(
std::basic_streambuf<Elem, Tr> & sb,
bool no_codecvt
@@ -146,7 +146,7 @@ class output_streambuf_access : public std::basic_streambuf<Elem, Tr> {
// scoped_ptr requires that g be a complete type at time of
// destruction so define destructor here rather than in the header
template<class Archive, class Elem, class Tr>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_binary_oprimitive<Archive, Elem, Tr>::~basic_binary_oprimitive(){
// flush buffer
//destructor can't throw
diff --git a/boost/archive/impl/basic_text_iarchive.ipp b/boost/archive/impl/basic_text_iarchive.ipp
index 8d364f9b5f..9ec8c6588c 100644
--- a/boost/archive/impl/basic_text_iarchive.ipp
+++ b/boost/archive/impl/basic_text_iarchive.ipp
@@ -29,11 +29,11 @@ namespace archive {
// implementation of text_text_archive
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-basic_text_iarchive<Archive>::load_override(class_name_type & t, int){
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+basic_text_iarchive<Archive>::load_override(class_name_type & t){
std::string cn;
cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
- load_override(cn, 0);
+ load_override(cn);
if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1))
boost::serialization::throw_exception(
archive_exception(archive_exception::invalid_class_name)
@@ -44,7 +44,7 @@ basic_text_iarchive<Archive>::load_override(class_name_type & t, int){
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_text_iarchive<Archive>::init(void){
// read signature in an archive version independent manner
std::string file_signature;
diff --git a/boost/archive/impl/basic_text_iprimitive.ipp b/boost/archive/impl/basic_text_iprimitive.ipp
index 9b66789698..e245dc540f 100644
--- a/boost/archive/impl/basic_text_iprimitive.ipp
+++ b/boost/archive/impl/basic_text_iprimitive.ipp
@@ -19,7 +19,6 @@ namespace std{
#endif
#include <boost/serialization/throw_exception.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/archive/basic_text_iprimitive.hpp>
#include <boost/archive/codecvt_null.hpp>
@@ -53,7 +52,7 @@ namespace detail {
// translate base64 text into binary and copy into buffer
// until buffer is full.
template<class IStream>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_text_iprimitive<IStream>::load_binary(
void *address,
std::size_t count
@@ -87,11 +86,7 @@ basic_text_iprimitive<IStream>::load_binary(
>
binary;
- binary i = binary(
- BOOST_MAKE_PFTO_WRAPPER(
- iterators::istream_iterator<CharType>(is)
- )
- );
+ binary i = binary(iterators::istream_iterator<CharType>(is));
char * caddr = static_cast<char *>(address);
@@ -112,7 +107,7 @@ basic_text_iprimitive<IStream>::load_binary(
}
template<class IStream>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_text_iprimitive<IStream>::basic_text_iprimitive(
IStream &is_,
bool no_codecvt
@@ -142,7 +137,7 @@ basic_text_iprimitive<IStream>::basic_text_iprimitive(
#endif
template<class IStream>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_text_iprimitive<IStream>::~basic_text_iprimitive(){
is.sync();
}
diff --git a/boost/archive/impl/basic_text_oarchive.ipp b/boost/archive/impl/basic_text_oarchive.ipp
index 4170c9718f..44bc1401fd 100644
--- a/boost/archive/impl/basic_text_oarchive.ipp
+++ b/boost/archive/impl/basic_text_oarchive.ipp
@@ -27,7 +27,7 @@ namespace archive {
// implementation of basic_text_oarchive
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_text_oarchive<Archive>::newtoken()
{
switch(delimiter){
@@ -48,7 +48,7 @@ basic_text_oarchive<Archive>::newtoken()
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_text_oarchive<Archive>::init(){
// write signature in an archive version independent manner
const std::string file_signature(BOOST_ARCHIVE_SIGNATURE());
diff --git a/boost/archive/impl/basic_text_oprimitive.ipp b/boost/archive/impl/basic_text_oprimitive.ipp
index 10e2133840..f2b0a10a60 100644
--- a/boost/archive/impl/basic_text_oprimitive.ipp
+++ b/boost/archive/impl/basic_text_oprimitive.ipp
@@ -10,7 +10,6 @@
#include <cstddef> // NULL
#include <algorithm> // std::copy
-#include <boost/serialization/pfto.hpp>
#include <boost/archive/basic_text_oprimitive.hpp>
#include <boost/archive/codecvt_null.hpp>
@@ -26,7 +25,7 @@ namespace archive {
// translate to base64 and copy in to buffer.
template<class OStream>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_text_oprimitive<OStream>::save_binary(
const void *address,
std::size_t count
@@ -59,9 +58,9 @@ basic_text_oprimitive<OStream>::save_binary(
boost::archive::iterators::ostream_iterator<CharType> oi(os);
std::copy(
- base64_text(BOOST_MAKE_PFTO_WRAPPER(static_cast<const char *>(address))),
+ base64_text(static_cast<const char *>(address)),
base64_text(
- BOOST_MAKE_PFTO_WRAPPER(static_cast<const char *>(address) + count)
+ static_cast<const char *>(address) + count
),
oi
);
@@ -75,7 +74,7 @@ basic_text_oprimitive<OStream>::save_binary(
}
template<class OStream>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_text_oprimitive<OStream>::basic_text_oprimitive(
OStream & os_,
bool no_codecvt
@@ -105,7 +104,7 @@ basic_text_oprimitive<OStream>::basic_text_oprimitive(
#endif
template<class OStream>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_text_oprimitive<OStream>::~basic_text_oprimitive(){
os << std::endl;
}
diff --git a/boost/archive/impl/basic_xml_grammar.hpp b/boost/archive/impl/basic_xml_grammar.hpp
index 66ca1f0b29..70a6013abc 100644
--- a/boost/archive/impl/basic_xml_grammar.hpp
+++ b/boost/archive/impl/basic_xml_grammar.hpp
@@ -72,14 +72,14 @@ public:
friend struct return_values;
private:
- typedef BOOST_DEDUCED_TYPENAME std::basic_istream<CharType> IStream;
- typedef BOOST_DEDUCED_TYPENAME std::basic_string<CharType> StringType;
- typedef BOOST_DEDUCED_TYPENAME boost::spirit::classic::chset<CharType> chset_t;
- typedef BOOST_DEDUCED_TYPENAME boost::spirit::classic::chlit<CharType> chlit_t;
- typedef BOOST_DEDUCED_TYPENAME boost::spirit::classic::scanner<
- BOOST_DEDUCED_TYPENAME std::basic_string<CharType>::iterator
+ typedef typename std::basic_istream<CharType> IStream;
+ typedef typename std::basic_string<CharType> StringType;
+ typedef typename boost::spirit::classic::chset<CharType> chset_t;
+ typedef typename boost::spirit::classic::chlit<CharType> chlit_t;
+ typedef typename boost::spirit::classic::scanner<
+ typename std::basic_string<CharType>::iterator
> scanner_t;
- typedef BOOST_DEDUCED_TYPENAME boost::spirit::classic::rule<scanner_t> rule_t;
+ typedef typename boost::spirit::classic::rule<scanner_t> rule_t;
// Start grammar definition
rule_t
Reference,
diff --git a/boost/archive/impl/basic_xml_iarchive.ipp b/boost/archive/impl/basic_xml_iarchive.ipp
index 52dfde1a23..9e670120f0 100644
--- a/boost/archive/impl/basic_xml_iarchive.ipp
+++ b/boost/archive/impl/basic_xml_iarchive.ipp
@@ -24,7 +24,7 @@ namespace archive {
// implementation of xml_text_archive
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_xml_iarchive<Archive>::load_start(const char *name){
// if there's no name
if(NULL == name)
@@ -41,7 +41,7 @@ basic_xml_iarchive<Archive>::load_start(const char *name){
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_xml_iarchive<Archive>::load_end(const char *name){
// if there's no name
if(NULL == name)
@@ -77,37 +77,37 @@ basic_xml_iarchive<Archive>::load_end(const char *name){
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-basic_xml_iarchive<Archive>::load_override(object_id_type & t, int){
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+basic_xml_iarchive<Archive>::load_override(object_id_type & t){
t = object_id_type(this->This()->gimpl->rv.object_id);
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-basic_xml_iarchive<Archive>::load_override(version_type & t, int){
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+basic_xml_iarchive<Archive>::load_override(version_type & t){
t = version_type(this->This()->gimpl->rv.version);
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-basic_xml_iarchive<Archive>::load_override(class_id_type & t, int){
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+basic_xml_iarchive<Archive>::load_override(class_id_type & t){
t = class_id_type(this->This()->gimpl->rv.class_id);
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-basic_xml_iarchive<Archive>::load_override(tracking_type & t, int){
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+basic_xml_iarchive<Archive>::load_override(tracking_type & t){
t = this->This()->gimpl->rv.tracking_level;
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_xml_iarchive<Archive>::basic_xml_iarchive(unsigned int flags) :
detail::common_iarchive<Archive>(flags),
depth(0)
{}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_xml_iarchive<Archive>::~basic_xml_iarchive(){}
} // namespace archive
diff --git a/boost/archive/impl/basic_xml_oarchive.ipp b/boost/archive/impl/basic_xml_oarchive.ipp
index 0c57a12c90..5db1e13096 100644
--- a/boost/archive/impl/basic_xml_oarchive.ipp
+++ b/boost/archive/impl/basic_xml_oarchive.ipp
@@ -58,7 +58,7 @@ struct XML_name {
// implemenations of functions common to both types of xml output
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_xml_oarchive<Archive>::write_attribute(
const char *attribute_name,
int t,
@@ -72,7 +72,7 @@ basic_xml_oarchive<Archive>::write_attribute(
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_xml_oarchive<Archive>::write_attribute(
const char *attribute_name,
const char *key
@@ -85,7 +85,7 @@ basic_xml_oarchive<Archive>::write_attribute(
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_xml_oarchive<Archive>::indent(){
int i;
for(i = depth; i-- > 0;)
@@ -93,7 +93,7 @@ basic_xml_oarchive<Archive>::indent(){
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_xml_oarchive<Archive>::save_start(const char *name)
{
if(NULL == name)
@@ -115,7 +115,7 @@ basic_xml_oarchive<Archive>::save_start(const char *name)
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_xml_oarchive<Archive>::save_end(const char *name)
{
if(NULL == name)
@@ -139,7 +139,7 @@ basic_xml_oarchive<Archive>::save_end(const char *name)
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_xml_oarchive<Archive>::end_preamble(){
if(pending_preamble){
this->This()->put('>');
@@ -148,14 +148,14 @@ basic_xml_oarchive<Archive>::end_preamble(){
}
#if 0
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-basic_xml_oarchive<Archive>::save_override(const object_id_type & t, int)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+basic_xml_oarchive<Archive>::save_override(const object_id_type & t)
{
int i = t.t; // extra .t is for borland
write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_");
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_xml_oarchive<Archive>::save_override(
const object_reference_type & t,
int
@@ -164,8 +164,8 @@ basic_xml_oarchive<Archive>::save_override(
write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_");
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-basic_xml_oarchive<Archive>::save_override(const version_type & t, int)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+basic_xml_oarchive<Archive>::save_override(const version_type & t)
{
int i = t.t; // extra .t is for borland
write_attribute(BOOST_ARCHIVE_XML_VERSION(), i);
@@ -173,55 +173,52 @@ basic_xml_oarchive<Archive>::save_override(const version_type & t, int)
#endif
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-basic_xml_oarchive<Archive>::save_override(const object_id_type & t, int)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+basic_xml_oarchive<Archive>::save_override(const object_id_type & t)
{
// borland doesn't do conversion of STRONG_TYPEDEFs very well
const unsigned int i = t;
write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_");
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_xml_oarchive<Archive>::save_override(
- const object_reference_type & t,
- int
+ const object_reference_type & t
){
const unsigned int i = t;
write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_");
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-basic_xml_oarchive<Archive>::save_override(const version_type & t, int)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+basic_xml_oarchive<Archive>::save_override(const version_type & t)
{
const unsigned int i = t;
write_attribute(BOOST_ARCHIVE_XML_VERSION(), i);
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-basic_xml_oarchive<Archive>::save_override(const class_id_type & t, int)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+basic_xml_oarchive<Archive>::save_override(const class_id_type & t)
{
write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t);
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_xml_oarchive<Archive>::save_override(
- const class_id_reference_type & t,
- int
+ const class_id_reference_type & t
){
write_attribute(BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE(), t);
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_xml_oarchive<Archive>::save_override(
- const class_id_optional_type & t,
- int
+ const class_id_optional_type & t
){
write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t);
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-basic_xml_oarchive<Archive>::save_override(const class_name_type & t, int)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+basic_xml_oarchive<Archive>::save_override(const class_name_type & t)
{
const char * key = t;
if(NULL == key)
@@ -230,14 +227,14 @@ basic_xml_oarchive<Archive>::save_override(const class_name_type & t, int)
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
-basic_xml_oarchive<Archive>::save_override(const tracking_type & t, int)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
+basic_xml_oarchive<Archive>::save_override(const tracking_type & t)
{
write_attribute(BOOST_ARCHIVE_XML_TRACKING(), t.t);
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
+BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_xml_oarchive<Archive>::init(){
// xml header
this->This()->put("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n");
@@ -250,7 +247,7 @@ basic_xml_oarchive<Archive>::init(){
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_xml_oarchive<Archive>::basic_xml_oarchive(unsigned int flags) :
detail::common_oarchive<Archive>(flags),
depth(0),
@@ -260,7 +257,7 @@ basic_xml_oarchive<Archive>::basic_xml_oarchive(unsigned int flags) :
}
template<class Archive>
-BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_xml_oarchive<Archive>::~basic_xml_oarchive(){
if(0 == (this->get_flags() & no_header)){
BOOST_TRY{
diff --git a/boost/archive/impl/text_iarchive_impl.ipp b/boost/archive/impl/text_iarchive_impl.ipp
index f14c0d8e2a..ae4e2750ce 100644
--- a/boost/archive/impl/text_iarchive_impl.ipp
+++ b/boost/archive/impl/text_iarchive_impl.ipp
@@ -28,7 +28,7 @@ namespace boost {
namespace archive {
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
text_iarchive_impl<Archive>::load(char *s)
{
std::size_t size;
@@ -41,7 +41,7 @@ text_iarchive_impl<Archive>::load(char *s)
}
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
text_iarchive_impl<Archive>::load(std::string &s)
{
std::size_t size;
@@ -60,7 +60,7 @@ text_iarchive_impl<Archive>::load(std::string &s)
#ifndef BOOST_NO_CWCHAR
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
text_iarchive_impl<Archive>::load(wchar_t *ws)
{
std::size_t size;
@@ -74,7 +74,7 @@ text_iarchive_impl<Archive>::load(wchar_t *ws)
#ifndef BOOST_NO_STD_WSTRING
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
text_iarchive_impl<Archive>::load(std::wstring &ws)
{
std::size_t size;
@@ -93,19 +93,19 @@ text_iarchive_impl<Archive>::load(std::wstring &ws)
#endif // BOOST_NO_CWCHAR
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
-text_iarchive_impl<Archive>::load_override(class_name_type & t, int){
- basic_text_iarchive<Archive>::load_override(t, 0);
+BOOST_ARCHIVE_DECL void
+text_iarchive_impl<Archive>::load_override(class_name_type & t){
+ basic_text_iarchive<Archive>::load_override(t);
}
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
text_iarchive_impl<Archive>::init(){
basic_text_iarchive<Archive>::init();
}
template<class Archive>
-BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_DECL
text_iarchive_impl<Archive>::text_iarchive_impl(
std::istream & is,
unsigned int flags
diff --git a/boost/archive/impl/text_oarchive_impl.ipp b/boost/archive/impl/text_oarchive_impl.ipp
index 2df0b46019..4ff488f4cb 100644
--- a/boost/archive/impl/text_oarchive_impl.ipp
+++ b/boost/archive/impl/text_oarchive_impl.ipp
@@ -38,7 +38,7 @@ namespace archive {
// of template parameters used to create a text_oprimitive
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
text_oarchive_impl<Archive>::save(const char * s)
{
const std::size_t len = std::ostream::traits_type::length(s);
@@ -48,7 +48,7 @@ text_oarchive_impl<Archive>::save(const char * s)
}
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
text_oarchive_impl<Archive>::save(const std::string &s)
{
const std::size_t size = s.size();
@@ -60,7 +60,7 @@ text_oarchive_impl<Archive>::save(const std::string &s)
#ifndef BOOST_NO_CWCHAR
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
text_oarchive_impl<Archive>::save(const wchar_t * ws)
{
const std::size_t l = std::wcslen(ws);
@@ -72,7 +72,7 @@ text_oarchive_impl<Archive>::save(const wchar_t * ws)
#ifndef BOOST_NO_STD_WSTRING
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
text_oarchive_impl<Archive>::save(const std::wstring &ws)
{
const std::size_t l = ws.size();
@@ -84,7 +84,7 @@ text_oarchive_impl<Archive>::save(const std::wstring &ws)
#endif // BOOST_NO_CWCHAR
template<class Archive>
-BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_DECL
text_oarchive_impl<Archive>::text_oarchive_impl(
std::ostream & os,
unsigned int flags
@@ -104,7 +104,7 @@ text_oarchive_impl<Archive>::text_oarchive_impl(
}
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
text_oarchive_impl<Archive>::save_binary(const void *address, std::size_t count){
put('\n');
this->end_preamble();
diff --git a/boost/archive/impl/text_wiarchive_impl.ipp b/boost/archive/impl/text_wiarchive_impl.ipp
index 6938c22659..12af2b9f12 100644
--- a/boost/archive/impl/text_wiarchive_impl.ipp
+++ b/boost/archive/impl/text_wiarchive_impl.ipp
@@ -29,7 +29,7 @@ namespace archive {
// implementation of wiprimtives functions
//
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
text_wiarchive_impl<Archive>::load(char *s)
{
std::size_t size;
@@ -43,7 +43,7 @@ text_wiarchive_impl<Archive>::load(char *s)
}
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
text_wiarchive_impl<Archive>::load(std::string &s)
{
std::size_t size;
@@ -63,7 +63,7 @@ text_wiarchive_impl<Archive>::load(std::string &s)
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
text_wiarchive_impl<Archive>::load(wchar_t *s)
{
std::size_t size;
@@ -78,7 +78,7 @@ text_wiarchive_impl<Archive>::load(wchar_t *s)
#ifndef BOOST_NO_STD_WSTRING
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
text_wiarchive_impl<Archive>::load(std::wstring &ws)
{
std::size_t size;
@@ -97,7 +97,7 @@ text_wiarchive_impl<Archive>::load(std::wstring &ws)
#endif
template<class Archive>
-BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_WARCHIVE_DECL
text_wiarchive_impl<Archive>::text_wiarchive_impl(
std::wistream & is,
unsigned int flags
diff --git a/boost/archive/impl/text_woarchive_impl.ipp b/boost/archive/impl/text_woarchive_impl.ipp
index 6683f528c0..2b6d427cd3 100644
--- a/boost/archive/impl/text_woarchive_impl.ipp
+++ b/boost/archive/impl/text_woarchive_impl.ipp
@@ -31,7 +31,7 @@ namespace archive {
// implementation of woarchive functions
//
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
text_woarchive_impl<Archive>::save(const char *s)
{
// note: superfluous local variable fixes borland warning
@@ -43,7 +43,7 @@ text_woarchive_impl<Archive>::save(const char *s)
}
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
text_woarchive_impl<Archive>::save(const std::string &s)
{
const std::size_t size = s.size();
@@ -56,7 +56,7 @@ text_woarchive_impl<Archive>::save(const std::string &s)
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
text_woarchive_impl<Archive>::save(const wchar_t *ws)
{
const std::size_t size = std::wostream::traits_type::length(ws);
@@ -68,7 +68,7 @@ text_woarchive_impl<Archive>::save(const wchar_t *ws)
#ifndef BOOST_NO_STD_WSTRING
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
text_woarchive_impl<Archive>::save(const std::wstring &ws)
{
const std::size_t size = ws.length();
diff --git a/boost/archive/impl/xml_iarchive_impl.ipp b/boost/archive/impl/xml_iarchive_impl.ipp
index 89e09818d8..7639ecb3b1 100644
--- a/boost/archive/impl/xml_iarchive_impl.ipp
+++ b/boost/archive/impl/xml_iarchive_impl.ipp
@@ -51,7 +51,7 @@ namespace archive {
#ifndef BOOST_NO_CWCHAR
#ifndef BOOST_NO_STD_WSTRING
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
xml_iarchive_impl<Archive>::load(std::wstring &ws){
std::string s;
bool result = gimpl->parse_string(is, s);
@@ -85,7 +85,7 @@ xml_iarchive_impl<Archive>::load(std::wstring &ws){
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
xml_iarchive_impl<Archive>::load(wchar_t * ws){
std::string s;
bool result = gimpl->parse_string(is, s);
@@ -117,7 +117,7 @@ xml_iarchive_impl<Archive>::load(wchar_t * ws){
#endif // BOOST_NO_CWCHAR
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
xml_iarchive_impl<Archive>::load(std::string &s){
bool result = gimpl->parse_string(is, s);
if(! result)
@@ -127,7 +127,7 @@ xml_iarchive_impl<Archive>::load(std::string &s){
}
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
xml_iarchive_impl<Archive>::load(char * s){
std::string tstring;
bool result = gimpl->parse_string(is, tstring);
@@ -140,8 +140,8 @@ xml_iarchive_impl<Archive>::load(char * s){
}
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
-xml_iarchive_impl<Archive>::load_override(class_name_type & t, int){
+BOOST_ARCHIVE_DECL void
+xml_iarchive_impl<Archive>::load_override(class_name_type & t){
const std::string & s = gimpl->rv.class_name;
if(s.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)
boost::serialization::throw_exception(
@@ -153,7 +153,7 @@ xml_iarchive_impl<Archive>::load_override(class_name_type & t, int){
}
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
xml_iarchive_impl<Archive>::init(){
gimpl->init(is);
this->set_library_version(
@@ -162,7 +162,7 @@ xml_iarchive_impl<Archive>::init(){
}
template<class Archive>
-BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_DECL
xml_iarchive_impl<Archive>::xml_iarchive_impl(
std::istream &is_,
unsigned int flags
@@ -179,7 +179,7 @@ xml_iarchive_impl<Archive>::xml_iarchive_impl(
}
template<class Archive>
-BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_DECL
xml_iarchive_impl<Archive>::~xml_iarchive_impl(){
if(0 == (this->get_flags() & no_header)){
BOOST_TRY{
diff --git a/boost/archive/impl/xml_oarchive_impl.ipp b/boost/archive/impl/xml_oarchive_impl.ipp
index ab1a2177bc..9e714f3ca6 100644
--- a/boost/archive/impl/xml_oarchive_impl.ipp
+++ b/boost/archive/impl/xml_oarchive_impl.ipp
@@ -42,15 +42,15 @@ void save_iterator(std::ostream &os, InputIterator begin, InputIterator end){
boost::archive::iterators::xml_escape<InputIterator>
> translator;
std::copy(
- translator(BOOST_MAKE_PFTO_WRAPPER(begin)),
- translator(BOOST_MAKE_PFTO_WRAPPER(end)),
+ translator(begin),
+ translator(end),
boost::archive::iterators::ostream_iterator<char>(os)
);
}
#ifndef BOOST_NO_STD_WSTRING
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
xml_oarchive_impl<Archive>::save(const std::wstring & ws){
// at least one library doesn't typedef value_type for strings
// so rather than using string directly make a pointer iterator out of it
@@ -61,7 +61,7 @@ xml_oarchive_impl<Archive>::save(const std::wstring & ws){
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
xml_oarchive_impl<Archive>::save(const wchar_t * ws){
save_iterator(os, ws, ws + std::wcslen(ws));
}
@@ -70,7 +70,7 @@ xml_oarchive_impl<Archive>::save(const wchar_t * ws){
#endif // BOOST_NO_CWCHAR
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
xml_oarchive_impl<Archive>::save(const std::string & s){
// at least one library doesn't typedef value_type for strings
// so rather than using string directly make a pointer iterator out of it
@@ -78,27 +78,27 @@ xml_oarchive_impl<Archive>::save(const std::string & s){
const char *
> xml_escape_translator;
std::copy(
- xml_escape_translator(BOOST_MAKE_PFTO_WRAPPER(s.data())),
- xml_escape_translator(BOOST_MAKE_PFTO_WRAPPER(s.data()+ s.size())),
+ xml_escape_translator(s.data()),
+ xml_escape_translator(s.data()+ s.size()),
boost::archive::iterators::ostream_iterator<char>(os)
);
}
template<class Archive>
-BOOST_ARCHIVE_DECL(void)
+BOOST_ARCHIVE_DECL void
xml_oarchive_impl<Archive>::save(const char * s){
typedef boost::archive::iterators::xml_escape<
const char *
> xml_escape_translator;
std::copy(
- xml_escape_translator(BOOST_MAKE_PFTO_WRAPPER(s)),
- xml_escape_translator(BOOST_MAKE_PFTO_WRAPPER(s + std::strlen(s))),
+ xml_escape_translator(s),
+ xml_escape_translator(s + std::strlen(s)),
boost::archive::iterators::ostream_iterator<char>(os)
);
}
template<class Archive>
-BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_ARCHIVE_DECL
xml_oarchive_impl<Archive>::xml_oarchive_impl(
std::ostream & os_,
unsigned int flags
diff --git a/boost/archive/impl/xml_wiarchive_impl.ipp b/boost/archive/impl/xml_wiarchive_impl.ipp
index 257b57590d..a837347edb 100644
--- a/boost/archive/impl/xml_wiarchive_impl.ipp
+++ b/boost/archive/impl/xml_wiarchive_impl.ipp
@@ -28,7 +28,6 @@ namespace std{
#include <boost/io/ios_state.hpp>
#include <boost/core/no_exceptions_support.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/serialization/string.hpp>
#include <boost/archive/basic_xml_archive.hpp>
@@ -52,10 +51,10 @@ namespace { // anonymous
void copy_to_ptr(char * s, const std::wstring & ws){
std::copy(
iterators::mb_from_wchar<std::wstring::const_iterator>(
- BOOST_MAKE_PFTO_WRAPPER(ws.begin())
+ ws.begin()
),
iterators::mb_from_wchar<std::wstring::const_iterator>(
- BOOST_MAKE_PFTO_WRAPPER(ws.end())
+ ws.end()
),
s
);
@@ -65,7 +64,7 @@ void copy_to_ptr(char * s, const std::wstring & ws){
} // anonymous
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
xml_wiarchive_impl<Archive>::load(std::string & s){
std::wstring ws;
bool result = gimpl->parse_string(is, ws);
@@ -80,10 +79,10 @@ xml_wiarchive_impl<Archive>::load(std::string & s){
s.reserve(ws.size());
std::copy(
iterators::mb_from_wchar<std::wstring::iterator>(
- BOOST_MAKE_PFTO_WRAPPER(ws.begin())
+ ws.begin()
),
iterators::mb_from_wchar<std::wstring::iterator>(
- BOOST_MAKE_PFTO_WRAPPER(ws.end())
+ ws.end()
),
std::back_inserter(s)
);
@@ -91,7 +90,7 @@ xml_wiarchive_impl<Archive>::load(std::string & s){
#ifndef BOOST_NO_STD_WSTRING
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
xml_wiarchive_impl<Archive>::load(std::wstring & ws){
bool result = gimpl->parse_string(is, ws);
if(! result)
@@ -102,7 +101,7 @@ xml_wiarchive_impl<Archive>::load(std::wstring & ws){
#endif
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
xml_wiarchive_impl<Archive>::load(char * s){
std::wstring ws;
bool result = gimpl->parse_string(is, ws);
@@ -115,7 +114,7 @@ xml_wiarchive_impl<Archive>::load(char * s){
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
xml_wiarchive_impl<Archive>::load(wchar_t * ws){
std::wstring twstring;
bool result = gimpl->parse_string(is, twstring);
@@ -129,8 +128,8 @@ xml_wiarchive_impl<Archive>::load(wchar_t * ws){
#endif
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
-xml_wiarchive_impl<Archive>::load_override(class_name_type & t, int){
+BOOST_WARCHIVE_DECL void
+xml_wiarchive_impl<Archive>::load_override(class_name_type & t){
const std::wstring & ws = gimpl->rv.class_name;
if(ws.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)
boost::serialization::throw_exception(
@@ -140,7 +139,7 @@ xml_wiarchive_impl<Archive>::load_override(class_name_type & t, int){
}
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
xml_wiarchive_impl<Archive>::init(){
gimpl->init(is);
this->set_library_version(
@@ -149,7 +148,7 @@ xml_wiarchive_impl<Archive>::init(){
}
template<class Archive>
-BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_WARCHIVE_DECL
xml_wiarchive_impl<Archive>::xml_wiarchive_impl(
std::wistream &is_,
unsigned int flags
@@ -177,7 +176,7 @@ xml_wiarchive_impl<Archive>::xml_wiarchive_impl(
}
template<class Archive>
-BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_WARCHIVE_DECL
xml_wiarchive_impl<Archive>::~xml_wiarchive_impl(){
if(0 == (this->get_flags() & no_header)){
BOOST_TRY{
diff --git a/boost/archive/impl/xml_woarchive_impl.ipp b/boost/archive/impl/xml_woarchive_impl.ipp
index 1e5139bc40..d5586d51ae 100644
--- a/boost/archive/impl/xml_woarchive_impl.ipp
+++ b/boost/archive/impl/xml_woarchive_impl.ipp
@@ -52,14 +52,14 @@ void save_iterator(std::wostream &os, InputIterator begin, InputIterator end){
iterators::xml_escape<InputIterator>
> xmbtows;
std::copy(
- xmbtows(BOOST_MAKE_PFTO_WRAPPER(begin)),
- xmbtows(BOOST_MAKE_PFTO_WRAPPER(end)),
+ xmbtows(begin),
+ xmbtows(end),
boost::archive::iterators::ostream_iterator<wchar_t>(os)
);
}
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
xml_woarchive_impl<Archive>::save(const std::string & s){
// note: we don't use s.begin() and s.end() because dinkumware
// doesn't have string::value_type defined. So use a wrapper
@@ -71,47 +71,47 @@ xml_woarchive_impl<Archive>::save(const std::string & s){
#ifndef BOOST_NO_STD_WSTRING
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
xml_woarchive_impl<Archive>::save(const std::wstring & ws){
#if 0
typedef iterators::xml_escape<std::wstring::const_iterator> xmbtows;
std::copy(
- xmbtows(BOOST_MAKE_PFTO_WRAPPER(ws.begin())),
- xmbtows(BOOST_MAKE_PFTO_WRAPPER(ws.end())),
+ xmbtows(ws.begin()),
+ xmbtows(ws.end()),
boost::archive::iterators::ostream_iterator<wchar_t>(os)
);
#endif
typedef iterators::xml_escape<const wchar_t *> xmbtows;
std::copy(
- xmbtows(BOOST_MAKE_PFTO_WRAPPER(ws.data())),
- xmbtows(BOOST_MAKE_PFTO_WRAPPER(ws.data() + ws.size())),
+ xmbtows(ws.data()),
+ xmbtows(ws.data() + ws.size()),
boost::archive::iterators::ostream_iterator<wchar_t>(os)
);
}
#endif //BOOST_NO_STD_WSTRING
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
xml_woarchive_impl<Archive>::save(const char * s){
save_iterator(os, s, s + std::strlen(s));
}
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<class Archive>
-BOOST_WARCHIVE_DECL(void)
+BOOST_WARCHIVE_DECL void
xml_woarchive_impl<Archive>::save(const wchar_t * ws){
os << ws;
typedef iterators::xml_escape<const wchar_t *> xmbtows;
std::copy(
- xmbtows(BOOST_MAKE_PFTO_WRAPPER(ws)),
- xmbtows(BOOST_MAKE_PFTO_WRAPPER(ws + std::wcslen(ws))),
+ xmbtows(ws),
+ xmbtows(ws + std::wcslen(ws)),
boost::archive::iterators::ostream_iterator<wchar_t>(os)
);
}
#endif
template<class Archive>
-BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_WARCHIVE_DECL
xml_woarchive_impl<Archive>::xml_woarchive_impl(
std::wostream & os_,
unsigned int flags
@@ -141,7 +141,7 @@ xml_woarchive_impl<Archive>::xml_woarchive_impl(
}
template<class Archive>
-BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY())
+BOOST_WARCHIVE_DECL
xml_woarchive_impl<Archive>::~xml_woarchive_impl(){
}
diff --git a/boost/archive/iterators/base64_from_binary.hpp b/boost/archive/iterators/base64_from_binary.hpp
index 836d93de35..00c4e10c10 100644
--- a/boost/archive/iterators/base64_from_binary.hpp
+++ b/boost/archive/iterators/base64_from_binary.hpp
@@ -25,8 +25,6 @@ namespace std{
} // namespace std
#endif
-#include <boost/serialization/pfto.hpp>
-
#include <boost/iterator/transform_iterator.hpp>
#include <boost/archive/iterators/dataflow_exception.hpp>
@@ -88,9 +86,9 @@ class base64_from_binary :
public:
// make composible buy using templated constructor
template<class T>
- base64_from_binary(BOOST_PFTO_WRAPPER(T) start) :
+ base64_from_binary(T start) :
super_t(
- Base(BOOST_MAKE_PFTO_WRAPPER(static_cast< T >(start))),
+ Base(static_cast< T >(start)),
detail::from_6_bit<CharType>()
)
{}
diff --git a/boost/archive/iterators/binary_from_base64.hpp b/boost/archive/iterators/binary_from_base64.hpp
index 9d2c87ebee..2eb7828251 100644
--- a/boost/archive/iterators/binary_from_base64.hpp
+++ b/boost/archive/iterators/binary_from_base64.hpp
@@ -19,7 +19,6 @@
#include <boost/assert.hpp>
#include <boost/serialization/throw_exception.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/static_assert.hpp>
#include <boost/iterator/transform_iterator.hpp>
@@ -96,9 +95,9 @@ class binary_from_base64 : public
public:
// make composible buy using templated constructor
template<class T>
- binary_from_base64(BOOST_PFTO_WRAPPER(T) start) :
+ binary_from_base64(T start) :
super_t(
- Base(BOOST_MAKE_PFTO_WRAPPER(static_cast< T >(start))),
+ Base(static_cast< T >(start)),
detail::to_6_bit<CharType>()
)
{}
diff --git a/boost/archive/iterators/insert_linebreaks.hpp b/boost/archive/iterators/insert_linebreaks.hpp
index 7fbc79f13a..2504b030db 100644
--- a/boost/archive/iterators/insert_linebreaks.hpp
+++ b/boost/archive/iterators/insert_linebreaks.hpp
@@ -23,8 +23,6 @@
namespace std{ using ::memcpy; }
#endif
-#include <boost/serialization/pfto.hpp>
-
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/iterator_traits.hpp>
@@ -83,8 +81,8 @@ private:
public:
// make composible buy using templated constructor
template<class T>
- insert_linebreaks(BOOST_PFTO_WRAPPER(T) start) :
- super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast< T >(start)))),
+ insert_linebreaks(T start) :
+ super_t(Base(static_cast< T >(start))),
m_count(0)
{}
// intel 7.1 doesn't like default copy constructor
diff --git a/boost/archive/iterators/mb_from_wchar.hpp b/boost/archive/iterators/mb_from_wchar.hpp
index 04e7c7e9fe..deb798f623 100644
--- a/boost/archive/iterators/mb_from_wchar.hpp
+++ b/boost/archive/iterators/mb_from_wchar.hpp
@@ -28,7 +28,6 @@ namespace std{
} // namespace std
#endif
-#include <boost/serialization/pfto.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
namespace boost {
@@ -86,7 +85,7 @@ class mb_from_wchar
wchar_t value = * this->base_reference();
#if (defined(__MINGW32__) && ((__MINGW32_MAJOR_VERSION > 3) \
|| ((__MINGW32_MAJOR_VERSION == 3) && (__MINGW32_MINOR_VERSION >= 8))))
- m_bend = std::wcrtomb(m_buffer, value, 0);
+ m_bend = std::wcrtomb(m_buffer, value,0);
#else
m_bend = std::wctomb(m_buffer, value);
#endif
@@ -114,8 +113,8 @@ class mb_from_wchar
public:
// make composible buy using templated constructor
template<class T>
- mb_from_wchar(BOOST_PFTO_WRAPPER(T) start) :
- super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast< T >(start)))),
+ mb_from_wchar(T start) :
+ super_t(Base(static_cast< T >(start))),
m_bend(0),
m_bnext(0),
m_full(false)
diff --git a/boost/archive/iterators/remove_whitespace.hpp b/boost/archive/iterators/remove_whitespace.hpp
index 4383987051..c3580ab258 100644
--- a/boost/archive/iterators/remove_whitespace.hpp
+++ b/boost/archive/iterators/remove_whitespace.hpp
@@ -18,8 +18,6 @@
#include <boost/assert.hpp>
-#include <boost/serialization/pfto.hpp>
-
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/iterator/iterator_traits.hpp>
@@ -153,8 +151,8 @@ public:
// remove_whitespace(){} // why is this needed?
// make composible buy using templated constructor
template<class T>
- remove_whitespace(BOOST_PFTO_WRAPPER(T) start) :
- super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast< T >(start))))
+ remove_whitespace(T start) :
+ super_t(Base(static_cast< T >(start)))
{}
// intel 7.1 doesn't like default copy constructor
remove_whitespace(const remove_whitespace & rhs) :
diff --git a/boost/archive/iterators/transform_width.hpp b/boost/archive/iterators/transform_width.hpp
index 15dd8dfc0e..d042560e29 100644
--- a/boost/archive/iterators/transform_width.hpp
+++ b/boost/archive/iterators/transform_width.hpp
@@ -24,8 +24,6 @@
// character and 8 bit bytes. Lowest common multiple is 24 => 4 6 bit characters
// or 3 8 bit characters
-#include <boost/serialization/pfto.hpp>
-
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/iterator_traits.hpp>
@@ -110,8 +108,8 @@ class transform_width :
public:
// make composible buy using templated constructor
template<class T>
- transform_width(BOOST_PFTO_WRAPPER(T) start) :
- super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast< T >(start)))),
+ transform_width(T start) :
+ super_t(Base(static_cast< T >(start))),
m_buffer_out_full(false),
// To disable GCC warning, but not truly necessary
//(m_buffer_in will be initialized later before being
@@ -154,7 +152,7 @@ void transform_width<Base, BitsOut, BitsIn, CharType>::fill() {
// append these bits to the next output
// up to the size of the output
- unsigned int i = std::min(missing_bits, m_remaining_bits);
+ unsigned int i = (std::min)(missing_bits, m_remaining_bits);
// shift interesting bits to least significant position
base_value_type j = m_buffer_in >> (m_remaining_bits - i);
// and mask off the un interesting higher bits
diff --git a/boost/archive/iterators/wchar_from_mb.hpp b/boost/archive/iterators/wchar_from_mb.hpp
index ab81f17b68..ad1d4cbb7d 100644
--- a/boost/archive/iterators/wchar_from_mb.hpp
+++ b/boost/archive/iterators/wchar_from_mb.hpp
@@ -30,7 +30,6 @@ namespace std{
#endif
#include <boost/serialization/throw_exception.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/archive/iterators/dataflow_exception.hpp>
@@ -89,8 +88,8 @@ class wchar_from_mb
public:
// make composible buy using templated constructor
template<class T>
- wchar_from_mb(BOOST_PFTO_WRAPPER(T) start) :
- super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast< T >(start)))),
+ wchar_from_mb(T start) :
+ super_t(Base(static_cast< T >(start))),
m_full(false)
{}
// intel 7.1 doesn't like default copy constructor
diff --git a/boost/archive/iterators/xml_escape.hpp b/boost/archive/iterators/xml_escape.hpp
index a5d2c5120f..c838a73b86 100644
--- a/boost/archive/iterators/xml_escape.hpp
+++ b/boost/archive/iterators/xml_escape.hpp
@@ -17,7 +17,6 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/assert.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/archive/iterators/escape.hpp>
namespace boost {
@@ -40,8 +39,8 @@ public:
wchar_t fill(const wchar_t * & bstart, const wchar_t * & bend);
template<class T>
- xml_escape(BOOST_PFTO_WRAPPER(T) start) :
- super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast< T >(start))))
+ xml_escape(T start) :
+ super_t(Base(static_cast< T >(start)))
{}
// intel 7.1 doesn't like default copy constructor
xml_escape(const xml_escape & rhs) :
diff --git a/boost/archive/iterators/xml_unescape.hpp b/boost/archive/iterators/xml_unescape.hpp
index 69438ed044..6997740456 100644
--- a/boost/archive/iterators/xml_unescape.hpp
+++ b/boost/archive/iterators/xml_unescape.hpp
@@ -19,7 +19,6 @@
#include <boost/assert.hpp>
#include <boost/serialization/throw_exception.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/archive/iterators/unescape.hpp>
#include <boost/archive/iterators/dataflow_exception.hpp>
@@ -54,8 +53,8 @@ public:
value_type drain();
template<class T>
- xml_unescape(BOOST_PFTO_WRAPPER(T) start) :
- super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast< T >(start))))
+ xml_unescape(T start) :
+ super_t(Base(static_cast< T >(start)))
{}
// intel 7.1 doesn't like default copy constructor
xml_unescape(const xml_unescape & rhs) :
diff --git a/boost/archive/polymorphic_iarchive.hpp b/boost/archive/polymorphic_iarchive.hpp
index 50488a331f..7f19410dd8 100644
--- a/boost/archive/polymorphic_iarchive.hpp
+++ b/boost/archive/polymorphic_iarchive.hpp
@@ -29,7 +29,6 @@ namespace std{
#include <boost/cstdint.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/archive/detail/iserializer.hpp>
#include <boost/archive/detail/interface_iarchive.hpp>
#include <boost/serialization/nvp.hpp>
@@ -44,13 +43,13 @@ namespace serialization {
} // namespace serialization
namespace archive {
namespace detail {
- class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iarchive;
- class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iarchive;
+ class BOOST_ARCHIVE_DECL basic_iarchive;
+ class BOOST_ARCHIVE_DECL basic_iarchive;
}
class polymorphic_iarchive;
-class polymorphic_iarchive_impl :
+class BOOST_SYMBOL_VISIBLE polymorphic_iarchive_impl :
public detail::interface_iarchive<polymorphic_iarchive>
{
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
@@ -98,22 +97,19 @@ public:
virtual void load_start(const char * name) = 0;
virtual void load_end(const char * name) = 0;
virtual void register_basic_serializer(const detail::basic_iserializer & bis) = 0;
+ virtual detail::helper_collection & get_helper_collection() = 0;
// msvc and borland won't automatically pass these to the base class so
// make it explicit here
template<class T>
- void load_override(T & t, BOOST_PFTO int)
+ void load_override(T & t)
{
archive::load(* this->This(), t);
}
// special treatment for name-value pairs.
template<class T>
void load_override(
- #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
- const
- #endif
- boost::serialization::nvp< T > & t,
- int
+ const boost::serialization::nvp< T > & t
){
load_start(t.name());
archive::load(* this->This(), t.value());
@@ -156,7 +152,7 @@ public:
namespace boost {
namespace archive {
-class polymorphic_iarchive :
+class BOOST_SYMBOL_VISIBLE polymorphic_iarchive :
public polymorphic_iarchive_impl
{
public:
diff --git a/boost/archive/polymorphic_oarchive.hpp b/boost/archive/polymorphic_oarchive.hpp
index 1eb9e0b419..aa30b2ac3e 100644
--- a/boost/archive/polymorphic_oarchive.hpp
+++ b/boost/archive/polymorphic_oarchive.hpp
@@ -28,7 +28,6 @@ namespace std{
#endif
#include <boost/cstdint.hpp>
-#include <boost/serialization/pfto.hpp>
#include <boost/archive/detail/oserializer.hpp>
#include <boost/archive/detail/interface_oarchive.hpp>
#include <boost/serialization/nvp.hpp>
@@ -43,13 +42,13 @@ namespace serialization {
} // namespace serialization
namespace archive {
namespace detail {
- class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oarchive;
- class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer;
+ class BOOST_ARCHIVE_DECL basic_oarchive;
+ class BOOST_ARCHIVE_DECL basic_oserializer;
}
class polymorphic_oarchive;
-class polymorphic_oarchive_impl :
+class BOOST_SYMBOL_VISIBLE polymorphic_oarchive_impl :
public detail::interface_oarchive<polymorphic_oarchive>
{
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
@@ -98,23 +97,21 @@ public:
virtual void save_start(const char * name) = 0;
virtual void save_end(const char * name) = 0;
virtual void register_basic_serializer(const detail::basic_oserializer & bos) = 0;
+ virtual detail::helper_collection & get_helper_collection() = 0;
virtual void end_preamble() = 0;
// msvc and borland won't automatically pass these to the base class so
// make it explicit here
template<class T>
- void save_override(T & t, BOOST_PFTO int)
+ void save_override(T & t)
{
archive::save(* this->This(), t);
}
// special treatment for name-value pairs.
template<class T>
void save_override(
- #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
- const
- #endif
- ::boost::serialization::nvp< T > & t, int
+ const ::boost::serialization::nvp< T > & t
){
save_start(t.name());
archive::save(* this->This(), t.const_value());
@@ -139,7 +136,7 @@ public:
};
// note: preserve naming symmetry
-class polymorphic_oarchive :
+class BOOST_SYMBOL_VISIBLE polymorphic_oarchive :
public polymorphic_oarchive_impl
{
public:
diff --git a/boost/archive/text_iarchive.hpp b/boost/archive/text_iarchive.hpp
index 1fd0f608d3..e40db8371d 100644
--- a/boost/archive/text_iarchive.hpp
+++ b/boost/archive/text_iarchive.hpp
@@ -40,7 +40,7 @@ namespace detail {
} // namespace detail
template<class Archive>
-class text_iarchive_impl :
+class BOOST_SYMBOL_VISIBLE text_iarchive_impl :
public basic_text_iprimitive<std::istream>,
public basic_text_iarchive<Archive>
{
@@ -72,33 +72,30 @@ protected:
load(v);
t = boost::serialization::item_version_type(v);
}
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
load(char * t);
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
load(wchar_t * t);
#endif
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
load(std::string &s);
#ifndef BOOST_NO_STD_WSTRING
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
load(std::wstring &ws);
#endif
- // note: the following should not needed - but one compiler (vc 7.1)
- // fails to compile one test (test_shared_ptr) without it !!!
- // make this protected so it can be called from a derived archive
template<class T>
- void load_override(T & t, BOOST_PFTO int){
- basic_text_iarchive<Archive>::load_override(t, 0);
+ void load_override(T & t){
+ basic_text_iarchive<Archive>::load_override(t);
}
- BOOST_ARCHIVE_DECL(void)
- load_override(class_name_type & t, int);
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
+ load_override(class_name_type & t);
+ BOOST_ARCHIVE_DECL void
init();
- BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_DECL
text_iarchive_impl(std::istream & is, unsigned int flags);
// don't import inline definitions! leave this as a reminder.
- //BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+ //BOOST_ARCHIVE_DECL
~text_iarchive_impl(){};
};
@@ -119,7 +116,7 @@ protected:
namespace boost {
namespace archive {
-class text_iarchive :
+class BOOST_SYMBOL_VISIBLE text_iarchive :
public text_iarchive_impl<text_iarchive>{
public:
text_iarchive(std::istream & is_, unsigned int flags = 0) :
diff --git a/boost/archive/text_oarchive.hpp b/boost/archive/text_oarchive.hpp
index 9fd63a9b97..7eaea17232 100644
--- a/boost/archive/text_oarchive.hpp
+++ b/boost/archive/text_oarchive.hpp
@@ -47,7 +47,7 @@ namespace detail {
} // namespace detail
template<class Archive>
-class text_oarchive_impl :
+class BOOST_SYMBOL_VISIBLE text_oarchive_impl :
/* protected ? */ public basic_text_oprimitive<std::ostream>,
public basic_text_oarchive<Archive>
{
@@ -78,32 +78,32 @@ protected:
void save(const boost::serialization::item_version_type & t){
save(static_cast<const unsigned int>(t));
}
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
save(const char * t);
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
save(const wchar_t * t);
#endif
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
save(const std::string &s);
#ifndef BOOST_NO_STD_WSTRING
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
save(const std::wstring &ws);
#endif
- BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_DECL
text_oarchive_impl(std::ostream & os, unsigned int flags);
// don't import inline definitions! leave this as a reminder.
- //BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+ //BOOST_ARCHIVE_DECL
~text_oarchive_impl(){};
public:
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
save_binary(const void *address, std::size_t count);
};
// do not derive from this class. If you want to extend this functionality
// via inhertance, derived from text_oarchive_impl instead. This will
// preserve correct static polymorphism.
-class text_oarchive :
+class BOOST_SYMBOL_VISIBLE text_oarchive :
public text_oarchive_impl<text_oarchive>
{
public:
diff --git a/boost/archive/text_wiarchive.hpp b/boost/archive/text_wiarchive.hpp
index 5105d351ca..3adf068a51 100644
--- a/boost/archive/text_wiarchive.hpp
+++ b/boost/archive/text_wiarchive.hpp
@@ -44,7 +44,7 @@ namespace detail {
} // namespace detail
template<class Archive>
-class text_wiarchive_impl :
+class BOOST_SYMBOL_VISIBLE text_wiarchive_impl :
public basic_text_iprimitive<std::wistream>,
public basic_text_iarchive<Archive>
{
@@ -76,25 +76,23 @@ protected:
load(v);
t = boost::serialization::item_version_type(v);
}
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
load(char * t);
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
load(wchar_t * t);
#endif
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
load(std::string &s);
#ifndef BOOST_NO_STD_WSTRING
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
load(std::wstring &ws);
#endif
- // note: the following should not needed - but one compiler (vc 7.1)
- // fails to compile one test (test_shared_ptr) without it !!!
template<class T>
- void load_override(T & t, BOOST_PFTO int){
- basic_text_iarchive<Archive>::load_override(t, 0);
+ void load_override(T & t){
+ basic_text_iarchive<Archive>::load_override(t);
}
- BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_WARCHIVE_DECL
text_wiarchive_impl(std::wistream & is, unsigned int flags);
~text_wiarchive_impl(){};
};
@@ -116,7 +114,7 @@ protected:
namespace boost {
namespace archive {
-class text_wiarchive :
+class BOOST_SYMBOL_VISIBLE text_wiarchive :
public text_wiarchive_impl<text_wiarchive>{
public:
text_wiarchive(std::wistream & is, unsigned int flags = 0) :
diff --git a/boost/archive/text_woarchive.hpp b/boost/archive/text_woarchive.hpp
index 2f75204d2f..b6b4f8ed59 100644
--- a/boost/archive/text_woarchive.hpp
+++ b/boost/archive/text_woarchive.hpp
@@ -52,7 +52,7 @@ namespace detail {
} // namespace detail
template<class Archive>
-class text_woarchive_impl :
+class BOOST_SYMBOL_VISIBLE text_woarchive_impl :
public basic_text_oprimitive<std::wostream>,
public basic_text_oarchive<Archive>
{
@@ -83,16 +83,16 @@ protected:
void save(const boost::serialization::item_version_type & t){
save(static_cast<const unsigned int>(t));
}
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
save(const char * t);
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
save(const wchar_t * t);
#endif
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
save(const std::string &s);
#ifndef BOOST_NO_STD_WSTRING
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
save(const std::wstring &ws);
#endif
text_woarchive_impl(std::wostream & os, unsigned int flags) :
@@ -129,7 +129,7 @@ public:
// do not derive from this class. If you want to extend this functionality
// via inhertance, derived from text_oarchive_impl instead. This will
// preserve correct static polymorphism.
-class text_woarchive :
+class BOOST_SYMBOL_VISIBLE text_woarchive :
public text_woarchive_impl<text_woarchive>
{
public:
diff --git a/boost/archive/xml_archive_exception.hpp b/boost/archive/xml_archive_exception.hpp
index 622cafea41..b07f9a0c33 100644
--- a/boost/archive/xml_archive_exception.hpp
+++ b/boost/archive/xml_archive_exception.hpp
@@ -20,7 +20,6 @@
#include <boost/assert.hpp>
#include <boost/config.hpp>
-#include <boost/preprocessor/empty.hpp>
#include <boost/archive/detail/decl.hpp>
#include <boost/archive/archive_exception.hpp>
@@ -32,7 +31,7 @@ namespace archive {
//////////////////////////////////////////////////////////////////////
// exceptions thrown by xml archives
//
-class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) xml_archive_exception :
+class BOOST_SYMBOL_VISIBLE xml_archive_exception :
public virtual boost::archive::archive_exception
{
public:
@@ -41,7 +40,7 @@ public:
xml_archive_tag_mismatch,
xml_archive_tag_name_error
} exception_code;
- xml_archive_exception(
+ BOOST_ARCHIVE_DECL xml_archive_exception(
exception_code c,
const char * e1 = NULL,
const char * e2 = NULL
diff --git a/boost/archive/xml_iarchive.hpp b/boost/archive/xml_iarchive.hpp
index ecaeeebe03..055ba0f426 100644
--- a/boost/archive/xml_iarchive.hpp
+++ b/boost/archive/xml_iarchive.hpp
@@ -44,7 +44,7 @@ class basic_xml_grammar;
typedef basic_xml_grammar<char> xml_grammar;
template<class Archive>
-class xml_iarchive_impl :
+class BOOST_SYMBOL_VISIBLE xml_iarchive_impl :
public basic_text_iprimitive<std::istream>,
public basic_xml_iarchive<Archive>
{
@@ -86,29 +86,29 @@ protected:
load(v);
t = boost::serialization::item_version_type(v);
}
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
load(char * t);
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
load(wchar_t * t);
#endif
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
load(std::string &s);
#ifndef BOOST_NO_STD_WSTRING
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
load(std::wstring &ws);
#endif
template<class T>
- void load_override(T & t, BOOST_PFTO int){
- basic_xml_iarchive<Archive>::load_override(t, 0);
+ void load_override(T & t){
+ basic_xml_iarchive<Archive>::load_override(t);
}
- BOOST_ARCHIVE_DECL(void)
- load_override(class_name_type & t, int);
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
+ load_override(class_name_type & t);
+ BOOST_ARCHIVE_DECL void
init();
- BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_DECL
xml_iarchive_impl(std::istream & is, unsigned int flags);
- BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_DECL
~xml_iarchive_impl();
};
@@ -128,7 +128,7 @@ protected:
namespace boost {
namespace archive {
-class xml_iarchive :
+class BOOST_SYMBOL_VISIBLE xml_iarchive :
public xml_iarchive_impl<xml_iarchive>{
public:
xml_iarchive(std::istream & is, unsigned int flags = 0) :
diff --git a/boost/archive/xml_oarchive.hpp b/boost/archive/xml_oarchive.hpp
index 2ac4ae1d69..c5e6da9271 100644
--- a/boost/archive/xml_oarchive.hpp
+++ b/boost/archive/xml_oarchive.hpp
@@ -47,7 +47,7 @@ namespace detail {
} // namespace detail
template<class Archive>
-class xml_oarchive_impl :
+class BOOST_SYMBOL_VISIBLE xml_oarchive_impl :
public basic_text_oprimitive<std::ostream>,
public basic_xml_oarchive<Archive>
{
@@ -82,19 +82,19 @@ protected:
save(const boost::serialization::item_version_type & t){
save(static_cast<const unsigned int>(t));
}
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
save(const char * t);
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
save(const wchar_t * t);
#endif
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
save(const std::string &s);
#ifndef BOOST_NO_STD_WSTRING
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
save(const std::wstring &ws);
#endif
- BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_ARCHIVE_DECL
xml_oarchive_impl(std::ostream & os, unsigned int flags);
~xml_oarchive_impl(){}
public:
@@ -118,7 +118,7 @@ public:
// do not derive from this class. If you want to extend this functionality
// via inhertance, derived from xml_oarchive_impl instead. This will
// preserve correct static polymorphism.
-class xml_oarchive :
+class BOOST_SYMBOL_VISIBLE xml_oarchive :
public xml_oarchive_impl<xml_oarchive>
{
public:
diff --git a/boost/archive/xml_wiarchive.hpp b/boost/archive/xml_wiarchive.hpp
index a1baa1f8ab..dbc2d721a4 100644
--- a/boost/archive/xml_wiarchive.hpp
+++ b/boost/archive/xml_wiarchive.hpp
@@ -58,7 +58,7 @@ class basic_xml_grammar;
typedef basic_xml_grammar<wchar_t> xml_wgrammar;
template<class Archive>
-class xml_wiarchive_impl :
+class BOOST_SYMBOL_VISIBLE xml_wiarchive_impl :
public basic_text_iprimitive<std::wistream>,
public basic_xml_iarchive<Archive>
{
@@ -99,29 +99,29 @@ protected:
load(v);
t = boost::serialization::item_version_type(v);
}
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
load(char * t);
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
load(wchar_t * t);
#endif
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
load(std::string &s);
#ifndef BOOST_NO_STD_WSTRING
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
load(std::wstring &ws);
#endif
template<class T>
- void load_override(T & t, BOOST_PFTO int){
- basic_xml_iarchive<Archive>::load_override(t, 0);
+ void load_override(T & t){
+ basic_xml_iarchive<Archive>::load_override(t);
}
- BOOST_WARCHIVE_DECL(void)
- load_override(class_name_type & t, int);
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
+ load_override(class_name_type & t);
+ BOOST_WARCHIVE_DECL void
init();
- BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_WARCHIVE_DECL
xml_wiarchive_impl(std::wistream & is, unsigned int flags) ;
- BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_WARCHIVE_DECL
~xml_wiarchive_impl();
};
@@ -142,7 +142,7 @@ protected:
namespace boost {
namespace archive {
-class xml_wiarchive :
+class BOOST_SYMBOL_VISIBLE xml_wiarchive :
public xml_wiarchive_impl<xml_wiarchive>{
public:
xml_wiarchive(std::wistream & is, unsigned int flags = 0) :
diff --git a/boost/archive/xml_woarchive.hpp b/boost/archive/xml_woarchive.hpp
index 338bf748b3..62700162d7 100644
--- a/boost/archive/xml_woarchive.hpp
+++ b/boost/archive/xml_woarchive.hpp
@@ -61,7 +61,7 @@ namespace detail {
} // namespace detail
template<class Archive>
-class xml_woarchive_impl :
+class BOOST_SYMBOL_VISIBLE xml_woarchive_impl :
public basic_text_oprimitive<std::wostream>,
public basic_xml_oarchive<Archive>
{
@@ -97,21 +97,21 @@ protected:
save(const boost::serialization::item_version_type & t){
save(static_cast<const unsigned int>(t));
}
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
save(const char * t);
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
save(const wchar_t * t);
#endif
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
save(const std::string &s);
#ifndef BOOST_NO_STD_WSTRING
- BOOST_WARCHIVE_DECL(void)
+ BOOST_WARCHIVE_DECL void
save(const std::wstring &ws);
#endif
- BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_WARCHIVE_DECL
xml_woarchive_impl(std::wostream & os, unsigned int flags);
- BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY())
+ BOOST_WARCHIVE_DECL
~xml_woarchive_impl();
public:
void
@@ -135,7 +135,7 @@ public:
// do not derive from this class. If you want to extend this functionality
// via inhertance, derived from xml_woarchive_impl instead. This will
// preserve correct static polymorphism.
-class xml_woarchive :
+class BOOST_SYMBOL_VISIBLE xml_woarchive :
public xml_woarchive_impl<xml_woarchive>
{
public:
diff --git a/boost/bind/bind.hpp b/boost/bind/bind.hpp
index 924d0551ec..fd05131236 100644
--- a/boost/bind/bind.hpp
+++ b/boost/bind/bind.hpp
@@ -29,6 +29,8 @@
#include <boost/bind/arg.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/visit_each.hpp>
+#include <boost/core/enable_if.hpp>
+#include <boost/core/is_same.hpp>
// Borland-specific bug, visit_each() silently fails to produce code
diff --git a/boost/bind/bind_mf_cc.hpp b/boost/bind/bind_mf_cc.hpp
index 9c3d290e27..e149384ff5 100644
--- a/boost/bind/bind_mf_cc.hpp
+++ b/boost/bind/bind_mf_cc.hpp
@@ -36,8 +36,9 @@ template<class R, class T,
template<class Rt2, class R, class T,
class A1>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf0)<R, T>, typename _bi::list_av_1<A1>::type>
- BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (), A1 a1)
+ >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (), A1 a1)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf0)<R, T> F;
typedef typename _bi::list_av_1<A1>::type list_type;
@@ -46,8 +47,9 @@ template<class Rt2, class R, class T,
template<class Rt2, class R, class T,
class A1>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T>, typename _bi::list_av_1<A1>::type>
- BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () const, A1 a1)
+ >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () const, A1 a1)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T> F;
typedef typename _bi::list_av_1<A1>::type list_type;
@@ -81,8 +83,9 @@ template<class R, class T,
template<class Rt2, class R, class T,
class B1,
class A1, class A2>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
- BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1), A1 a1, A2 a2)
+ >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1), A1 a1, A2 a2)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1> F;
typedef typename _bi::list_av_2<A1, A2>::type list_type;
@@ -92,8 +95,9 @@ template<class Rt2, class R, class T,
template<class Rt2, class R, class T,
class B1,
class A1, class A2>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
- BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) const, A1 a1, A2 a2)
+ >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) const, A1 a1, A2 a2)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1> F;
typedef typename _bi::list_av_2<A1, A2>::type list_type;
@@ -127,8 +131,9 @@ template<class R, class T,
template<class Rt2, class R, class T,
class B1, class B2,
class A1, class A2, class A3>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type>
- BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2), A1 a1, A2 a2, A3 a3)
+ >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2), A1 a1, A2 a2, A3 a3)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2> F;
typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
@@ -138,8 +143,9 @@ template<class Rt2, class R, class T,
template<class Rt2, class R, class T,
class B1, class B2,
class A1, class A2, class A3>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type>
- BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) const, A1 a1, A2 a2, A3 a3)
+ >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) const, A1 a1, A2 a2, A3 a3)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2> F;
typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
@@ -173,8 +179,9 @@ template<class R, class T,
template<class Rt2, class R, class T,
class B1, class B2, class B3,
class A1, class A2, class A3, class A4>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type>
- BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3), A1 a1, A2 a2, A3 a3, A4 a4)
+ >::type BOOST_BIND(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)<R, T, B1, B2, B3> F;
typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
@@ -184,8 +191,9 @@ template<class Rt2, class R, class T,
template<class Rt2, class R, class T,
class B1, class B2, class B3,
class A1, class A2, class A3, class A4>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type>
- BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const, A1 a1, A2 a2, A3 a3, A4 a4)
+ >::type BOOST_BIND(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)<R, T, B1, B2, B3> F;
typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
@@ -219,8 +227,9 @@ template<class R, class T,
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4,
class A1, class A2, class A3, class A4, class A5>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
- BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+ >::type BOOST_BIND(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)<R, T, B1, B2, B3, B4> F;
typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
@@ -230,8 +239,9 @@ template<class Rt2, class R, class T,
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4,
class A1, class A2, class A3, class A4, class A5>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
- BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+ >::type BOOST_BIND(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)<R, T, B1, B2, B3, B4> F;
typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
@@ -265,8 +275,9 @@ template<class R, class T,
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5,
class A1, class A2, class A3, class A4, class A5, class A6>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
- BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+ >::type BOOST_BIND(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)<R, T, B1, B2, B3, B4, B5> F;
typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
@@ -276,8 +287,9 @@ template<class Rt2, class R, class T,
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5,
class A1, class A2, class A3, class A4, class A5, class A6>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
- BOOST_BIND(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)
+ >::type BOOST_BIND(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)<R, T, B1, B2, B3, B4, B5> F;
typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
@@ -311,8 +323,9 @@ template<class R, class T,
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6,
class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
- BOOST_BIND(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)
+ >::type BOOST_BIND(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)<R, T, B1, B2, B3, B4, B5, B6> F;
typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
@@ -322,8 +335,9 @@ template<class Rt2, class R, class T,
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6,
class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
- BOOST_BIND(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)
+ >::type BOOST_BIND(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)<R, T, B1, B2, B3, B4, B5, B6> F;
typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
@@ -357,8 +371,9 @@ template<class R, class T,
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6, class B7,
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
- BOOST_BIND(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)
+ >::type BOOST_BIND(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)<R, T, B1, B2, B3, B4, B5, B6, B7> F;
typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
@@ -368,8 +383,9 @@ template<class Rt2, class R, class T,
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6, class B7,
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
- BOOST_BIND(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)
+ >::type BOOST_BIND(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)<R, T, B1, B2, B3, B4, B5, B6, B7> F;
typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
@@ -403,8 +419,9 @@ template<class R, class T,
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8,
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
- BOOST_BIND(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)
+ >::type BOOST_BIND(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)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F;
typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
@@ -414,8 +431,9 @@ template<class Rt2, class R, class T,
template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8,
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+ typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
- BOOST_BIND(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)
+ >::type BOOST_BIND(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)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F;
typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
diff --git a/boost/concept/detail/general.hpp b/boost/concept/detail/general.hpp
index c88a1edd3a..525ea656c2 100644
--- a/boost/concept/detail/general.hpp
+++ b/boost/concept/detail/general.hpp
@@ -4,6 +4,7 @@
#ifndef BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP
# define BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP
+# include <boost/config.hpp>
# include <boost/preprocessor/cat.hpp>
# include <boost/concept/detail/backward_compatibility.hpp>
@@ -65,19 +66,11 @@ struct requirement_<void(*)(Model)>
# endif
-// Version check from https://svn.boost.org/trac/boost/changeset/82886
-// (boost/static_assert.hpp)
-#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)))
-#define BOOST_CONCEPT_UNUSED_TYPEDEF __attribute__((unused))
-#else
-#define BOOST_CONCEPT_UNUSED_TYPEDEF /**/
-#endif
-
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
typedef ::boost::concepts::detail::instantiate< \
&::boost::concepts::requirement_<ModelFnPtr>::failed> \
BOOST_PP_CAT(boost_concept_check,__LINE__) \
- BOOST_CONCEPT_UNUSED_TYPEDEF
+ BOOST_ATTRIBUTE_UNUSED
}}
diff --git a/boost/config/compiler/intel.hpp b/boost/config/compiler/intel.hpp
index b47610c16f..ecfacc5e70 100644
--- a/boost/config/compiler/intel.hpp
+++ b/boost/config/compiler/intel.hpp
@@ -14,6 +14,76 @@
// Intel compiler setup:
+#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500) && (defined(_MSC_VER) || defined(__GNUC__))
+
+#ifdef _MSC_VER
+
+#include <boost/config/compiler/visualc.hpp>
+
+#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
+
+#else
+
+#include <boost/config/compiler/gcc.hpp>
+
+#endif
+
+#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
+
#include "boost/config/compiler/common_edg.hpp"
#if defined(__INTEL_COMPILER)
@@ -442,9 +512,10 @@ template<> struct assert_intrinsic_wchar_t<unsigned short> {};
# define BOOST_HAS_INT128
#endif
+#endif
//
// last known and checked version:
-#if (BOOST_INTEL_CXX_VERSION > 1310)
+#if (BOOST_INTEL_CXX_VERSION > 1500)
# if defined(BOOST_ASSERT_CONFIG)
# error "Unknown compiler version - please run the configure tests and report the results"
# elif defined(_MSC_VER)
diff --git a/boost/config/compiler/visualc.hpp b/boost/config/compiler/visualc.hpp
index ce6bbeec78..93908cea50 100644
--- a/boost/config/compiler/visualc.hpp
+++ b/boost/config/compiler/visualc.hpp
@@ -67,21 +67,6 @@
#endif
-// MSVC (including the latest checked version) 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
-// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues
-// (Niels Dekker, LKEB, May 2010)
-# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION
-
#ifndef _NATIVE_WCHAR_T_DEFINED
# define BOOST_NO_INTRINSIC_WCHAR_T
#endif
@@ -172,9 +157,9 @@
# define BOOST_NO_CXX11_DECLTYPE_N3276
#endif
-// C++11 features supported by VC++ 14 (aka 2015) Preview
+// C++11 features supported by VC++ 14 (aka 2015)
//
-#if (_MSC_FULL_VER < 190022310)
+#if (_MSC_FULL_VER < 190023026)
# define BOOST_NO_CXX11_NOEXCEPT
# define BOOST_NO_CXX11_REF_QUALIFIERS
# define BOOST_NO_CXX11_USER_DEFINED_LITERALS
@@ -188,12 +173,33 @@
# 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
#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)
+#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION
// C++11 features not supported by any versions
-#define BOOST_NO_CXX11_CONSTEXPR
#define BOOST_NO_SFINAE_EXPR
#define BOOST_NO_TWO_PHASE_NAME_LOOKUP
+//
+// This is somewhat supported in VC14, but we may need to wait for
+// a service release before enabling:
+//
+#define BOOST_NO_CXX11_CONSTEXPR
// C++ 14:
#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304)
@@ -202,9 +208,6 @@
#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304)
# define BOOST_NO_CXX14_CONSTEXPR
#endif
-#if (__cplusplus < 201304) // There's no SD6 check for this....
-# define BOOST_NO_CXX14_DIGIT_SEPARATORS
-#endif
#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304)
# define BOOST_NO_CXX14_VARIABLE_TEMPLATES
#endif
@@ -284,8 +287,8 @@
#endif
//
-// last known and checked version is 19.00.22129 (VC14 Preview):
-#if (_MSC_VER > 1800 && _MSC_FULL_VER > 190022310)
+// last known and checked version is 19.00.23026 (VC++ 2015 RTM):
+#if (_MSC_VER > 1900)
# if defined(BOOST_ASSERT_CONFIG)
# error "Unknown compiler version - please run the configure tests and report the results"
# else
diff --git a/boost/config/compiler/xlcpp.hpp b/boost/config/compiler/xlcpp.hpp
new file mode 100644
index 0000000000..e369ecefd2
--- /dev/null
+++ b/boost/config/compiler/xlcpp.hpp
@@ -0,0 +1,258 @@
+// (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
+
+#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 <class T>
+// constexpr typename enable_if<pred<T> >::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 __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
+
+#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/platform/haiku.hpp b/boost/config/platform/haiku.hpp
index e3910d8424..750866c47d 100644
--- a/boost/config/platform/haiku.hpp
+++ b/boost/config/platform/haiku.hpp
@@ -11,7 +11,6 @@
#define BOOST_HAS_UNISTD_H
#define BOOST_HAS_STDINT_H
-#define BOOST_HASH_NO_EXTENSIONS
#ifndef BOOST_DISABLE_THREADS
# define BOOST_HAS_THREADS
@@ -26,7 +25,6 @@
// thread API's not auto detected:
//
#define BOOST_HAS_SCHED_YIELD
-#define BOOST_HAS_PTHREAD_YIELD
#define BOOST_HAS_GETTIMEOFDAY
// boilerplate code:
diff --git a/boost/config/select_compiler_config.hpp b/boost/config/select_compiler_config.hpp
index 3d8bdd878b..4d87093af3 100644
--- a/boost/config/select_compiler_config.hpp
+++ b/boost/config/select_compiler_config.hpp
@@ -39,7 +39,7 @@
// Intel
# define BOOST_COMPILER_CONFIG "boost/config/compiler/intel.hpp"
-#elif defined __clang__ && !defined(__CUDACC__)
+#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"
@@ -48,7 +48,7 @@
// Digital Mars C++
# define BOOST_COMPILER_CONFIG "boost/config/compiler/digitalmars.hpp"
-# elif defined __GNUC__
+# elif defined(__GNUC__) && !defined(__ibmxl__)
// GNU C++:
# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc.hpp"
@@ -92,8 +92,12 @@
// MPW MrCpp or SCpp
# define BOOST_COMPILER_CONFIG "boost/config/compiler/mpw.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
+// IBM Visual Age or IBM XL C/C++ for Linux (Big Endian)
# define BOOST_COMPILER_CONFIG "boost/config/compiler/vacpp.hpp"
#elif defined(__PGI)
diff --git a/boost/config/stdlib/dinkumware.hpp b/boost/config/stdlib/dinkumware.hpp
index 404e68634b..90c45c6c23 100644
--- a/boost/config/stdlib/dinkumware.hpp
+++ b/boost/config/stdlib/dinkumware.hpp
@@ -147,6 +147,16 @@
# define BOOST_NO_CXX11_STD_ALIGN
#endif
+#if defined(__has_include)
+#if !__has_include(<shared_mutex>)
+# define BOOST_NO_CXX14_HDR_SHARED_MUTEX
+#elif __cplusplus < 201402
+# define BOOST_NO_CXX14_HDR_SHARED_MUTEX
+#endif
+#elif !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650)
+# define BOOST_NO_CXX14_HDR_SHARED_MUTEX
+#endif
+
#if defined(BOOST_INTEL) && (BOOST_INTEL <= 1400)
// Intel's compiler can't handle this header yet:
# define BOOST_NO_CXX11_HDR_ATOMIC
@@ -155,7 +165,16 @@
// 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 _CPPLIB_VER == 650
+# define BOOST_NO_CXX11_HDR_CODECVT
+#endif
#ifdef _CPPLIB_VER
# define BOOST_DINKUMWARE_STDLIB _CPPLIB_VER
diff --git a/boost/config/stdlib/libcomo.hpp b/boost/config/stdlib/libcomo.hpp
index 5aacfb2a7c..941498d076 100644
--- a/boost/config/stdlib/libcomo.hpp
+++ b/boost/config/stdlib/libcomo.hpp
@@ -62,6 +62,16 @@
# define BOOST_NO_CXX11_STD_ALIGN
# define BOOST_NO_CXX11_ADDRESSOF
+#if defined(__has_include)
+#if !__has_include(<shared_mutex>)
+# 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
+
//
// Intrinsic type_traits support.
// The SGI STL has it's own __type_traits class, which
@@ -71,5 +81,3 @@
#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
index eee2d75d21..ab5d123544 100644
--- a/boost/config/stdlib/libcpp.hpp
+++ b/boost/config/stdlib/libcpp.hpp
@@ -67,4 +67,14 @@
// libc++ uses a non-standard messages_base
#define BOOST_NO_STD_MESSAGES
+#if defined(__has_include)
+#if !__has_include(<shared_mutex>)
+# 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
index e4ff8542e3..7d27b0cc0c 100644
--- a/boost/config/stdlib/libstdcpp3.hpp
+++ b/boost/config/stdlib/libstdcpp3.hpp
@@ -123,12 +123,12 @@
#ifdef __clang__
#if __has_include(<experimental/any>)
-# define BOOST_LIBSTDCXX_VERSION 50000
+# define BOOST_LIBSTDCXX_VERSION 50100
#elif __has_include(<shared_mutex>)
# define BOOST_LIBSTDCXX_VERSION 40900
#elif __has_include(<ext/cmath>)
# define BOOST_LIBSTDCXX_VERSION 40800
-#elif __has_include(<chrono>)
+#elif __has_include(<scoped_allocator>)
# define BOOST_LIBSTDCXX_VERSION 40700
#elif __has_include(<typeindex>)
# define BOOST_LIBSTDCXX_VERSION 40600
@@ -213,6 +213,8 @@
# 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 <regex> 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.
@@ -223,13 +225,25 @@
// As of clang-3.6, libstdc++ header <atomic> throws up errors with clang:
# define BOOST_NO_CXX11_HDR_ATOMIC
#endif
-
-// C++0x headers not yet (fully!) implemented
//
+// 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
+
+#if defined(__has_include)
+#if !__has_include(<shared_mutex>)
+# 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:
@@ -250,6 +264,9 @@
# 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)
diff --git a/boost/config/stdlib/modena.hpp b/boost/config/stdlib/modena.hpp
index f2a83888c0..7a85e0cd57 100644
--- a/boost/config/stdlib/modena.hpp
+++ b/boost/config/stdlib/modena.hpp
@@ -51,6 +51,16 @@
# define BOOST_NO_CXX11_STD_ALIGN
# define BOOST_NO_CXX11_ADDRESSOF
+#if defined(__has_include)
+#if !__has_include(<shared_mutex>)
+# 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
+
#define BOOST_STDLIB "Modena C++ standard library"
diff --git a/boost/config/stdlib/msl.hpp b/boost/config/stdlib/msl.hpp
index b8f43a1286..dd2775e10c 100644
--- a/boost/config/stdlib/msl.hpp
+++ b/boost/config/stdlib/msl.hpp
@@ -75,13 +75,14 @@
# define BOOST_NO_CXX11_STD_ALIGN
# define BOOST_NO_CXX11_ADDRESSOF
-#define BOOST_STDLIB "Metrowerks Standard Library version " BOOST_STRINGIZE(__MSL_CPP__)
-
-
-
-
-
-
-
-
+#if defined(__has_include)
+#if !__has_include(<shared_mutex>)
+# 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
+#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
index 2b4e8636c5..97a2b0b90b 100644
--- a/boost/config/stdlib/roguewave.hpp
+++ b/boost/config/stdlib/roguewave.hpp
@@ -187,3 +187,12 @@
# define BOOST_NO_CXX11_STD_ALIGN
# define BOOST_NO_CXX11_ADDRESSOF
+#if defined(__has_include)
+#if !__has_include(<shared_mutex>)
+# 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
diff --git a/boost/config/stdlib/sgi.hpp b/boost/config/stdlib/sgi.hpp
index bda77c2275..c8052717ce 100644
--- a/boost/config/stdlib/sgi.hpp
+++ b/boost/config/stdlib/sgi.hpp
@@ -145,7 +145,14 @@
# define BOOST_NO_CXX11_STD_ALIGN
# define BOOST_NO_CXX11_ADDRESSOF
-#define BOOST_STDLIB "SGI standard library"
-
-
+#if defined(__has_include)
+#if !__has_include(<shared_mutex>)
+# 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
+#define BOOST_STDLIB "SGI standard library" \ No newline at end of file
diff --git a/boost/config/stdlib/stlport.hpp b/boost/config/stdlib/stlport.hpp
index fd5d3a5a6c..bbc4176c90 100644
--- a/boost/config/stdlib/stlport.hpp
+++ b/boost/config/stdlib/stlport.hpp
@@ -235,12 +235,14 @@ namespace boost { using std::min; using std::max; }
# define BOOST_NO_CXX11_STD_ALIGN
# define BOOST_NO_CXX11_ADDRESSOF
-#define BOOST_STDLIB "STLPort standard library version " BOOST_STRINGIZE(__SGI_STL_PORT)
-
-
-
-
-
-
-
+#if defined(__has_include)
+#if !__has_include(<shared_mutex>)
+# 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
+#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
index a58ec1c5e1..4ccd0d2466 100644
--- a/boost/config/stdlib/vacpp.hpp
+++ b/boost/config/stdlib/vacpp.hpp
@@ -51,7 +51,14 @@
# define BOOST_NO_CXX11_STD_ALIGN
# define BOOST_NO_CXX11_ADDRESSOF
-#define BOOST_STDLIB "Visual Age default standard library"
-
-
+#if defined(__has_include)
+#if !__has_include(<shared_mutex>)
+# 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
+#define BOOST_STDLIB "Visual Age default standard library"
diff --git a/boost/container/adaptive_pool.hpp b/boost/container/adaptive_pool.hpp
index 1f6b6667e9..59ba37bc93 100644
--- a/boost/container/adaptive_pool.hpp
+++ b/boost/container/adaptive_pool.hpp
@@ -83,9 +83,9 @@ class adaptive_pool
typedef T * pointer;
typedef const T * const_pointer;
typedef typename ::boost::container::
- container_detail::unvoid<T>::type & reference;
- typedef const typename ::boost::container::
- container_detail::unvoid<T>::type & const_reference;
+ container_detail::unvoid_ref<T>::type reference;
+ typedef typename ::boost::container::
+ container_detail::unvoid_ref<const T>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
diff --git a/boost/container/allocator_traits.hpp b/boost/container/allocator_traits.hpp
index cdaf2eacf0..2c7900ea72 100644
--- a/boost/container/allocator_traits.hpp
+++ b/boost/container/allocator_traits.hpp
@@ -96,6 +96,10 @@ template<class T>
struct is_std_allocator< std::allocator<T> >
{ static const bool value = true; };
+template<class Allocator>
+struct is_not_std_allocator
+{ static const bool value = !is_std_allocator<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)
@@ -195,11 +199,11 @@ struct allocator_traits
const_pointer;
//reference
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
- reference, typename container_detail::unvoid<value_type>::type&)
+ reference, typename container_detail::unvoid_ref<value_type>::type)
reference;
//const_reference
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
- const_reference, const typename container_detail::unvoid<value_type>::type&)
+ const_reference, typename container_detail::unvoid_ref<const value_type>::type)
const_reference;
//void_pointer
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator,
@@ -340,7 +344,12 @@ struct allocator_traits
template <class T, class ...Args>
static void construct(Allocator & a, T* p, BOOST_FWD_REF(Args)... args)
{
- container_detail::bool_<container_detail::is_std_allocator<Allocator>::value> flag;
+ static const bool value = ::boost::move_detail::and_
+ < container_detail::is_not_std_allocator<Allocator>
+ , boost::container::container_detail::has_member_function_callable_with_construct
+ < Allocator, T*, Args... >
+ >::value;
+ container_detail::bool_<value> flag;
allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...);
}
#endif
@@ -391,25 +400,11 @@ struct allocator_traits
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T, class ...Args>
- static void priv_construct(container_detail::false_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args)
- {
- const bool value = boost::container::container_detail::
- has_member_function_callable_with_construct
- < Allocator, T*, Args... >::value;
- container_detail::bool_<value> flag;
- (priv_construct_dispatch_next)(flag, a, p, ::boost::forward<Args>(args)...);
- }
-
- template<class T, class ...Args>
static void priv_construct(container_detail::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args)
- { (priv_construct_dispatch_next)(container_detail::false_type(), a, p, ::boost::forward<Args>(args)...); }
-
- template<class T, class ...Args>
- static void priv_construct_dispatch_next(container_detail::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args)
{ a.construct( p, ::boost::forward<Args>(args)...); }
template<class T, class ...Args>
- static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p, BOOST_FWD_REF(Args) ...args)
+ static void priv_construct(container_detail::false_type, Allocator &, T *p, BOOST_FWD_REF(Args) ...args)
{ ::new((void*)p, boost_container_new_t()) T(::boost::forward<Args>(args)...); }
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
public:
@@ -418,54 +413,38 @@ struct allocator_traits
template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
static void construct(Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
- container_detail::bool_<container_detail::is_std_allocator<Allocator>::value> flag;\
+ static const bool value = ::boost::move_detail::and_ \
+ < container_detail::is_not_std_allocator<Allocator> \
+ , boost::container::container_detail::has_member_function_callable_with_construct \
+ < Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_FWD_T##N > \
+ >::value; \
+ container_detail::bool_<value> flag;\
(priv_construct)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
}\
//
- BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL)
+ 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<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
- static void priv_construct(container_detail::false_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
- {\
- const bool value = boost::container::container_detail::has_member_function_callable_with_construct\
- < Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_FWD_T##N>::value;\
- container_detail::bool_<value> flag;\
- (priv_construct_dispatch_next)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
- }\
- \
- template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
static void priv_construct(container_detail::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
- { (priv_construct_dispatch_next)(container_detail::false_type(), a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
- //
- BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL)
- #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL
-
- /////////////////////////////////
- // priv_construct_dispatch_next
- /////////////////////////////////
- #define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_DISPATCH_NEXT_IMPL(N) \
- template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
- static void priv_construct_dispatch_next(container_detail::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<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
- static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ static void priv_construct(container_detail::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_DISPATCH_NEXT_IMPL)
- #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_DISPATCH_NEXT_IMPL
+ 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<class T>
- static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p, const ::boost::container::default_init_t&)
+ static void priv_construct(container_detail::false_type, Allocator &, T *p, const ::boost::container::default_init_t&)
{ ::new((void*)p) T; }
static bool priv_storage_is_unpropagable(container_detail::true_type, const Allocator &a, pointer p)
diff --git a/boost/container/deque.hpp b/boost/container/deque.hpp
index eb372a430a..bdfecc1212 100644
--- a/boost/container/deque.hpp
+++ b/boost/container/deque.hpp
@@ -835,9 +835,10 @@ class deque : protected deque_base<Allocator>
template <class InIt>
void assign(InIt first, InIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<InIt, size_type>::value
- && container_detail::is_input_iterator<InIt>::value
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_convertible<InIt, size_type>
+ , container_detail::is_not_input_iterator<InIt>
>::type * = 0
#endif
)
@@ -857,9 +858,10 @@ class deque : protected deque_base<Allocator>
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template <class FwdIt>
void assign(FwdIt first, FwdIt last
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<FwdIt, size_type>::value
- && !container_detail::is_input_iterator<FwdIt>::value
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_convertible<FwdIt, size_type>
+ , container_detail::is_input_iterator<FwdIt>
>::type * = 0
)
{
@@ -1509,9 +1511,10 @@ class deque : protected deque_base<Allocator>
template <class InIt>
iterator insert(const_iterator pos, InIt first, InIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<InIt, size_type>::value
- && container_detail::is_input_iterator<InIt>::value
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_convertible<InIt, size_type>
+ , container_detail::is_not_input_iterator<InIt>
>::type * = 0
#endif
)
@@ -1545,9 +1548,10 @@ class deque : protected deque_base<Allocator>
template <class FwdIt>
iterator insert(const_iterator p, FwdIt first, FwdIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<FwdIt, size_type>::value
- && !container_detail::is_input_iterator<FwdIt>::value
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_convertible<FwdIt, size_type>
+ , container_detail::is_input_iterator<FwdIt>
>::type * = 0
#endif
)
diff --git a/boost/container/detail/copy_move_algo.hpp b/boost/container/detail/copy_move_algo.hpp
index 79cbde80a9..23fa730838 100644
--- a/boost/container/detail/copy_move_algo.hpp
+++ b/boost/container/detail/copy_move_algo.hpp
@@ -123,48 +123,49 @@ struct are_elements_contiguous< ::boost::interprocess::offset_ptr<PointedType, D
template <typename I, typename O>
struct are_contiguous_and_same
-{
- static const bool is_same_io =
- is_same< typename remove_const< typename ::boost::container::iterator_traits<I>::value_type >::type
- , typename ::boost::container::iterator_traits<O>::value_type
- >::value;
- static const bool value = is_same_io &&
- are_elements_contiguous<I>::value &&
- are_elements_contiguous<O>::value;
-};
+ : boost::move_detail::and_
+ < are_elements_contiguous<I>
+ , are_elements_contiguous<O>
+ , is_same< typename remove_const< typename ::boost::container::iterator_traits<I>::value_type >::type
+ , typename ::boost::container::iterator_traits<O>::value_type
+ >
+ >
+{};
template <typename I, typename O>
struct is_memtransfer_copy_assignable
-{
- static const bool value = are_contiguous_and_same<I, O>::value &&
- container_detail::is_trivially_copy_assignable< typename ::boost::container::iterator_traits<I>::value_type >::value;
-};
+ : boost::move_detail::and_
+ < are_contiguous_and_same<I, O>
+ , container_detail::is_trivially_copy_assignable< typename ::boost::container::iterator_traits<I>::value_type >
+ >
+{};
template <typename I, typename O>
struct is_memtransfer_copy_constructible
-{
- static const bool value = are_contiguous_and_same<I, O>::value &&
- container_detail::is_trivially_copy_constructible< typename ::boost::container::iterator_traits<I>::value_type >::value;
-};
+ : boost::move_detail::and_
+ < are_contiguous_and_same<I, O>
+ , container_detail::is_trivially_copy_constructible< typename ::boost::container::iterator_traits<I>::value_type >
+ >
+{};
template <typename I, typename O, typename R>
struct enable_if_memtransfer_copy_constructible
- : enable_if_c<container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
+ : enable_if<container_detail::is_memtransfer_copy_constructible<I, O>, R>
{};
template <typename I, typename O, typename R>
struct disable_if_memtransfer_copy_constructible
- : enable_if_c<!container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
+ : disable_if<container_detail::is_memtransfer_copy_constructible<I, O>, R>
{};
template <typename I, typename O, typename R>
struct enable_if_memtransfer_copy_assignable
- : enable_if_c<container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
+ : enable_if<container_detail::is_memtransfer_copy_assignable<I, O>, R>
{};
template <typename I, typename O, typename R>
struct disable_if_memtransfer_copy_assignable
- : enable_if_c<!container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
+ : disable_if<container_detail::is_memtransfer_copy_assignable<I, O>, R>
{};
template
@@ -174,8 +175,10 @@ inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
{
typedef typename boost::container::iterator_traits<I>::value_type value_type;
typename boost::container::iterator_traits<I>::difference_type n = boost::container::iterator_distance(f, l);
- std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
- boost::container::iterator_advance(r, n);
+ if(n){
+ std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
+ boost::container::iterator_advance(r, n);
+ }
return r;
}
@@ -185,8 +188,10 @@ template
F memmove_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{
typedef typename boost::container::iterator_traits<I>::value_type value_type;
- std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
- boost::container::iterator_advance(r, n);
+ if(n){
+ std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
+ boost::container::iterator_advance(r, n);
+ }
return r;
}
@@ -195,9 +200,11 @@ template
typename F> // F models ForwardIterator
I memmove_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{
- typedef typename boost::container::iterator_traits<I>::value_type value_type;
- std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
- boost::container::iterator_advance(f, n);
+ if(n){
+ typedef typename boost::container::iterator_traits<I>::value_type value_type;
+ std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
+ boost::container::iterator_advance(f, n);
+ }
return f;
}
@@ -207,9 +214,11 @@ template
I memmove_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
{
typedef typename boost::container::iterator_traits<I>::value_type value_type;
- std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
- boost::container::iterator_advance(f, n);
- boost::container::iterator_advance(r, n);
+ if(n){
+ std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
+ boost::container::iterator_advance(f, n);
+ boost::container::iterator_advance(r, n);
+ }
return f;
}
diff --git a/boost/container/detail/flat_tree.hpp b/boost/container/detail/flat_tree.hpp
index a94043c6bd..f27421125f 100644
--- a/boost/container/detail/flat_tree.hpp
+++ b/boost/container/detail/flat_tree.hpp
@@ -470,20 +470,22 @@ class flat_tree
template <class BidirIt>
void insert_equal(ordered_range_t, BidirIt first, BidirIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !container_detail::is_input_iterator<BidirIt>::value &&
- !container_detail::is_forward_iterator<BidirIt>::value
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_input_iterator<BidirIt>
+ , container_detail::is_forward_iterator<BidirIt>
>::type * = 0
#endif
)
- { this->priv_insert_ordered_range(false, first, last); }
+ { this->m_data.m_vect.merge(first, last); }
template <class InIt>
void insert_unique(ordered_unique_range_t, InIt first, InIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < container_detail::is_input_iterator<InIt>::value ||
- container_detail::is_forward_iterator<InIt>::value
+ , typename container_detail::enable_if_or
+ < void
+ , container_detail::is_input_iterator<InIt>
+ , container_detail::is_forward_iterator<InIt>
>::type * = 0
#endif
)
@@ -504,7 +506,7 @@ class flat_tree
>::type * = 0
#endif
)
- { this->priv_insert_ordered_range(true, first, last); }
+ { this->m_data.m_vect.merge_unique(first, last, value_compare()); }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
@@ -855,8 +857,8 @@ class flat_tree
}
template <class RanIt>
- RanIt priv_upper_bound(RanIt first, const RanIt last,
- const key_type & key) const
+ RanIt priv_upper_bound
+ (RanIt first, const RanIt last,const key_type & key) const
{
const Compare &key_cmp = this->m_data.get_comp();
KeyOfValue key_extract;
@@ -904,9 +906,9 @@ class flat_tree
//Middle is equal to key
last = first;
last += len;
+ RanIt const first_ret = this->priv_lower_bound(first, middle, key);
return std::pair<RanIt, RanIt>
- ( this->priv_lower_bound(first, middle, key)
- , this->priv_upper_bound(++middle, last, key));
+ ( first_ret, this->priv_upper_bound(++middle, last, key));
}
}
return std::pair<RanIt, RanIt>(first, first);
@@ -939,81 +941,11 @@ class flat_tree
for ( ; first != last; ++first){
//If ordered, then try hint version
//to achieve constant-time complexity per insertion
+ //in some cases
pos = this->insert_equal(pos, *first);
++pos;
}
}
-
- template <class BidirIt>
- void priv_insert_ordered_range(const bool unique_values, BidirIt first, BidirIt last)
- {
- size_type len = static_cast<size_type>(boost::container::iterator_distance(first, last));
- //Prereserve all memory so that iterators are not invalidated
- this->reserve(this->size()+len);
- //Auxiliary data for insertion positions.
- const size_type BurstSize = len;
- const ::boost::movelib::unique_ptr<size_type[]> positions =
- ::boost::movelib::make_unique_definit<size_type[]>(BurstSize);
-
- const const_iterator b(this->cbegin());
- const const_iterator ce(this->cend());
- const_iterator pos(b);
- const value_compare &val_cmp = this->m_data;
- //Loop in burst sizes
- bool back_insert = false;
- while(len && !back_insert){
- const size_type burst = len < BurstSize ? len : BurstSize;
- size_type unique_burst = 0u;
- size_type checked = 0;
- for(; checked != burst; ++checked){
- //Get the insertion position for each key, use iterator_traits<BidirIt>::value_type
- //because it can be different from container::value_type
- //(e.g. conversion between std::pair<T1, T2> -> boost::container::pair<T1, T2>
- const typename boost::container::iterator_traits<BidirIt>::value_type & val = *first;
- pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, ce, KeyOfValue()(val));
- //Check if already present
- if (pos != ce){
- ++first;
- --len;
- positions[checked] = (unique_values && !val_cmp(val, *pos)) ?
- size_type(-1) : (++unique_burst, static_cast<size_type>(pos - b));
- }
- else{ //this element and the remaining should be back inserted
- back_insert = true;
- break;
- }
- }
- if(unique_burst){
- //Insert all in a single step in the precalculated positions
- this->m_data.m_vect.insert_ordered_at(unique_burst, positions.get() + checked, first);
- //Next search position updated, iterator still valid because we've preserved the vector
- pos += unique_burst;
- }
- }
- //The remaining range should be back inserted
- if(unique_values){
- while(len--){
- BidirIt next(first);
- ++next;
- //Use iterator_traits<BidirIt>::value_type
- //because it can be different from container::value_type
- //(e.g. conversion between std::pair<T1, T2> -> boost::container::pair<T1, T2>
- const typename boost::container::iterator_traits<BidirIt>::value_type & val = *first;
- if (next == last || val_cmp(val, *next)){
- const bool room = this->m_data.m_vect.stable_emplace_back(*first);
- (void)room;
- BOOST_ASSERT(room);
- }
- first = next;
- }
- BOOST_ASSERT(first == last);
- }
- else{
- BOOST_ASSERT(size_type(boost::container::iterator_distance(first, last)) == len);
- if(len)
- this->m_data.m_vect.insert(this->m_data.m_vect.cend(), len, first, last);
- }
- }
};
} //namespace container_detail {
diff --git a/boost/container/detail/iterator.hpp b/boost/container/detail/iterator.hpp
index ceb224f3ad..8538acc161 100644
--- a/boost/container/detail/iterator.hpp
+++ b/boost/container/detail/iterator.hpp
@@ -32,6 +32,7 @@ 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;
} //namespace container {
} //namespace boost {
diff --git a/boost/container/detail/iterators.hpp b/boost/container/detail/iterators.hpp
index 1f80d3e122..e8cfcf97a4 100644
--- a/boost/container/detail/iterators.hpp
+++ b/boost/container/detail/iterators.hpp
@@ -651,11 +651,13 @@ namespace container_detail {
template<class T>
struct has_iterator_category
{
+ struct two { char _[2]; };
+
template <typename X>
static char test(int, typename X::iterator_category*);
template <typename X>
- static int test(int, ...);
+ static two test(int, ...);
static const bool value = (1 == sizeof(test<T>(0, 0)));
};
@@ -673,6 +675,12 @@ struct is_input_iterator<T, false>
static const bool value = false;
};
+template<class T>
+struct is_not_input_iterator
+{
+ static const bool value = !is_input_iterator<T>::value;
+};
+
template<class T, bool = has_iterator_category<T>::value >
struct is_forward_iterator
{
@@ -796,7 +804,7 @@ class iterator_from_iiterator
{ return !(l == r); }
reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
- { return (*this->m_iit).get_data(); }
+ { return this->m_iit->get_data(); }
pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
{ return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); }
diff --git a/boost/container/detail/mpl.hpp b/boost/container/detail/mpl.hpp
index 74b618f8c6..e1684ea0b1 100644
--- a/boost/container/detail/mpl.hpp
+++ b/boost/container/detail/mpl.hpp
@@ -23,6 +23,8 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
+#include <boost/move/detail/type_traits.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
#include <cstddef>
@@ -30,110 +32,35 @@ namespace boost {
namespace container {
namespace container_detail {
-template <class T, T val>
-struct integral_constant
-{
- static const T value = val;
- typedef integral_constant<T,val> type;
-};
-
-template< bool C_ >
-struct bool_ : integral_constant<bool, C_>
-{
- static const bool value = C_;
- operator bool() const { return bool_::value; }
-};
-
-template< unsigned V_ >
-struct unsigned_ : integral_constant<unsigned, V_>
-{
- static const unsigned value = V_;
- operator unsigned() const { return unsigned_::value; }
-};
-
-typedef bool_<true> true_;
-typedef bool_<false> false_;
-
-typedef true_ true_type;
-typedef false_ false_type;
-
-typedef char yes_type;
-struct no_type
-{
- char padding[8];
-};
-
-template <bool B, class T = void>
-struct enable_if_c {
- typedef T type;
-};
-
-template <class T>
-struct enable_if_c<false, T> {};
-
-template <class Cond, class T = void>
-struct enable_if : public enable_if_c<Cond::value, T> {};
-
-template <class Cond, class T = void>
-struct disable_if : public enable_if_c<!Cond::value, T> {};
-
-template <bool B, class T = void>
-struct disable_if_c : public enable_if_c<!B, T> {};
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
-
-template <class T, class U>
-struct is_convertible
-{
- static const bool value = __is_convertible_to(T, U);
-};
-
-#else
-
-template <class T, class U>
-class is_convertible
-{
- typedef char true_t;
- class false_t { char dummy[2]; };
- //use any_conversion as first parameter since in MSVC
- //overaligned types can't go through ellipsis
- static false_t dispatch(...);
- static true_t dispatch(U);
- static T &trigger();
- public:
- static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
-};
-
-#endif
-
-template<
- bool C
- , typename T1
- , typename T2
- >
-struct if_c
-{
- typedef T1 type;
-};
-
-template<
- typename T1
- , typename T2
- >
-struct if_c<false,T1,T2>
-{
- typedef T2 type;
-};
-
-template<
- typename T1
- , typename T2
- , typename T3
- >
-struct if_
-{
- typedef typename if_c<0 != T1::value, T2, T3>::type type;
-};
+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 <class Pair>
@@ -150,46 +77,6 @@ struct select1st
{ return x; }
};
-// identity is an extension: it is not part of the standard.
-template <class T>
-struct identity
-{
- typedef T argument_type;
- typedef T result_type;
-
- typedef T type;
- const T& operator()(const T& x) const
- { return x; }
-};
-
-template<std::size_t S>
-struct ls_zeros
-{
- static const std::size_t value = (S & std::size_t(1)) ? 0 : (1u + 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;
-};
-
-template <std::size_t OrigSize, std::size_t RoundTo>
-struct ct_rounded_size
-{
- static const std::size_t value = ((OrigSize-1)/RoundTo+1)*RoundTo;
-};
-
-template <typename T> struct unvoid { typedef T type; };
-template <> struct unvoid<void> { struct type { }; };
-template <> struct unvoid<const void> { struct type { }; };
-
} //namespace container_detail {
} //namespace container {
} //namespace boost {
diff --git a/boost/container/detail/node_alloc_holder.hpp b/boost/container/detail/node_alloc_holder.hpp
index 98c8e62baa..3b632a677d 100644
--- a/boost/container/detail/node_alloc_holder.hpp
+++ b/boost/container/detail/node_alloc_holder.hpp
@@ -173,87 +173,25 @@ struct node_alloc_holder
}
#else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- NodePtr create_node()
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- allocator_traits<NodeAlloc>::construct
- (this->node_alloc(), container_detail::addressof(p->m_data));
- node_deallocator.release();
- typedef typename Node::hook_type hook_type;
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
- return (p);
- }
-
- template<BOOST_MOVE_CLASS1>
- NodePtr create_node(BOOST_MOVE_UREF1)
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- allocator_traits<NodeAlloc>::construct
- (this->node_alloc(), container_detail::addressof(p->m_data)
- , BOOST_MOVE_FWD1);
- node_deallocator.release();
- typedef typename Node::hook_type hook_type;
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
- return (p);
- }
- template<BOOST_MOVE_CLASS2>
- NodePtr create_node(BOOST_MOVE_UREF2)
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- allocator_traits<NodeAlloc>::construct
- (this->node_alloc(), container_detail::addressof(p->m_data)
- , BOOST_MOVE_FWD2);
- node_deallocator.release();
- typedef typename Node::hook_type hook_type;
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
- return (p);
- }
-
- template<BOOST_MOVE_CLASS3>
- NodePtr create_node(BOOST_MOVE_UREF3)
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- allocator_traits<NodeAlloc>::construct
- (this->node_alloc(), container_detail::addressof(p->m_data)
- , BOOST_MOVE_FWD3);
- node_deallocator.release();
- typedef typename Node::hook_type hook_type;
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
- return (p);
- }
-
- template<BOOST_MOVE_CLASS4>
- NodePtr create_node(BOOST_MOVE_UREF4)
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- allocator_traits<NodeAlloc>::construct
- (this->node_alloc(), container_detail::addressof(p->m_data)
- , BOOST_MOVE_FWD4);
- node_deallocator.release();
- typedef typename Node::hook_type hook_type;
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
- return (p);
- }
-
- template<BOOST_MOVE_CLASS5>
- NodePtr create_node(BOOST_MOVE_UREF5)
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- allocator_traits<NodeAlloc>::construct
- (this->node_alloc(), container_detail::addressof(p->m_data)
- , BOOST_MOVE_FWD5);
- node_deallocator.release();
- typedef typename Node::hook_type hook_type;
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
- return (p);
- }
+ #define BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ NodePtr create_node(BOOST_MOVE_UREF##N)\
+ {\
+ NodePtr p = this->allocate_one();\
+ Deallocator node_deallocator(p, this->node_alloc());\
+ allocator_traits<NodeAlloc>::construct\
+ ( this->node_alloc()\
+ , container_detail::addressof(p->m_data)\
+ BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+ node_deallocator.release();\
+ typedef typename Node::hook_type hook_type;\
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;\
+ return (p);\
+ }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL)
+ #undef BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
@@ -375,7 +313,7 @@ struct node_alloc_holder
{}
NodePtr operator()(const Node &other) const
- { return m_holder.create_node(other.get_data()); }
+ { return m_holder.create_node(other.m_data); }
node_alloc_holder &m_holder;
};
@@ -387,7 +325,9 @@ struct node_alloc_holder
{}
NodePtr operator()(Node &other)
- { return m_holder.create_node(::boost::move(other.get_data())); }
+ { //Use m_data instead of get_data to allow moving const key in [multi]map
+ return m_holder.create_node(::boost::move(other.m_data));
+ }
node_alloc_holder &m_holder;
};
@@ -413,12 +353,12 @@ struct node_alloc_holder
template<class ConvertibleToAlloc>
members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const value_compare &c)
: NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
- , m_icont(typename ICont::value_compare(c))
+ , m_icont(typename ICont::key_compare(c))
{}
explicit members_holder(const value_compare &c)
: NodeAlloc()
- , m_icont(typename ICont::value_compare(c))
+ , m_icont(typename ICont::key_compare(c))
{}
//The intrusive container
diff --git a/boost/container/detail/pair.hpp b/boost/container/detail/pair.hpp
index 6d31d3b796..35e8846caa 100644
--- a/boost/container/detail/pair.hpp
+++ b/boost/container/detail/pair.hpp
@@ -33,6 +33,46 @@
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
#include <boost/move/utility_core.hpp>
+/*
+namespace boost{
+
+template<class T1, class T2>
+inline rv< std::pair<T1, T2> > &move(std::pair<T1, T2> &r)
+{
+ return reinterpret_cast< rv< std::pair<T1, T2> > &>(r);
+}
+
+template<class T1, class T2>
+inline rv< std::pair<T1, T2> > &move(rv< std::pair<T1, T2> > &r)
+{
+ return r;
+}
+
+template <class T>
+inline typename ::boost::move_detail::enable_if_and
+ < T &
+ , boost::container::container_detail::is_std_pair<T>
+ , ::boost::move_detail::is_rv<T>
+ >::type
+ forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
+{
+ return const_cast<T&>(x);
+}
+
+template <class T>
+inline typename ::boost::move_detail::enable_if_and
+ < const T &
+ , boost::container::container_detail::is_std_pair<T>
+ , ::boost::move_detail::is_not_rv<T>
+ >::type
+ forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
+{
+ return x;
+}
+
+} //namespace boost {
+*/
+
namespace boost {
namespace container {
namespace container_detail {
@@ -58,6 +98,24 @@ struct is_pair< std::pair<T1, T2> >
static const bool value = true;
};
+template <class T>
+struct is_not_pair
+{
+ static const bool value = !is_pair<T>::value;
+};
+
+template <class T>
+struct is_std_pair
+{
+ static const bool value = false;
+};
+
+template <class T1, class T2>
+struct is_std_pair< std::pair<T1, T2> >
+{
+ static const bool value = true;
+};
+
struct pair_nat;
struct piecewise_construct_t { };
@@ -182,10 +240,11 @@ struct pair
}
template <class D, class S>
- typename ::boost::container::container_detail::enable_if_c
- < !(::boost::container::container_detail::is_same<T1, D>::value &&
- ::boost::container::container_detail::is_same<T2, S>::value)
- , pair &>::type
+ typename ::boost::container::container_detail::disable_if_or
+ < pair &
+ , ::boost::container::container_detail::is_same<T1, D>
+ , ::boost::container::container_detail::is_same<T2, S>
+ >::type
operator=(const pair<D, S>&p)
{
first = p.first;
@@ -194,18 +253,18 @@ struct pair
}
template <class D, class S>
- typename ::boost::container::container_detail::enable_if_c
- < !(::boost::container::container_detail::is_same<T1, D>::value &&
- ::boost::container::container_detail::is_same<T2, S>::value)
- , pair &>::type
+ typename ::boost::container::container_detail::disable_if_or
+ < pair &
+ , ::boost::container::container_detail::is_same<T1, D>
+ , ::boost::container::container_detail::is_same<T2, S>
+ >::type
operator=(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
{
first = ::boost::move(p.first);
second = ::boost::move(p.second);
return *this;
}
-
- //std::pair copy assignment
+//std::pair copy assignment
pair& operator=(const std::pair<T1, T2> &p)
{
first = p.first;
diff --git a/boost/container/detail/std_fwd.hpp b/boost/container/detail/std_fwd.hpp
index a2931c134b..1277df071f 100644
--- a/boost/container/detail/std_fwd.hpp
+++ b/boost/container/detail/std_fwd.hpp
@@ -23,10 +23,12 @@
// Standard predeclarations
//////////////////////////////////////////////////////////////////////////////
-#if defined(__clang__) && defined(_LIBCPP_VERSION)
+#if defined(_LIBCPP_VERSION)
#define BOOST_CONTAINER_CLANG_INLINE_STD_NS
#pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wc++11-extensions"
+ #if defined(__clang__)
+ #pragma GCC diagnostic ignored "-Wc++11-extensions"
+ #endif
#define BOOST_CONTAINER_STD_NS_BEG _LIBCPP_BEGIN_NAMESPACE_STD
#define BOOST_CONTAINER_STD_NS_END _LIBCPP_END_NAMESPACE_STD
#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE_VERSION) //GCC >= 4.6
diff --git a/boost/container/detail/tree.hpp b/boost/container/detail/tree.hpp
index 0f90b5a4e2..c90202973a 100644
--- a/boost/container/detail/tree.hpp
+++ b/boost/container/detail/tree.hpp
@@ -43,6 +43,7 @@
#include <boost/intrusive/sgtree.hpp>
// intrusive/detail
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
+#include <boost/intrusive/detail/tree_value_compare.hpp> //tree_value_compare
// move
#include <boost/move/utility_core.hpp>
// move/detail
@@ -52,57 +53,15 @@
// other
#include <boost/core/no_exceptions_support.hpp>
-namespace boost {
-namespace container {
-namespace container_detail {
-template<class Key, class T, class Compare, class KeyOfValue>
-struct tree_value_compare
- : public Compare
-{
- typedef T value_type;
- typedef Compare key_compare;
- typedef KeyOfValue key_of_value;
- typedef Key key_type;
- explicit tree_value_compare(const key_compare &kcomp)
- : Compare(kcomp)
- {}
-
- tree_value_compare()
- : Compare()
- {}
+#include <boost/container/detail/std_fwd.hpp>
- const key_compare &key_comp() const
- { return static_cast<const key_compare &>(*this); }
-
- key_compare &key_comp()
- { return static_cast<key_compare &>(*this); }
-
- template<class U>
- struct is_key
- {
- static const bool value = is_same<const U, const key_type>::value;
- };
-
- template<class U>
- typename enable_if_c<is_key<U>::value, const key_type &>::type
- key_forward(const U &key) const
- { return key; }
-
- template<class U>
- typename enable_if_c<!is_key<U>::value, const key_type &>::type
- key_forward(const U &key) const
- { return KeyOfValue()(key); }
-
- template<class KeyType, class KeyType2>
- bool operator()(const KeyType &key1, const KeyType2 &key2) const
- { return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
+namespace boost {
+namespace container {
+namespace container_detail {
- template<class KeyType, class KeyType2>
- bool operator()(const KeyType &key1, const KeyType2 &key2)
- { return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
-};
+using boost::intrusive::tree_value_compare;
template<class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
struct intrusive_tree_hook;
@@ -156,7 +115,7 @@ struct tree_internal_data_type
template<class T1, class T2>
struct tree_internal_data_type< std::pair<T1, T2> >
{
- typedef pair<T1, T2> type;
+ typedef pair<typename boost::move_detail::remove_const<T1>::type, T2> type;
};
//The node to be store in the tree
@@ -549,9 +508,10 @@ class tree
tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
const allocator_type& a
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < container_detail::is_input_iterator<InputIterator>::value
- || container_detail::is_same<alloc_version, version_1>::value
+ , typename container_detail::enable_if_or
+ < void
+ , container_detail::is_same<alloc_version, version_1>
+ , container_detail::is_input_iterator<InputIterator>
>::type * = 0
#endif
)
@@ -577,9 +537,10 @@ class tree
tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
const allocator_type& a
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !(container_detail::is_input_iterator<InputIterator>::value
- || container_detail::is_same<alloc_version, version_1>::value)
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_same<alloc_version, version_1>
+ , container_detail::is_input_iterator<InputIterator>
>::type * = 0
#endif
)
@@ -606,10 +567,11 @@ class tree
tree( ordered_range_t, InputIterator first, InputIterator last
, const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < container_detail::is_input_iterator<InputIterator>::value
- || container_detail::is_same<alloc_version, version_1>::value
- >::type * = 0
+ , typename container_detail::enable_if_or
+ < void
+ , container_detail::is_same<alloc_version, version_1>
+ , container_detail::is_input_iterator<InputIterator>
+ >::type * = 0
#endif
)
: AllocHolder(value_compare(comp), a)
@@ -623,10 +585,11 @@ class tree
tree( ordered_range_t, InputIterator first, InputIterator last
, const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !(container_detail::is_input_iterator<InputIterator>::value
- || container_detail::is_same<alloc_version, version_1>::value)
- >::type * = 0
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_same<alloc_version, version_1>
+ , container_detail::is_input_iterator<InputIterator>
+ >::type * = 0
#endif
)
: AllocHolder(value_compare(comp), a)
@@ -663,7 +626,7 @@ class tree
}
else{
this->icont().clone_from
- (x.icont(), typename AllocHolder::move_cloner(*this), Destroyer(this->node_alloc()));
+ (boost::move(x.icont()), typename AllocHolder::move_cloner(*this), Destroyer(this->node_alloc()));
}
}
@@ -730,7 +693,7 @@ class tree
//Now recreate the source tree reusing nodes stored by other_tree
this->icont().clone_from
- (x.icont()
+ (::boost::move(x.icont())
, RecyclingCloner<AllocHolder, true>(*this, other_tree)
, Destroyer(this->node_alloc()));
diff --git a/boost/container/detail/type_traits.hpp b/boost/container/detail/type_traits.hpp
index 1ae2426863..e02709ac6e 100644
--- a/boost/container/detail/type_traits.hpp
+++ b/boost/container/detail/type_traits.hpp
@@ -31,6 +31,7 @@ namespace container {
namespace container_detail {
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;
diff --git a/boost/container/list.hpp b/boost/container/list.hpp
index 54da6df518..5135eaecee 100644
--- a/boost/container/list.hpp
+++ b/boost/container/list.hpp
@@ -417,9 +417,7 @@ class list
template <class InpIt>
void assign(InpIt first, InpIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<InpIt, size_type>::value
- >::type * = 0
+ , typename container_detail::disable_if_convertible<InpIt, size_type>::type * = 0
#endif
)
{
diff --git a/boost/container/node_allocator.hpp b/boost/container/node_allocator.hpp
index afd6f98a8d..c3d809078f 100644
--- a/boost/container/node_allocator.hpp
+++ b/boost/container/node_allocator.hpp
@@ -74,9 +74,9 @@ class node_allocator
typedef T * pointer;
typedef const T * const_pointer;
typedef typename ::boost::container::
- container_detail::unvoid<T>::type & reference;
- typedef const typename ::boost::container::
- container_detail::unvoid<T>::type & const_reference;
+ container_detail::unvoid_ref<T>::type reference;
+ typedef typename ::boost::container::
+ container_detail::unvoid_ref<const T>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
diff --git a/boost/container/scoped_allocator.hpp b/boost/container/scoped_allocator.hpp
index 55514aae21..0724f948fb 100644
--- a/boost/container/scoped_allocator.hpp
+++ b/boost/container/scoped_allocator.hpp
@@ -1129,7 +1129,7 @@ class scoped_allocator_adaptor
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
void
#else
- typename container_detail::enable_if_c<!container_detail::is_pair<T>::value, void>::type
+ typename container_detail::enable_if<container_detail::is_not_pair<T> >::type
#endif
construct(T* p, BOOST_FWD_REF(Args)...args)
{
@@ -1146,7 +1146,7 @@ class scoped_allocator_adaptor
//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 >\
- typename container_detail::enable_if_c<!container_detail::is_pair<T>::value, void>::type\
+ typename container_detail::enable_if< container_detail::is_not_pair<T> >::type\
construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\
{\
container_detail::dispatch_uses_allocator\
@@ -1188,12 +1188,12 @@ class scoped_allocator_adaptor
template <class T1, class T2, class U, class V>
void construct( std::pair<T1, T2>* p
, BOOST_RV_REF_BEG std::pair<U, V> BOOST_RV_REF_END x)
- { this->construct_pair(p, x); }
+ { this->construct_pair(p, ::boost::move(x)); }
template <class T1, class T2, class U, class V>
void construct( container_detail::pair<T1, T2>* p
, BOOST_RV_REF_BEG container_detail::pair<U, V> BOOST_RV_REF_END x)
- { this->construct_pair(p, x); }
+ { this->construct_pair(p, ::boost::move(x)); }
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
@@ -1246,6 +1246,39 @@ class scoped_allocator_adaptor
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
+template<bool ZeroInner>
+struct scoped_allocator_operator_equal
+{
+ //Optimize equal outer allocator types with
+ //allocator_traits::equal which uses is_always_equal
+ template<class IA>
+ static bool equal_outer(const IA &l, const IA &r)
+ { return allocator_traits<IA>::equal(l, r); }
+
+ //Otherwise compare it normally
+ template<class IA1, class IA2>
+ static bool equal_outer(const IA1 &l, const IA2 &r)
+ { return l == r; }
+
+ //Otherwise compare it normally
+ template<class IA>
+ static bool equal_inner(const IA &l, const IA &r)
+ { return allocator_traits<IA>::equal(l, r); }
+};
+
+template<>
+struct scoped_allocator_operator_equal<true>
+ : scoped_allocator_operator_equal<false>
+{
+ //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<class IA1, class IA2>
+ static bool equal_inner(const IA1 &, const IA2 &)
+ { return true; }
+};
+
+
template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
inline bool operator==(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b)
@@ -1255,14 +1288,9 @@ inline bool operator==(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_S
#else
const bool has_zero_inner = boost::container::container_detail::is_same<P0, void>::value;
#endif
- typedef typename scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>
- ::outer_allocator_type outer_allocator_type;
- typedef typename scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>
- ::inner_allocator_type inner_allocator_type;
-
- return allocator_traits<outer_allocator_type>::equal(a.outer_allocator(), b.outer_allocator())
- && (has_zero_inner ||
- allocator_traits<inner_allocator_type>::equal(a.inner_allocator(), b.inner_allocator()));
+ typedef scoped_allocator_operator_equal<has_zero_inner> equal_t;
+ return equal_t::equal_outer(a.outer_allocator(), b.outer_allocator()) &&
+ equal_t::equal_inner(a.inner_allocator(), b.inner_allocator());
}
template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
diff --git a/boost/container/slist.hpp b/boost/container/slist.hpp
index b0901ef086..2b53df132f 100644
--- a/boost/container/slist.hpp
+++ b/boost/container/slist.hpp
@@ -442,9 +442,7 @@ class slist
template <class InpIt>
void assign(InpIt first, InpIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<InpIt, size_type>::value
- >::type * = 0
+ , typename container_detail::disable_if_convertible<InpIt, size_type>::type * = 0
#endif
)
{
diff --git a/boost/container/small_vector.hpp b/boost/container/small_vector.hpp
index 7ef0c238a3..a9f7522205 100644
--- a/boost/container/small_vector.hpp
+++ b/boost/container/small_vector.hpp
@@ -60,7 +60,7 @@ class small_vector_base;
//! for documentation purposes.
//!
//! This allocator inherits from a standard-conforming allocator
-//! and forwards member functiond to the standard allocator except
+//! and forwards member functions to the standard allocator except
//! when internal storage is being used as memory source.
//!
//! This allocator is a "partially_propagable" allocator and
@@ -68,7 +68,7 @@ class small_vector_base;
//!
//! A partially propagable allocator means that not all storage
//! allocatod by an instance of `small_vector_allocator` can be
-//! deallocated by another instance of this type, even is both
+//! deallocated by another instance of this type, even if both
//! instances compare equal or an instance is propagated to another
//! one using the copy/move constructor or assignment. The storage that
//! can never be propagated is identified by `storage_is_unpropagable(p)`.
@@ -311,8 +311,12 @@ class small_vector_base
: public vector<T, small_vector_allocator<SecondaryAllocator> >
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+ public:
+ //Make it public as it will be inherited by small_vector and container
+ //must have this public member
typedef typename allocator_traits<SecondaryAllocator>::pointer pointer;
+ private:
BOOST_COPYABLE_AND_MOVABLE(small_vector_base)
friend class small_vector_allocator<SecondaryAllocator>;
@@ -428,8 +432,8 @@ struct small_vector_storage_definer
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
-//! small_vector a vector-like container optimized for the case when it contains few elements.
-//! It contains some preallocated elements in-place, which allows it to avoid the use of dynamic storage allocation
+//! small_vector is a vector-like container optimized for the case when it contains few elements.
+//! It contains some preallocated elements in-place, which can avoid the use of dynamic storage allocation
//! when the actual number of elements is below that preallocated threshold.
//!
//! `small_vector<T, N, Allocator>` is convertible to `small_vector_base<T, Allocator>` that is independent
diff --git a/boost/container/stable_vector.hpp b/boost/container/stable_vector.hpp
index 76c9e9f07b..6aca69bde6 100644
--- a/boost/container/stable_vector.hpp
+++ b/boost/container/stable_vector.hpp
@@ -349,7 +349,7 @@ class stable_vector_iterator
return tmp;
}
- friend difference_type operator-(const stable_vector_iterator& left, const stable_vector_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW
+ friend difference_type operator-(const stable_vector_iterator &left, const stable_vector_iterator &right) BOOST_NOEXCEPT_OR_NOTHROW
{ return left.m_pn->up - right.m_pn->up; }
//Comparison operators
@@ -493,7 +493,7 @@ class stable_vector
, false> iterator_impl;
typedef stable_vector_iterator
< typename allocator_traits<Allocator>::pointer
- , false> const_iterator_impl;
+ , true> const_iterator_impl;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -687,7 +687,7 @@ class stable_vector
: internal_data(l), index(l)
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
- insert(cend(), il.begin(), il.end())
+ insert(cend(), il.begin(), il.end());
STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -804,6 +804,7 @@ class stable_vector
//Resources can be transferred if both allocators are
//going to be equal after this function (either propagated or already equal)
if(propagate_alloc || allocators_equal){
+ STABLE_VECTOR_CHECK_INVARIANT
//Destroy objects but retain memory in case x reuses it in the future
this->clear();
//Move allocator if needed
@@ -850,13 +851,12 @@ class stable_vector
//!
//! <b>Complexity</b>: Linear to n.
template<typename InputIterator>
- void assign(InputIterator first,InputIterator last
- #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<InputIterator, size_type>::value
- >::type * = 0
- #endif
- )
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ typename container_detail::disable_if_convertible<InputIterator, size_type>::type
+ #else
+ void
+ #endif
+ assign(InputIterator first,InputIterator last)
{
STABLE_VECTOR_CHECK_INVARIANT;
iterator first1 = this->begin();
@@ -1112,13 +1112,12 @@ class stable_vector
{
const size_type index_size = this->index.size();
BOOST_ASSERT(!index_size || index_size >= ExtraPointers);
- const size_type bucket_extra_capacity = this->index.capacity()- index_size;
const size_type node_extra_capacity = this->internal_data.pool_size;
- const size_type extra_capacity = (bucket_extra_capacity < node_extra_capacity)
- ? bucket_extra_capacity : node_extra_capacity;
+ //Pool count must be less than index capacity, as index is a vector
+ BOOST_ASSERT(node_extra_capacity <= (this->index.capacity()- index_size));
const size_type index_offset =
- (ExtraPointers + extra_capacity) & (size_type(0u) - size_type(index_size != 0));
- return index_size - index_offset;
+ (node_extra_capacity - ExtraPointers) & (size_type(0u) - size_type(index_size != 0));
+ return index_size + index_offset;
}
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -1294,11 +1293,10 @@ class stable_vector
return (this->index.empty()) ? this->cend() : iterator(node_ptr_traits::static_cast_from(this->index[n]));
}
- //! <b>Requires</b>: size() >= n.
+ //! <b>Requires</b>: begin() <= p <= end().
//!
- //! <b>Effects</b>: Returns an iterator to the nth element
- //! from the beginning of the container. Returns end()
- //! if n == size().
+ //! <b>Effects</b>: Returns the index of the element pointed by p
+ //! and size() if p == end().
//!
//! <b>Throws</b>: Nothing.
//!
@@ -1517,14 +1515,16 @@ class stable_vector
//!
//! <b>Complexity</b>: Linear to distance [first, last).
template <class InputIterator>
- iterator insert(const_iterator p, InputIterator first, InputIterator last
- #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<InputIterator, size_type>::value
- && container_detail::is_input_iterator<InputIterator>::value
- >::type * = 0
- #endif
- )
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ typename container_detail::disable_if_or
+ < iterator
+ , container_detail::is_convertible<InputIterator, size_type>
+ , container_detail::is_not_input_iterator<InputIterator>
+ >::type
+ #else
+ iterator
+ #endif
+ insert(const_iterator p, InputIterator first, InputIterator last)
{
STABLE_VECTOR_CHECK_INVARIANT;
const size_type pos_n = p - this->cbegin();
@@ -1536,12 +1536,12 @@ class stable_vector
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template <class FwdIt>
- iterator insert(const_iterator p, FwdIt first, FwdIt last
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<FwdIt, size_type>::value
- && !container_detail::is_input_iterator<FwdIt>::value
- >::type * = 0
- )
+ typename container_detail::disable_if_or
+ < iterator
+ , container_detail::is_convertible<FwdIt, size_type>
+ , container_detail::is_input_iterator<FwdIt>
+ >::type
+ insert(const_iterator p, FwdIt first, FwdIt last)
{
const size_type num_new = static_cast<size_type>(boost::container::iterator_distance(first, last));
const size_type idx = static_cast<size_type>(p - this->cbegin());
@@ -1786,7 +1786,7 @@ class stable_vector
template <class U>
void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x)
{
- if(this->priv_capacity_bigger_than_size()){
+ if(BOOST_LIKELY(this->priv_capacity_bigger_than_size())){
//Enough memory in the pool and in the index
const node_ptr p = this->priv_get_from_pool();
BOOST_ASSERT(!!p);
@@ -1961,8 +1961,19 @@ class stable_vector
{
index_type & index_ref = const_cast<index_type&>(this->index);
- if(index.empty())
+ const size_type index_size = this->index.size();
+ if(!index_size)
return !this->capacity() && !this->size();
+
+ if(index_size < ExtraPointers)
+ return false;
+
+ const size_type bucket_extra_capacity = this->index.capacity()- index_size;
+ const size_type node_extra_capacity = this->internal_data.pool_size;
+ if(bucket_extra_capacity < node_extra_capacity){
+ return false;
+ }
+
if(this->priv_get_end_node() != *(index.end() - ExtraPointers)){
return false;
}
diff --git a/boost/container/string.hpp b/boost/container/string.hpp
index e5ec287cf8..7399223904 100644
--- a/boost/container/string.hpp
+++ b/boost/container/string.hpp
@@ -111,8 +111,7 @@ class basic_string_base
~basic_string_base()
{
if(!this->is_short()){
- this->deallocate_block();
- this->is_short(true);
+ this->deallocate(this->priv_long_addr(), this->priv_long_storage());
}
}
@@ -131,15 +130,14 @@ class basic_string_base
long_t(const long_t &other)
{
- this->is_short = other.is_short;
+ this->is_short = false;
length = other.length;
storage = other.storage;
start = other.start;
}
- long_t &operator =(const long_t &other)
+ long_t &operator= (const long_t &other)
{
- this->is_short = other.is_short;
length = other.length;
storage = other.storage;
start = other.start;
@@ -165,8 +163,7 @@ class basic_string_base
static const size_type MinInternalBufferChars = 8;
static const size_type AlignmentOfValueType =
alignment_of<value_type>::value;
- static const size_type ShortDataOffset =
- container_detail::ct_rounded_size<sizeof(short_header), AlignmentOfValueType>::value;
+ static const size_type ShortDataOffset = ((sizeof(short_header)-1)/AlignmentOfValueType+1)*AlignmentOfValueType;
static const size_type ZeroCostInternalBufferChars =
(sizeof(long_t) - ShortDataOffset)/sizeof(value_type);
static const size_type UnalignedFinalInternalBufferChars =
@@ -421,21 +418,19 @@ class basic_string_base
}
else{
short_t short_backup(this->members_.m_repr.short_repr());
- long_t long_backup (other.members_.m_repr.long_repr());
+ this->members_.m_repr.short_repr().~short_t();
+ ::new(&this->members_.m_repr.long_repr()) long_t(other.members_.m_repr.long_repr());
other.members_.m_repr.long_repr().~long_t();
- ::new(&this->members_.m_repr.long_repr()) long_t;
- this->members_.m_repr.long_repr() = long_backup;
- other.members_.m_repr.short_repr() = short_backup;
+ ::new(&other.members_.m_repr.short_repr()) short_t(short_backup);
}
}
else{
if(other.is_short()){
short_t short_backup(other.members_.m_repr.short_repr());
- long_t long_backup (this->members_.m_repr.long_repr());
+ other.members_.m_repr.short_repr().~short_t();
+ ::new(&other.members_.m_repr.long_repr()) long_t(this->members_.m_repr.long_repr());
this->members_.m_repr.long_repr().~long_t();
- ::new(&other.members_.m_repr.long_repr()) long_t;
- other.members_.m_repr.long_repr() = long_backup;
- this->members_.m_repr.short_repr() = short_backup;
+ ::new(&this->members_.m_repr.short_repr()) short_t(short_backup);
}
else{
boost::adl_move_swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
@@ -1289,9 +1284,7 @@ class basic_string
template <class InputIter>
basic_string& assign(InputIter first, InputIter last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<InputIter, size_type>::value
- >::type * = 0
+ , typename container_detail::disable_if_convertible<InputIter, size_type>::type * = 0
#endif
)
{
@@ -1438,9 +1431,10 @@ class basic_string
template <class InputIter>
iterator insert(const_iterator p, InputIter first, InputIter last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<InputIter, size_type>::value
- && container_detail::is_input_iterator<InputIter>::value
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_convertible<InputIter, size_type>
+ , container_detail::is_not_input_iterator<InputIter>
>::type * = 0
#endif
)
@@ -1455,9 +1449,10 @@ class basic_string
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template <class ForwardIter>
iterator insert(const_iterator p, ForwardIter first, ForwardIter last
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<ForwardIter, size_type>::value
- && !container_detail::is_input_iterator<ForwardIter>::value
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_convertible<ForwardIter, size_type>
+ , container_detail::is_input_iterator<ForwardIter>
>::type * = 0
)
{
@@ -1829,9 +1824,10 @@ class basic_string
template <class InputIter>
basic_string& replace(const_iterator i1, const_iterator i2, InputIter j1, InputIter j2
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<InputIter, size_type>::value
- && container_detail::is_input_iterator<InputIter>::value
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_convertible<InputIter, size_type>
+ , container_detail::is_input_iterator<InputIter>
>::type * = 0
#endif
)
@@ -1850,9 +1846,10 @@ class basic_string
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template <class ForwardIter>
basic_string& replace(const_iterator i1, const_iterator i2, ForwardIter j1, ForwardIter j2
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<ForwardIter, size_type>::value
- && !container_detail::is_input_iterator<ForwardIter>::value
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_convertible<ForwardIter, size_type>
+ , container_detail::is_not_input_iterator<ForwardIter>
>::type * = 0
)
{
diff --git a/boost/container/vector.hpp b/boost/container/vector.hpp
index 1b6d963934..1cf44c8e27 100644
--- a/boost/container/vector.hpp
+++ b/boost/container/vector.hpp
@@ -57,6 +57,7 @@
// other
#include <boost/core/no_exceptions_support.hpp>
#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
//std
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -179,6 +180,70 @@ class vec_iterator
{ return l.m_ptr >= r.m_ptr; }
};
+template<class BiDirPosConstIt, class BiDirValueIt>
+struct vector_insert_ordered_cursor
+{
+ typedef typename iterator_traits<BiDirPosConstIt>::value_type size_type;
+ typedef typename iterator_traits<BiDirValueIt>::reference reference;
+
+ 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;
+ }
+ }
+
+ size_type get_pos() const
+ { return *last_position_it; }
+
+ reference get_val()
+ { return *last_value_it; }
+
+ BiDirPosConstIt last_position_it;
+ BiDirValueIt last_value_it;
+};
+
+template<class T, class SizeType, class BiDirValueIt, class Comp>
+struct vector_merge_cursor
+{
+ typedef SizeType size_type;
+ typedef typename iterator_traits<BiDirValueIt>::reference reference;
+
+ vector_merge_cursor(T *pbeg, T *plast, BiDirValueIt valueit, Comp cmp)
+ : m_pbeg(pbeg), m_pcur(--plast), m_valueit(valueit), m_cmp(cmp)
+ {}
+
+ void operator --()
+ {
+ --m_valueit;
+ const T &t = *m_valueit;
+ while((m_pcur + 1) != m_pbeg){
+ if(!m_cmp(t, *m_pcur)){
+ break;
+ }
+ --m_pcur;
+ }
+ }
+
+ size_type get_pos() const
+ { return static_cast<size_type>((m_pcur + 1) - m_pbeg); }
+
+ reference get_val()
+ { return *m_valueit; }
+
+ T *const m_pbeg;
+ T *m_pcur;
+ BiDirValueIt m_valueit;
+ Comp m_cmp;
+};
+
} //namespace container_detail {
template<class Pointer, bool IsConst>
@@ -640,6 +705,13 @@ class vector
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+ struct value_less
+ {
+ typedef typename boost::container::allocator_traits<Allocator>::value_type value_type;
+ bool operator()(const value_type &a, const value_type &b) const
+ { return a < b; }
+ };
+
typedef typename container_detail::version<Allocator>::type alloc_version;
typedef boost::container::container_detail::vector_alloc_holder<Allocator> alloc_holder_t;
alloc_holder_t m_holder;
@@ -1043,10 +1115,11 @@ class vector
//!
//! <b>Note</b>: Non-standard extension to support static_vector
template<class OtherAllocator>
- typename container_detail::enable_if_c
- < container_detail::is_version<OtherAllocator, 0>::value &&
- !container_detail::is_same<OtherAllocator, allocator_type>::value
- , vector& >::type
+ typename container_detail::enable_if_and
+ < vector&
+ , container_detail::is_version<OtherAllocator, 0>
+ , container_detail::is_different<OtherAllocator, allocator_type>
+ >::type
operator=(BOOST_RV_REF_BEG vector<value_type, OtherAllocator> BOOST_RV_REF_END x)
{
this->priv_move_assign(boost::move(x));
@@ -1064,10 +1137,11 @@ class vector
//!
//! <b>Note</b>: Non-standard extension to support static_vector
template<class OtherAllocator>
- typename container_detail::enable_if_c
- < container_detail::is_version<OtherAllocator, 0>::value &&
- !container_detail::is_same<OtherAllocator, allocator_type>::value
- , vector& >::type
+ typename container_detail::enable_if_and
+ < vector&
+ , container_detail::is_version<OtherAllocator, 0>
+ , container_detail::is_different<OtherAllocator, allocator_type>
+ >::type
operator=(const vector<value_type, OtherAllocator> &x)
{
this->priv_copy_assign(x);
@@ -1084,11 +1158,15 @@ class vector
//! <b>Complexity</b>: Linear to n.
template <class InIt>
void assign(InIt first, InIt last
- BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename container_detail::enable_if_c
- < !container_detail::is_convertible<InIt BOOST_MOVE_I size_type>::value &&
- ( container_detail::is_input_iterator<InIt>::value ||
- container_detail::is_same<alloc_version BOOST_MOVE_I version_0>::value )
- >::type * = 0) )
+ BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename container_detail::disable_if_or
+ < void
+ BOOST_MOVE_I container_detail::is_convertible<InIt BOOST_MOVE_I size_type>
+ BOOST_MOVE_I container_detail::and_
+ < container_detail::is_different<alloc_version BOOST_MOVE_I version_0>
+ BOOST_MOVE_I container_detail::is_not_input_iterator<InIt>
+ >
+ >::type * = 0)
+ )
{
//Overwrite all elements we can from [first, last)
iterator cur = this->begin();
@@ -1129,10 +1207,11 @@ class vector
//! <b>Complexity</b>: Linear to n.
template <class FwdIt>
void assign(FwdIt first, FwdIt last
- BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename container_detail::enable_if_c
- < !container_detail::is_convertible<FwdIt BOOST_MOVE_I size_type>::value &&
- ( !container_detail::is_input_iterator<FwdIt>::value &&
- !container_detail::is_same<alloc_version BOOST_MOVE_I version_0>::value )
+ BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename container_detail::disable_if_or
+ < void
+ BOOST_MOVE_I container_detail::is_same<alloc_version BOOST_MOVE_I version_0>
+ BOOST_MOVE_I container_detail::is_convertible<FwdIt BOOST_MOVE_I size_type>
+ BOOST_MOVE_I container_detail::is_input_iterator<FwdIt>
>::type * = 0)
)
{
@@ -1791,10 +1870,13 @@ class vector
//! <b>Complexity</b>: Linear to boost::container::iterator_distance [first, last).
template <class InIt>
iterator insert(const_iterator pos, InIt first, InIt last
- BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename container_detail::enable_if_c
- < !container_detail::is_convertible<InIt BOOST_MOVE_I size_type>::value
- && container_detail::is_input_iterator<InIt>::value
- >::type * = 0)
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_convertible<InIt, size_type>
+ , container_detail::is_not_input_iterator<InIt>
+ >::type * = 0
+ #endif
)
{
const size_type n_pos = pos - this->cbegin();
@@ -1809,9 +1891,10 @@ class vector
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template <class FwdIt>
iterator insert(const_iterator pos, FwdIt first, FwdIt last
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<FwdIt, size_type>::value
- && !container_detail::is_input_iterator<FwdIt>::value
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_convertible<FwdIt, size_type>
+ , container_detail::is_input_iterator<FwdIt>
>::type * = 0
)
{
@@ -1902,7 +1985,7 @@ class vector
T* const first_ptr = container_detail::to_raw_pointer(vector_iterator_get_ptr(first));
T* const last_ptr = container_detail::to_raw_pointer(vector_iterator_get_ptr(last));
T* const ptr = container_detail::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr));
- this->priv_destroy_last_n(old_end_ptr - ptr, last_ptr == old_end_ptr);
+ this->priv_destroy_last_n(old_end_ptr - ptr);
}
return iterator(vector_iterator_get_ptr(first));
}
@@ -1931,9 +2014,11 @@ class vector
//! <b>Note</b>: Non-standard extension to support static_vector
template<class OtherAllocator>
void swap(vector<T, OtherAllocator> & x
- , typename container_detail::enable_if_c
- < container_detail::is_version<OtherAllocator, 0>::value &&
- !container_detail::is_same<OtherAllocator, allocator_type>::value >::type * = 0
+ , typename container_detail::enable_if_and
+ < void
+ , container_detail::is_version<OtherAllocator, 0>
+ , container_detail::is_different<OtherAllocator, allocator_type>
+ >::type * = 0
)
{ this->m_holder.deep_swap(x.m_holder); }
@@ -2017,12 +2102,36 @@ class vector
template<class BiDirPosConstIt, class BiDirValueIt>
void insert_ordered_at(const size_type element_count, BiDirPosConstIt last_position_it, BiDirValueIt last_value_it)
{
+ typedef container_detail::vector_insert_ordered_cursor<BiDirPosConstIt, BiDirValueIt> inserter_t;
+ return this->priv_insert_ordered_at(element_count, inserter_t(last_position_it, last_value_it));
+ }
+
+ template<class BidirIt>
+ void merge(BidirIt first, BidirIt last)
+ { this->merge(first, last, value_less()); }
+
+ template<class BidirIt, class Compare>
+ void merge(BidirIt first, BidirIt last, Compare comp)
+ { this->priv_merge(container_detail::false_type(), first, last, comp); }
+
+ template<class BidirIt>
+ void merge_unique(BidirIt first, BidirIt last)
+ { this->priv_merge(container_detail::true_type(), first, last, value_less()); }
+
+ template<class BidirIt, class Compare>
+ void merge_unique(BidirIt first, BidirIt last, Compare comp)
+ { this->priv_merge(container_detail::true_type(), first, last, comp); }
+
+ private:
+ template<class PositionValue>
+ 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 = container_detail::to_raw_pointer(this->m_holder.start());
size_type insertions_left = element_count;
- size_type next_pos = old_size_pos;
- size_type hole_size = 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.
@@ -2031,52 +2140,197 @@ class vector
//Loop for each insertion backwards, first moving the elements after the insertion point,
//then inserting the element.
while(insertions_left){
- size_type pos = static_cast<size_type>(*(--last_position_it));
- while(pos == size_type(-1)){
- --last_value_it;
- pos = static_cast<size_type>(*(--last_position_it));
- }
-
- BOOST_ASSERT(pos != size_type(-1) && pos <= old_size_pos);
+ --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 != next_pos)
- ? priv_insert_ordered_at_shift_range(pos, next_pos, this->size(), insertions_left)
- : hole_size
+ 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 > 0){
+ 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(next_pos - pos);
+ 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, *(--last_value_it));
- --new_hole_size;
- if(new_hole_size == 0){
+ 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{
- //The hole was reduced by the new insertion by one
- past_hole_values_destroyer.increment_size_backwards(size_type(1u));
- }
}
else{
- if(hole_size){
+ 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] = *(--last_value_it);
+ begin_ptr[pos + insertions_left - 1] = position_value.get_val();
}
--insertions_left;
- hole_size = new_hole_size;
- next_pos = pos;
+ old_hole_size = new_hole_size;
+ prev_pos = pos;
}
}
- private:
+ template<class UniqueBool, class BidirIt, class Compare>
+ void priv_merge(UniqueBool, BidirIt first, BidirIt last, Compare comp)
+ {
+ size_type const n = static_cast<size_type>(boost::container::iterator_distance(first, last));
+ if(BOOST_LIKELY(n)){
+ size_type const s = this->size();
+ if(BOOST_LIKELY(s)){
+ size_type const c = this->capacity();
+ size_type const free_c = (c - s);
+ //Use a new buffer if current one is too small for new elements,
+ //or there is no room for position indexes
+ bool new_buffer = false;
+ if(free_c < n){
+ new_buffer = true;
+ }
+ else if(!UniqueBool::value && free_c >= n){
+ typedef container_detail::vector_merge_cursor<T, size_type, BidirIt, Compare> inserter_t;
+ T* const pbeg = container_detail::to_raw_pointer(m_holder.start());
+ return this->priv_insert_ordered_at(n, inserter_t(pbeg, pbeg + s, last, comp));
+ }
+ else if(UniqueBool::value){ //Query for room to store n + 1 indexes (+1 to guarantee potential alignment overhead).
+ //No need to destroy them as they are integral types, which simplifies things a lot.
+ std::size_t const sz_vlt = sizeof(value_type);
+ std::size_t const sz_szt = sizeof(size_type);
+ new_buffer = (c-s-n)*sz_vlt/sz_szt < (n+1);
+ }
+
+ if(new_buffer){
+ size_type const new_size = s + n;
+ size_type new_cap = new_size;
+ pointer p = pointer();
+ p = this->m_holder.allocation_command(allocate_new, new_size, new_cap, p);
+ this->priv_merge_in_new_buffer(UniqueBool(), first, n, comp, p, new_cap);
+ }
+ else{
+ //Use trailing memory to store position offsets
+ uintptr_t const szt_align_mask = container_detail::alignment_of<size_type>::value - 1;
+ boost::uintptr_t const addr = boost::uintptr_t(container_detail::to_raw_pointer(m_holder.start()) + s + n);
+ //Align memory before casting to address
+ size_type *const paddr = reinterpret_cast<size_type *>((addr + szt_align_mask) & ~szt_align_mask);
+ this->priv_insert_ordered_range(UniqueBool(), n, first, last, paddr, comp);
+ }
+ }
+ else{
+ this->insert(this->cend(), n, first, last);
+ }
+ }
+ }
+
+ template <class UniqueBool, class BidirIt, class Compare>
+ void priv_insert_ordered_range
+ (UniqueBool, size_type const n, BidirIt first, BidirIt const last, size_type positions[], Compare comp)
+ {
+ //Linear: at most N + M -1 comparisons
+ //Log: MlogN
+ //Average
+ //Linear: N + M - 2
+ //Log: MlogN
+ //N+M - 2
+ //N
+ //(N+M)/2 < MlogN
+ //(N/M+1)/2 <= logN
+ //bool const linear = !s || !n || (s <= n) || ((s+n)/n/2 < logN);
+ size_type const s = this->size();
+ size_type remaining = n;
+ T* const pbeg = container_detail::to_raw_pointer(m_holder.start());
+ T* const pend = pbeg + s;
+ T* pcur = pbeg;
+ size_type *position = positions;
+ size_type added_in_middle = 0;
+ if(first != last && pcur != pend){
+ while(1){
+ //maintain stability moving external values only if they are strictly less
+ if(comp(*first, *pcur)) {
+ *position = static_cast<size_type>(pcur - pbeg);
+ BOOST_ASSERT((position == positions) || (*(position-1) == size_type(-1)) || (*(position-1) <= *position));
+ ++position;
+ ++added_in_middle;
+ --remaining;
+ if(++first == last) break;
+ }
+ else if(UniqueBool::value && !comp(*pcur, *first)){
+ *position = size_type(-1);
+ ++position;
+ --remaining;
+ if(++first == last) break;
+ }
+ else{
+ if(++pcur == pend) break;
+ }
+ }
+ }
+ this->insert_ordered_at(added_in_middle, position, first);
+ this->insert(this->cend(), remaining, first, last);
+ }
+
+ template<class UniqueBool, class FwdIt, class Compare>
+ void priv_merge_in_new_buffer
+ (UniqueBool, FwdIt first, size_type n, Compare comp, pointer new_storage, size_type const new_cap)
+ {
+ 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 = container_detail::to_raw_pointer(m_holder.start());
+ size_type const old_size = this->size();
+ T* const pend = pbeg + old_size;
+ T* d_first = container_detail::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, ::boost::move(*first) );
+ new_values_destroyer.increment_size(1u);
+ ++first;
+ --n;
+ ++d_first;
+ }
+ else if(UniqueBool::value && !comp(*pbeg, *first)){
+ ++first;
+ --n;
+ --added;
+ }
+ 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, container_detail::to_raw_pointer(old_p), old_size);
+ a.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();
+ }
bool room_enough() const
{ return this->m_holder.m_size < this->m_holder.capacity(); }
@@ -2113,9 +2367,11 @@ class vector
template<class OtherAllocator>
void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
- , typename container_detail::enable_if_c
- < !container_detail::is_version<OtherAllocator, 0>::value &&
- container_detail::is_same<OtherAllocator, allocator_type>::value>::type * = 0)
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_version<OtherAllocator, 0>
+ , container_detail::is_different<OtherAllocator, allocator_type>
+ >::type * = 0)
{
//for move constructor, no aliasing (&x != this) is assummed.
BOOST_ASSERT(this != &x);
@@ -2167,10 +2423,12 @@ class vector
}
template<class OtherAllocator>
- void priv_copy_assign(const vector<T, OtherAllocator> &x
- , typename container_detail::enable_if_c
- < !container_detail::is_version<OtherAllocator, 0>::value &&
- container_detail::is_same<OtherAllocator, allocator_type>::value >::type * = 0)
+ typename container_detail::disable_if_or
+ < void
+ , container_detail::is_version<OtherAllocator, 0>
+ , container_detail::is_different<OtherAllocator, allocator_type>
+ >::type
+ priv_copy_assign(const vector<T, OtherAllocator> &x)
{
allocator_type &this_alloc = this->m_holder.alloc();
const allocator_type &x_alloc = x.m_holder.alloc();
@@ -2274,16 +2532,7 @@ class vector
}
}
- void priv_destroy_last() BOOST_NOEXCEPT_OR_NOTHROW
- {
- if(!value_traits::trivial_dctr){
- value_type* const p = this->back_raw() - 1;
- allocator_traits_type::destroy(this->get_stored_allocator(), p);
- }
- --this->m_holder.m_size;
- }
-
- void priv_destroy_last(const bool moved) BOOST_NOEXCEPT_OR_NOTHROW
+ void priv_destroy_last(const bool moved = false) BOOST_NOEXCEPT_OR_NOTHROW
{
(void)moved;
if(!(value_traits::trivial_dctr || (value_traits::trivial_dctr_after_move && moved))){
@@ -2303,17 +2552,6 @@ class vector
this->m_holder.m_size -= n;
}
- void priv_destroy_last_n(const size_type n, const bool moved) BOOST_NOEXCEPT_OR_NOTHROW
- {
- BOOST_ASSERT(n <= this->m_holder.m_size);
- (void)moved;
- if(!(value_traits::trivial_dctr || (value_traits::trivial_dctr_after_move && moved))){
- T* const destroy_pos = container_detail::to_raw_pointer(this->m_holder.start()) + (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<class InpIt>
void priv_uninitialized_construct_at_end(InpIt first, InpIt last)
{
@@ -2554,69 +2792,6 @@ class vector
return this->priv_forward_range_insert(this->back_ptr(), n, insert_range_proxy);
}
- //Absolutely experimental. This function might change, disappear or simply crash!
- template<class BiDirPosConstIt, class BiDirSkipConstIt, class BiDirValueIt>
- void priv_insert_ordered_at( size_type element_count, BiDirPosConstIt last_position_it
- , bool do_skip, BiDirSkipConstIt last_skip_it, BiDirValueIt last_value_it)
- {
- const size_type old_size_pos = this->size();
- this->reserve(old_size_pos + element_count);
- T* const begin_ptr = container_detail::to_raw_pointer(this->m_holder.start());
- size_type insertions_left = element_count;
- size_type next_pos = old_size_pos;
- size_type 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){
- if(do_skip){
- size_type n = *(--last_skip_it);
- boost::container::iterator_advance(last_value_it, -difference_type(n));
- }
- const size_type pos = static_cast<size_type>(*(--last_position_it));
- BOOST_ASSERT(pos <= old_size_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 != next_pos)
- ? priv_insert_ordered_at_shift_range(pos, next_pos, this->size(), insertions_left)
- : hole_size
- ;
- if(new_hole_size > 0){
- //The hole was reduced by priv_insert_ordered_at_shift_range so expand exception rollback range backwards
- past_hole_values_destroyer.increment_size_backwards(next_pos - pos);
- //Insert the new value in the hole
- allocator_traits_type::construct(this->m_holder.alloc(), begin_ptr + pos + insertions_left - 1, *(--last_value_it));
- --new_hole_size;
- if(new_hole_size == 0){
- //Hole was just filled, disable exception rollback and change vector size
- past_hole_values_destroyer.release();
- this->m_holder.m_size += element_count;
- }
- else{
- //The hole was reduced by the new insertion by one
- past_hole_values_destroyer.increment_size_backwards(size_type(1u));
- }
- }
- else{
- if(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] = *(--last_value_it);
- }
- --insertions_left;
- hole_size = new_hole_size;
- next_pos = pos;
- }
- }
-
//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.
//
@@ -2647,7 +2822,7 @@ class vector
// |_>_>_>_>_>^
//
//
- //New situation in Case B (hole_size > 0):
+ //New situation in Case B (hole_size >= 0):
// range is moved through uninitialized moves
//
// first_pos last_pos limit_pos
@@ -2689,7 +2864,7 @@ class vector
//All uninitialized_moved
::boost::container::uninitialized_move_alloc
(this->m_holder.alloc(), first_ptr, last_ptr, first_ptr + shift_count);
- hole_size = last_pos + shift_count - limit_pos;
+ hole_size = first_pos + shift_count - limit_pos;
}
//Case C:
else{
@@ -2716,7 +2891,7 @@ class vector
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(!n) return;
+ if(BOOST_UNLIKELY(!n)) return;
//There is enough memory
T* const old_finish = this->back_raw();
const size_type elems_after = old_finish - pos;
diff --git a/boost/context/detail/config.hpp b/boost/context/detail/config.hpp
index 28edf1f953..ea23a5f9db 100644
--- a/boost/context/detail/config.hpp
+++ b/boost/context/detail/config.hpp
@@ -7,6 +7,9 @@
#ifndef BOOST_CONTEXT_DETAIL_CONFIG_H
#define BOOST_CONTEXT_DETAIL_CONFIG_H
+// required for SD-6 compile-time integer sequences
+#include <utility>
+
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
@@ -55,19 +58,24 @@
#endif
#undef BOOST_CONTEXT_NO_EXECUTION_CONTEXT
-#if defined( BOOST_NO_CXX11_DECLTYPE) || \
- defined( BOOST_NO_CXX11_DELETED_FUNCTIONS) || \
- defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) || \
- defined( BOOST_NO_CXX11_HDR_TUPLE) || \
- defined( BOOST_NO_CXX11_LAMBDAS) || \
- defined( BOOST_NO_CXX11_NOEXCEPT) || \
- defined( BOOST_NO_CXX11_NULLPTR) || \
- defined( BOOST_NO_CXX11_TEMPLATE_ALIASES) || \
- defined( BOOST_NO_CXX11_RVALUE_REFERENCES) || \
- defined( BOOST_NO_CXX11_VARIADIC_MACROS) || \
- defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \
- defined( BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES)
+#if defined(BOOST_NO_CXX11_DECLTYPE) || \
+ defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || \
+ defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) || \
+ defined(BOOST_NO_CXX11_HDR_TUPLE) || \
+ defined(BOOST_NO_CXX11_LAMBDAS) || \
+ defined(BOOST_NO_CXX11_NOEXCEPT) || \
+ defined(BOOST_NO_CXX11_NULLPTR) || \
+ defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) || \
+ defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \
+ defined(BOOST_NO_CXX11_VARIADIC_MACROS) || \
+ defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \
+ defined(BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES) || \
+ ! defined(__cpp_lib_integer_sequence) && __cpp_lib_integer_sequence < 201304
# define BOOST_CONTEXT_NO_EXECUTION_CONTEXT
#endif
+// workaroud: MSVC 14 does not provide macros to test for compile-time integer sequence
+#if _MSC_VER > 1800 // _MSC_VER == 1800 -> MS Visual Studio 2013
+# undef BOOST_CONTEXT_NO_EXECUTION_CONTEXT
+#endif
#endif // BOOST_CONTEXT_DETAIL_CONFIG_H
diff --git a/boost/context/detail/invoke.hpp b/boost/context/detail/invoke.hpp
new file mode 100644
index 0000000000..aba05d5cfb
--- /dev/null
+++ b/boost/context/detail/invoke.hpp
@@ -0,0 +1,48 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_CONTEXT_DETAIL_INVOKE_H
+#define BOOST_CONTEXT_DETAIL_INVOKE_H
+
+#include <functional>
+#include <type_traits>
+#include <utility>
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace context {
+namespace detail {
+
+template< typename Fn, typename... Args >
+typename std::enable_if<
+ std::is_member_pointer< typename std::decay< Fn >::type >::value,
+ typename std::result_of< Fn&&( Args && ...) >::type
+>::type
+invoke( Fn && fn, Args && ... args) {
+ return std::mem_fn( fn)( std::forward< Args >( args) ...);
+}
+
+template< typename Fn, typename ... Args >
+typename std::enable_if<
+ ! std::is_member_pointer< typename std::decay< Fn >::type >::value,
+ typename std::result_of< Fn&&( Args && ...) >::type
+>::type
+invoke( Fn && fn, Args && ... args) {
+ return std::forward< Fn >( fn)( std::forward< Args >( args) ...);
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+#include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_CONTEXT_DETAIL_INVOKE_H
diff --git a/boost/context/execution_context.hpp b/boost/context/execution_context.hpp
index 4d809b0c21..97b1d4e70a 100644
--- a/boost/context/execution_context.hpp
+++ b/boost/context/execution_context.hpp
@@ -4,304 +4,8 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_CONTEXT_EXECUTION_CONTEXT_H
-#define BOOST_CONTEXT_EXECUTION_CONTEXT_H
-
-#include <boost/context/detail/config.hpp>
-
-#if ! defined(BOOST_CONTEXT_NO_EXECUTION_CONTEXT)
-
-# include <cstddef>
-# include <cstdint>
-# include <cstdlib>
-# include <exception>
-# include <memory>
-# include <tuple>
-# include <utility>
-
-# include <boost/assert.hpp>
-# include <boost/config.hpp>
-# include <boost/context/fcontext.hpp>
-# include <boost/intrusive_ptr.hpp>
-
-# include <boost/context/stack_context.hpp>
-# include <boost/context/segmented_stack.hpp>
-
-# ifdef BOOST_HAS_ABI_HEADERS
-# include BOOST_ABI_PREFIX
-# endif
-
-# if defined(BOOST_USE_SEGMENTED_STACKS)
-extern "C" {
-
-void __splitstack_getcontext( void * [BOOST_CONTEXT_SEGMENTS]);
-
-void __splitstack_setcontext( void * [BOOST_CONTEXT_SEGMENTS]);
-
-}
-# endif
-
-namespace boost {
-namespace context {
-
-struct preallocated {
- void * sp;
- std::size_t size;
- stack_context sctx;
-
- preallocated( void * sp_, std::size_t size_, stack_context sctx_) noexcept :
- sp( sp_), size( size_), sctx( sctx_) {
- }
-};
-
-class BOOST_CONTEXT_DECL execution_context {
-private:
- struct fcontext {
- std::size_t use_count;
- fcontext_t fctx;
- stack_context sctx;
-
- // main-context
- fcontext() noexcept :
- use_count( 1),
- fctx( nullptr),
- sctx() {
- }
-
- // worker-context
- fcontext( fcontext_t fctx_, stack_context const& sctx_) noexcept :
- use_count( 0),
- fctx( fctx_),
- sctx( sctx_) {
- }
-
- virtual ~fcontext() noexcept {
- }
-
- virtual void deallocate() {
- }
-
- virtual void run() noexcept {
- }
-
- friend void intrusive_ptr_add_ref( fcontext * ctx) {
- ++ctx->use_count;
- }
-
- friend void intrusive_ptr_release( fcontext * ctx) {
- BOOST_ASSERT( nullptr != ctx);
-
- if ( 0 == --ctx->use_count) {
- ctx->~fcontext();
- }
- }
- };
-
- template< typename Fn, typename StackAlloc >
- class worker_fcontext : public fcontext {
- private:
- StackAlloc salloc_;
- Fn fn_;
-
- static void destroy( worker_fcontext * p) {
- StackAlloc salloc( p->salloc_);
- stack_context sctx( p->sctx);
- p->~worker_fcontext();
- salloc.deallocate( sctx);
- }
-
- public:
- explicit worker_fcontext( stack_context sctx, StackAlloc const& salloc, fcontext_t fctx, Fn && fn) noexcept :
- fcontext( fctx, sctx),
- salloc_( salloc),
- fn_( std::forward< Fn >( fn) ) {
- }
-
- void deallocate() override final {
- destroy( this);
- }
-
- void run() noexcept override final {
- fn_();
- }
- };
-
- static void entry_func( intptr_t p) noexcept {
- BOOST_ASSERT( 0 != p);
-
- fcontext * bp( reinterpret_cast< fcontext * >( p) );
- BOOST_ASSERT( nullptr != bp);
-
- bp->run();
- }
-
- typedef boost::intrusive_ptr< fcontext > ptr_t;
-
- thread_local static fcontext main_ctx_;
- thread_local static ptr_t current_ctx_;
-
- boost::intrusive_ptr< fcontext > ptr_;
-# if defined(BOOST_USE_SEGMENTED_STACKS)
- bool use_segmented_stack_ = false;
-# endif
-
- template< typename StackAlloc, typename Fn >
- static fcontext * create_context( StackAlloc salloc, Fn && fn) {
- typedef worker_fcontext< Fn, StackAlloc > func_t;
-
- stack_context sctx( salloc.allocate() );
- // reserve space for control structure
- std::size_t size = sctx.size - sizeof( func_t);
- void * sp = static_cast< char * >( sctx.sp) - sizeof( func_t);
-#if 0
- constexpr std::size_t func_alignment = 64; // alignof( func_t);
- constexpr std::size_t func_size = sizeof( func_t);
- // reserve space on stack
- void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment;
- // align sp pointer
- sp = std::align( func_alignment, func_size, sp, func_size + func_alignment);
- BOOST_ASSERT( nullptr != sp);
- // calculate remaining size
- std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) );
-#endif
- // create fast-context
- fcontext_t fctx = make_fcontext( sp, size, & execution_context::entry_func);
- BOOST_ASSERT( nullptr != fctx);
- // placment new for control structure on fast-context stack
- return new ( sp) func_t( sctx, salloc, fctx, std::forward< Fn >( fn) );
- }
-
- template< typename StackAlloc, typename Fn >
- static fcontext * create_context( preallocated palloc, StackAlloc salloc, Fn && fn) {
- typedef worker_fcontext< Fn, StackAlloc > func_t;
-
- // reserve space for control structure
- std::size_t size = palloc.size - sizeof( func_t);
- void * sp = static_cast< char * >( palloc.sp) - sizeof( func_t);
-#if 0
- constexpr std::size_t func_alignment = 64; // alignof( func_t);
- constexpr std::size_t func_size = sizeof( func_t);
- // reserve space on stack
- void * sp = static_cast< char * >( palloc.sp) - func_size - func_alignment;
- // align sp pointer
- sp = std::align( func_alignment, func_size, sp, func_size + func_alignment);
- BOOST_ASSERT( nullptr != sp);
- // calculate remaining size
- std::size_t size = palloc.size - ( static_cast< char * >( palloc.sp) - static_cast< char * >( sp) );
+#if defined(BOOST_USE_WINFIBERS)
+#include <boost/context/execution_context_winfib.ipp>
+#else
+#include <boost/context/execution_context.ipp>
#endif
- // create fast-context
- fcontext_t fctx = make_fcontext( sp, size, & execution_context::entry_func);
- BOOST_ASSERT( nullptr != fctx);
- // placment new for control structure on fast-context stack
- return new ( sp) func_t( palloc.sctx, salloc, fctx, std::forward< Fn >( fn) );
- }
-
- template< typename StackAlloc, typename Fn, typename Tpl, std::size_t ... I >
- static fcontext * create_worker_fcontext( StackAlloc salloc,
- Fn && fn_, Tpl && tpl_,
- std::index_sequence< I ... >) {
- return create_context( salloc,
- [fn=std::forward< Fn >( fn_),tpl=std::forward< Tpl >( tpl_)] () mutable {
- try {
- fn(
- // std::tuple_element<> does not perfect forwarding
- std::forward< decltype( std::get< I >( std::declval< Tpl >() ) ) >(
- std::get< I >( std::forward< Tpl >( tpl) ) ) ... );
- } catch (...) {
- std::terminate();
- }
- });
- }
-
- template< typename StackAlloc, typename Fn, typename Tpl, std::size_t ... I >
- static fcontext * create_worker_fcontext( preallocated palloc, StackAlloc salloc,
- Fn && fn_, Tpl && tpl_,
- std::index_sequence< I ... >) {
- return create_context( palloc, salloc,
- [fn=std::forward< Fn >( fn_),tpl=std::forward< Tpl >( tpl_)] () mutable {
- try {
- fn(
- // std::tuple_element<> does not perfect forwarding
- std::forward< decltype( std::get< I >( std::declval< Tpl >() ) ) >(
- std::get< I >( std::forward< Tpl >( tpl) ) ) ... );
- } catch (...) {
- std::terminate();
- }
- });
- }
-
- execution_context() :
- ptr_( current_ctx_) {
- }
-
-public:
- static execution_context current() noexcept {
- return execution_context();
- }
-
-# if defined(BOOST_USE_SEGMENTED_STACKS)
- template< typename Fn, typename ... Args >
- explicit execution_context( segmented_stack salloc, Fn && fn, Args && ... args) :
- ptr_( create_worker_fcontext( salloc,
- std::forward< Fn >( fn),
- std::make_tuple( std::forward< Args >( args) ... ),
- std::index_sequence_for< Args ... >() ) ),
- use_segmented_stack_( true) {
- }
-
- template< typename Fn, typename ... Args >
- explicit execution_context( preallocated palloc, segmented_stack salloc, Fn && fn, Args && ... args) :
- ptr_( create_worker_fcontext( palloc, salloc,
- std::forward< Fn >( fn),
- std::make_tuple( std::forward< Args >( args) ... ),
- std::index_sequence_for< Args ... >() ) ),
- use_segmented_stack_( true) {
- }
-# endif
-
- template< typename StackAlloc, typename Fn, typename ... Args >
- explicit execution_context( StackAlloc salloc, Fn && fn, Args && ... args) :
- ptr_( create_worker_fcontext( salloc,
- std::forward< Fn >( fn),
- std::make_tuple( std::forward< Args >( args) ... ),
- std::index_sequence_for< Args ... >() ) ) {
- }
-
- template< typename StackAlloc, typename Fn, typename ... Args >
- explicit execution_context( preallocated palloc, StackAlloc salloc, Fn && fn, Args && ... args) :
- ptr_( create_worker_fcontext( palloc, salloc,
- std::forward< Fn >( fn),
- std::make_tuple( std::forward< Args >( args) ... ),
- std::index_sequence_for< Args ... >() ) ) {
- }
-
- void resume( bool preserve_fpu = false) noexcept {
- fcontext * old_ctx( current_ctx_.get() );
- fcontext * new_ctx( ptr_.get() );
- current_ctx_ = ptr_;
-# if defined(BOOST_USE_SEGMENTED_STACKS)
- if ( use_segmented_stack_) {
- __splitstack_getcontext( old_ctx->sctx.segments_ctx);
- __splitstack_setcontext( new_ctx->sctx.segments_ctx);
-
- jump_fcontext( & old_ctx->fctx, new_ctx->fctx, reinterpret_cast< intptr_t >( new_ctx), preserve_fpu);
-
- __splitstack_setcontext( old_ctx->sctx.segments_ctx);
- } else {
- jump_fcontext( & old_ctx->fctx, new_ctx->fctx, reinterpret_cast< intptr_t >( new_ctx), preserve_fpu);
- }
-# else
- jump_fcontext( & old_ctx->fctx, new_ctx->fctx, reinterpret_cast< intptr_t >( new_ctx), preserve_fpu);
-# endif
- }
-};
-
-}}
-
-# ifdef BOOST_HAS_ABI_HEADERS
-# include BOOST_ABI_SUFFIX
-# endif
-
-#endif
-
-#endif // BOOST_CONTEXT_EXECUTION_CONTEXT_H
diff --git a/boost/context/execution_context.ipp b/boost/context/execution_context.ipp
new file mode 100644
index 0000000000..8832d75c20
--- /dev/null
+++ b/boost/context/execution_context.ipp
@@ -0,0 +1,374 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_CONTEXT_EXECUTION_CONTEXT_H
+#define BOOST_CONTEXT_EXECUTION_CONTEXT_H
+
+#include <boost/context/detail/config.hpp>
+
+#if ! defined(BOOST_CONTEXT_NO_EXECUTION_CONTEXT)
+
+# include <algorithm>
+# include <cstddef>
+# include <cstdint>
+# include <cstdlib>
+# include <functional>
+# include <memory>
+# include <tuple>
+# include <utility>
+
+# include <boost/assert.hpp>
+# include <boost/config.hpp>
+# include <boost/context/fcontext.hpp>
+# include <boost/intrusive_ptr.hpp>
+
+# include <boost/context/detail/invoke.hpp>
+# include <boost/context/stack_context.hpp>
+# include <boost/context/segmented_stack.hpp>
+
+# ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+# endif
+
+# if defined(BOOST_USE_SEGMENTED_STACKS)
+extern "C" {
+
+void __splitstack_getcontext( void * [BOOST_CONTEXT_SEGMENTS]);
+
+void __splitstack_setcontext( void * [BOOST_CONTEXT_SEGMENTS]);
+
+}
+# endif
+
+namespace boost {
+namespace context {
+
+struct preallocated {
+ void * sp;
+ std::size_t size;
+ stack_context sctx;
+
+ preallocated( void * sp_, std::size_t size_, stack_context sctx_) noexcept :
+ sp( sp_), size( size_), sctx( sctx_) {
+ }
+};
+
+class BOOST_CONTEXT_DECL execution_context {
+private:
+ struct activation_record {
+ typedef boost::intrusive_ptr< activation_record > ptr_t;
+
+ enum flag_t {
+ flag_main_ctx = 1 << 1,
+ flag_preserve_fpu = 1 << 2,
+ flag_segmented_stack = 1 << 3
+ };
+
+ thread_local static activation_record toplevel_rec;
+ thread_local static ptr_t current_rec;
+
+ std::size_t use_count;
+ fcontext_t fctx;
+ stack_context sctx;
+ int flags;
+
+ // used for toplevel-context
+ // (e.g. main context, thread-entry context)
+ activation_record() noexcept :
+ use_count( 1),
+ fctx( nullptr),
+ sctx(),
+ flags( flag_main_ctx) {
+ }
+
+ activation_record( fcontext_t fctx_, stack_context sctx_, bool use_segmented_stack) noexcept :
+ use_count( 0),
+ fctx( fctx_),
+ sctx( sctx_),
+ flags( use_segmented_stack ? flag_segmented_stack : 0) {
+ }
+
+ virtual ~activation_record() noexcept = default;
+
+ void resume( bool fpu = false) noexcept {
+ // store current activation record in local variable
+ activation_record * from = current_rec.get();
+ // store `this` in static, thread local pointer
+ // `this` will become the active (running) context
+ // returned by execution_context::current()
+ current_rec = this;
+ // set FPU flag
+ if (fpu) {
+ from->flags |= flag_preserve_fpu;
+ this->flags |= flag_preserve_fpu;
+ } else {
+ from->flags &= ~flag_preserve_fpu;
+ this->flags &= ~flag_preserve_fpu;
+ }
+# if defined(BOOST_USE_SEGMENTED_STACKS)
+ if ( 0 != (flags & flag_segmented_stack) ) {
+ // adjust segmented stack properties
+ __splitstack_getcontext( from->sctx.segments_ctx);
+ __splitstack_setcontext( sctx.segments_ctx);
+ // context switch from parent context to `this`-context
+ jump_fcontext( & from->fctx, fctx, reinterpret_cast< intptr_t >( this), fpu);
+ // parent context resumed
+ // adjust segmented stack properties
+ __splitstack_setcontext( from->sctx.segments_ctx);
+ } else {
+ // context switch from parent context to `this`-context
+ jump_fcontext( & from->fctx, fctx, reinterpret_cast< intptr_t >( this), fpu);
+ // parent context resumed
+ }
+# else
+ // context switch from parent context to `this`-context
+ jump_fcontext( & from->fctx, fctx, reinterpret_cast< intptr_t >( this), fpu);
+ // parent context resumed
+# endif
+ }
+
+ virtual void deallocate() {}
+
+ friend void intrusive_ptr_add_ref( activation_record * ar) {
+ ++ar->use_count;
+ }
+
+ friend void intrusive_ptr_release( activation_record * ar) {
+ BOOST_ASSERT( nullptr != ar);
+
+ if ( 0 == --ar->use_count) {
+ ar->deallocate();
+ }
+ }
+ };
+
+ template< typename Fn, typename StackAlloc >
+ class capture_record : public activation_record {
+ private:
+ StackAlloc salloc_;
+ Fn fn_;
+
+ static void destroy( capture_record * p) {
+ StackAlloc salloc( p->salloc_);
+ stack_context sctx( p->sctx);
+ // deallocate activation record
+ p->~capture_record();
+ // destroy stack with stack allocator
+ salloc.deallocate( sctx);
+ }
+
+ public:
+ explicit capture_record( stack_context sctx, StackAlloc const& salloc, fcontext_t fctx, Fn && fn, bool use_segmented_stack) noexcept :
+ activation_record( fctx, sctx, use_segmented_stack),
+ salloc_( salloc),
+ fn_( std::forward< Fn >( fn) ) {
+ }
+
+ void deallocate() override final {
+ destroy( this);
+ }
+
+ void run() noexcept {
+ try {
+ fn_();
+ } catch (...) {
+ std::terminate();
+ }
+ BOOST_ASSERT( 0 == (flags & flag_main_ctx) );
+ }
+ };
+
+ // tampoline function
+ // entered if the execution context
+ // is resumed for the first time
+ template< typename AR >
+ static void entry_func( intptr_t p) noexcept {
+ BOOST_ASSERT( 0 != p);
+
+ AR * ar( reinterpret_cast< AR * >( p) );
+ BOOST_ASSERT( nullptr != ar);
+
+ // start execution of toplevel context-function
+ ar->run();
+ }
+
+ typedef boost::intrusive_ptr< activation_record > ptr_t;
+
+ ptr_t ptr_;
+
+ template< typename StackAlloc, typename Fn >
+ static activation_record * create_context( StackAlloc salloc, Fn && fn, bool use_segmented_stack) {
+ typedef capture_record< Fn, StackAlloc > capture_t;
+
+ stack_context sctx( salloc.allocate() );
+ // reserve space for control structure
+#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN)
+ std::size_t size = sctx.size - sizeof( capture_t);
+ void * sp = static_cast< char * >( sctx.sp) - sizeof( capture_t);
+#else
+ constexpr std::size_t func_alignment = 64; // alignof( capture_t);
+ constexpr std::size_t func_size = sizeof( capture_t);
+ // reserve space on stack
+ void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment;
+ // align sp pointer
+ std::size_t space = func_size + func_alignment;
+ sp = std::align( func_alignment, func_size, sp, space);
+ BOOST_ASSERT( nullptr != sp);
+ // calculate remaining size
+ std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) );
+#endif
+ // create fast-context
+ fcontext_t fctx = make_fcontext( sp, size, & execution_context::entry_func< capture_t >);
+ BOOST_ASSERT( nullptr != fctx);
+ // placment new for control structure on fast-context stack
+ return new ( sp) capture_t( sctx, salloc, fctx, std::forward< Fn >( fn), use_segmented_stack);
+ }
+
+ template< typename StackAlloc, typename Fn >
+ static activation_record * create_context( preallocated palloc, StackAlloc salloc, Fn && fn, bool use_segmented_stack) {
+ typedef capture_record< Fn, StackAlloc > capture_t;
+
+ // reserve space for control structure
+#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN)
+ std::size_t size = palloc.size - sizeof( capture_t);
+ void * sp = static_cast< char * >( palloc.sp) - sizeof( capture_t);
+#else
+ constexpr std::size_t func_alignment = 64; // alignof( capture_t);
+ constexpr std::size_t func_size = sizeof( capture_t);
+ // reserve space on stack
+ void * sp = static_cast< char * >( palloc.sp) - func_size - func_alignment;
+ // align sp pointer
+ std::size_t space = func_size + func_alignment;
+ sp = std::align( func_alignment, func_size, sp, space);
+ BOOST_ASSERT( nullptr != sp);
+ // calculate remaining size
+ std::size_t size = palloc.size - ( static_cast< char * >( palloc.sp) - static_cast< char * >( sp) );
+#endif
+ // create fast-context
+ fcontext_t fctx = make_fcontext( sp, size, & execution_context::entry_func< capture_t >);
+ BOOST_ASSERT( nullptr != fctx);
+ // placment new for control structure on fast-context stack
+ return new ( sp) capture_t( palloc.sctx, salloc, fctx, std::forward< Fn >( fn), use_segmented_stack);
+ }
+
+ template< typename StackAlloc, typename Fn, typename Tpl, std::size_t ... I >
+ static activation_record * create_capture_record( StackAlloc salloc,
+ Fn && fn_, Tpl && tpl_,
+ std::index_sequence< I ... >,
+ bool use_segmented_stack) {
+ return create_context(
+ salloc,
+ // lambda, executed in new execution context
+ [fn=std::forward< Fn >( fn_),tpl=std::forward< Tpl >( tpl_)] () mutable -> decltype( auto) {
+ detail::invoke( fn,
+ // non-type template parameter pack used to extract the
+ // parameters (arguments) from the tuple and pass them to fn
+ // via parameter pack expansion
+ // std::tuple_element<> does not perfect forwarding
+ std::forward< decltype( std::get< I >( std::declval< Tpl >() ) ) >(
+ std::get< I >( std::forward< Tpl >( tpl) ) ) ... );
+ },
+ use_segmented_stack);
+ }
+
+ template< typename StackAlloc, typename Fn, typename Tpl, std::size_t ... I >
+ static activation_record * create_capture_record( preallocated palloc, StackAlloc salloc,
+ Fn && fn_, Tpl && tpl_,
+ std::index_sequence< I ... >,
+ bool use_segmented_stack) {
+ return create_context(
+ palloc, salloc,
+ // lambda, executed in new execution context
+ [fn=std::forward< Fn >( fn_),tpl=std::forward< Tpl >( tpl_)] () mutable -> decltype( auto) {
+ detail::invoke( fn,
+ // non-type template parameter pack used to extract the
+ // parameters (arguments) from the tuple and pass them to fn
+ // via parameter pack expansion
+ // std::tuple_element<> does not perfect forwarding
+ std::forward< decltype( std::get< I >( std::declval< Tpl >() ) ) >(
+ std::get< I >( std::forward< Tpl >( tpl) ) ) ... );
+ },
+ use_segmented_stack);
+ }
+
+ execution_context() :
+ // default constructed with current activation_record
+ ptr_( activation_record::current_rec) {
+ }
+
+public:
+ static execution_context current() noexcept {
+ return execution_context();
+ }
+
+# if defined(BOOST_USE_SEGMENTED_STACKS)
+ template< typename Fn, typename ... Args >
+ explicit execution_context( segmented_stack salloc, Fn && fn, Args && ... args) :
+ // deferred execution of fn and its arguments
+ // arguments are stored in std::tuple<>
+ // non-type template parameter pack via std::index_sequence_for<>
+ // preserves the number of arguments
+ // used to extract the function arguments from std::tuple<>
+ ptr_( create_capture_record( salloc,
+ std::forward< Fn >( fn),
+ std::make_tuple( std::forward< Args >( args) ... ),
+ std::index_sequence_for< Args ... >(), true) ) {
+ }
+
+ template< typename Fn, typename ... Args >
+ explicit execution_context( preallocated palloc, segmented_stack salloc, Fn && fn, Args && ... args) :
+ // deferred execution of fn and its arguments
+ // arguments are stored in std::tuple<>
+ // non-type template parameter pack via std::index_sequence_for<>
+ // preserves the number of arguments
+ // used to extract the function arguments from std::tuple<>
+ ptr_( create_capture_record( palloc, salloc,
+ std::forward< Fn >( fn),
+ std::make_tuple( std::forward< Args >( args) ... ),
+ std::index_sequence_for< Args ... >(), true) ) {
+ }
+# endif
+
+ template< typename StackAlloc, typename Fn, typename ... Args >
+ explicit execution_context( StackAlloc salloc, Fn && fn, Args && ... args) :
+ // deferred execution of fn and its arguments
+ // arguments are stored in std::tuple<>
+ // non-type template parameter pack via std::index_sequence_for<>
+ // preserves the number of arguments
+ // used to extract the function arguments from std::tuple<>
+ ptr_( create_capture_record( salloc,
+ std::forward< Fn >( fn),
+ std::make_tuple( std::forward< Args >( args) ... ),
+ std::index_sequence_for< Args ... >(), false) ) {
+ }
+
+ template< typename StackAlloc, typename Fn, typename ... Args >
+ explicit execution_context( preallocated palloc, StackAlloc salloc, Fn && fn, Args && ... args) :
+ // deferred execution of fn and its arguments
+ // arguments are stored in std::tuple<>
+ // non-type template parameter pack via std::index_sequence_for<>
+ // preserves the number of arguments
+ // used to extract the function arguments from std::tuple<>
+ ptr_( create_capture_record( palloc, salloc,
+ std::forward< Fn >( fn),
+ std::make_tuple( std::forward< Args >( args) ... ),
+ std::index_sequence_for< Args ... >(), false) ) {
+ }
+
+ void operator()( bool preserve_fpu = false) noexcept {
+ ptr_->resume( preserve_fpu);
+ }
+};
+
+}}
+
+# ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+# endif
+
+#endif
+
+#endif // BOOST_CONTEXT_EXECUTION_CONTEXT_H
diff --git a/boost/context/execution_context_winfib.ipp b/boost/context/execution_context_winfib.ipp
new file mode 100644
index 0000000000..7b0a92b550
--- /dev/null
+++ b/boost/context/execution_context_winfib.ipp
@@ -0,0 +1,308 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_CONTEXT_EXECUTION_CONTEXT_H
+#define BOOST_CONTEXT_EXECUTION_CONTEXT_H
+
+#include <boost/context/detail/config.hpp>
+
+#if ! defined(BOOST_CONTEXT_NO_EXECUTION_CONTEXT)
+
+#include <windows.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <memory>
+#include <tuple>
+#include <utility>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/intrusive_ptr.hpp>
+
+#include <boost/context/detail/invoke.hpp>
+#include <boost/context/stack_context.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace context {
+
+struct preallocated {
+ void * sp;
+ std::size_t size;
+ stack_context sctx;
+
+ preallocated( void * sp_, std::size_t size_, stack_context sctx_) noexcept :
+ sp( sp_), size( size_), sctx( sctx_) {
+ }
+};
+
+class BOOST_CONTEXT_DECL execution_context {
+private:
+ struct activation_record {
+ typedef boost::intrusive_ptr< activation_record > ptr_t;
+
+ enum flag_t {
+ flag_main_ctx = 1 << 1,
+ flag_preserve_fpu = 1 << 2,
+ flag_segmented_stack = 1 << 3
+ };
+
+ thread_local static activation_record toplevel_rec;
+ thread_local static ptr_t current_rec;
+
+ std::size_t use_count;
+ LPVOID fiber;
+ stack_context sctx;
+ int flags;
+
+ // used for toplevel-context
+ // (e.g. main context, thread-entry context)
+ activation_record() noexcept :
+ use_count( 1),
+ fiber( nullptr),
+ sctx(),
+ flags( flag_main_ctx) {
+ }
+
+ activation_record( stack_context sctx_, bool use_segmented_stack) noexcept :
+ use_count( 0),
+ fiber( nullptr),
+ sctx( sctx_),
+ flags( use_segmented_stack ? flag_segmented_stack : 0) {
+ }
+
+ virtual ~activation_record() noexcept = default;
+
+ void resume() noexcept {
+ // store current activation record in local variable
+ activation_record * from = current_rec.get();
+ // store `this` in static, thread local pointer
+ // `this` will become the active (running) context
+ // returned by execution_context::current()
+ current_rec = this;
+ // context switch from parent context to `this`-context
+#if ( _WIN32_WINNT > 0x0600)
+ if ( ::IsThreadAFiber() ) {
+ from->fiber = ::GetCurrentFiber();
+ } else {
+ from->fiber = ::ConvertThreadToFiber( nullptr);
+ }
+#else
+ from->fiber = ::ConvertThreadToFiber( nullptr);
+ if ( nullptr == from->fiber) {
+ DWORD err = ::GetLastError();
+ BOOST_ASSERT( ERROR_ALREADY_FIBER == err);
+ from->fiber = ::GetCurrentFiber();
+ BOOST_ASSERT( nullptr != from->fiber);
+ BOOST_ASSERT( reinterpret_cast< LPVOID >( 0x1E00) != from->fiber);
+ }
+#endif
+ ::SwitchToFiber( fiber);
+ }
+
+ virtual void deallocate() {}
+
+ friend void intrusive_ptr_add_ref( activation_record * ar) {
+ ++ar->use_count;
+ }
+
+ friend void intrusive_ptr_release( activation_record * ar) {
+ BOOST_ASSERT( nullptr != ar);
+
+ if ( 0 == --ar->use_count) {
+ ar->deallocate();
+ }
+ }
+ };
+
+ template< typename Fn, typename StackAlloc >
+ class capture_record : public activation_record {
+ private:
+ StackAlloc salloc_;
+ Fn fn_;
+
+ static void destroy( capture_record * p) {
+ StackAlloc salloc( p->salloc_);
+ stack_context sctx( p->sctx);
+ // deallocate activation record
+ p->~capture_record();
+ // destroy stack with stack allocator
+ salloc.deallocate( sctx);
+ }
+
+ public:
+ explicit capture_record( stack_context sctx, StackAlloc const& salloc, Fn && fn, bool use_segmented_stack) noexcept :
+ activation_record( sctx, use_segmented_stack),
+ salloc_( salloc),
+ fn_( std::forward< Fn >( fn) ) {
+ }
+
+ void deallocate() override final {
+ destroy( this);
+ }
+
+ void run() noexcept {
+ try {
+ fn_();
+ } catch (...) {
+ std::terminate();
+ }
+ BOOST_ASSERT( 0 == (flags & flag_main_ctx) );
+ }
+ };
+
+ // tampoline function
+ // entered if the execution context
+ // is resumed for the first time
+ template< typename AR >
+ static VOID WINAPI entry_func( LPVOID p) {
+ BOOST_ASSERT( 0 != p);
+
+ AR * ar( reinterpret_cast< AR * >( p) );
+ // start execution of toplevel context-function
+ ar->run();
+ //ctx->fn_(ctx->param_);
+ ::DeleteFiber( ar->fiber);
+ }
+
+ typedef boost::intrusive_ptr< activation_record > ptr_t;
+
+ ptr_t ptr_;
+
+ template< typename StackAlloc, typename Fn >
+ static activation_record * create_context( StackAlloc salloc, Fn && fn, bool use_segmented_stack) {
+ typedef capture_record< Fn, StackAlloc > capture_t;
+
+ // hackish
+ std::size_t fsize = salloc.size_;
+ salloc.size_ = sizeof( capture_t);
+
+ stack_context sctx( salloc.allocate() );
+ // reserve space for control structure
+ void * sp = static_cast< char * >( sctx.sp) - sizeof( capture_t);
+ // placment new for control structure on fast-context stack
+ capture_t * cr = new ( sp) capture_t( sctx, salloc, std::forward< Fn >( fn), use_segmented_stack);
+ // create fiber
+ // use default stacksize
+ cr->fiber = ::CreateFiber( fsize, execution_context::entry_func< capture_t >, cr);
+ BOOST_ASSERT( nullptr != cr->fiber);
+ return cr;
+ }
+
+ template< typename StackAlloc, typename Fn >
+ static activation_record * create_context( preallocated palloc, StackAlloc salloc, Fn && fn, bool use_segmented_stack) {
+ typedef capture_record< Fn, StackAlloc > capture_t;
+
+ // hackish
+ std::size_t fsize = salloc.size_;
+ salloc.size_ = sizeof( capture_t);
+
+ // reserve space for control structure
+ void * sp = static_cast< char * >( palloc.sp) - sizeof( capture_t);
+ // placment new for control structure on fast-context stack
+ capture_t * cr = new ( sp) capture_t( palloc.sctx, salloc, std::forward< Fn >( fn), use_segmented_stack);
+ // create fiber
+ // use default stacksize
+ cr->fiber = ::CreateFiber( fsize, execution_context::entry_func< capture_t >, cr);
+ BOOST_ASSERT( nullptr != cr->fiber);
+ return cr;
+ }
+
+ template< typename StackAlloc, typename Fn, typename Tpl, std::size_t ... I >
+ static activation_record * create_capture_record( StackAlloc salloc,
+ Fn && fn_, Tpl && tpl_,
+ std::index_sequence< I ... >,
+ bool use_segmented_stack) {
+ return create_context(
+ salloc,
+ // lambda, executed in new execution context
+ [fn=std::forward< Fn >( fn_),tpl=std::forward< Tpl >( tpl_)] () mutable -> decltype( auto) {
+ detail::invoke( fn,
+ // non-type template parameter pack used to extract the
+ // parameters (arguments) from the tuple and pass them to fn
+ // via parameter pack expansion
+ // std::tuple_element<> does not perfect forwarding
+ std::forward< decltype( std::get< I >( std::declval< Tpl >() ) ) >(
+ std::get< I >( std::forward< Tpl >( tpl) ) ) ... );
+ },
+ use_segmented_stack);
+ }
+
+ template< typename StackAlloc, typename Fn, typename Tpl, std::size_t ... I >
+ static activation_record * create_capture_record( preallocated palloc, StackAlloc salloc,
+ Fn && fn_, Tpl && tpl_,
+ std::index_sequence< I ... >,
+ bool use_segmented_stack) {
+ return create_context(
+ palloc, salloc,
+ // lambda, executed in new execution context
+ [fn=std::forward< Fn >( fn_),tpl=std::forward< Tpl >( tpl_)] () mutable -> decltype( auto) {
+ detail::invoke( fn,
+ // non-type template parameter pack used to extract the
+ // parameters (arguments) from the tuple and pass them to fn
+ // via parameter pack expansion
+ // std::tuple_element<> does not perfect forwarding
+ std::forward< decltype( std::get< I >( std::declval< Tpl >() ) ) >(
+ std::get< I >( std::forward< Tpl >( tpl) ) ) ... );
+ },
+ use_segmented_stack);
+ }
+
+ execution_context() :
+ // default constructed with current activation_record
+ ptr_( activation_record::current_rec) {
+ }
+
+public:
+ static execution_context current() noexcept {
+ return execution_context();
+ }
+
+ template< typename StackAlloc, typename Fn, typename ... Args >
+ explicit execution_context( StackAlloc salloc, Fn && fn, Args && ... args) :
+ // deferred execution of fn and its arguments
+ // arguments are stored in std::tuple<>
+ // non-type template parameter pack via std::index_sequence_for<>
+ // preserves the number of arguments
+ // used to extract the function arguments from std::tuple<>
+ ptr_( create_capture_record( salloc,
+ std::forward< Fn >( fn),
+ std::make_tuple( std::forward< Args >( args) ... ),
+ std::index_sequence_for< Args ... >(), false) ) {
+ }
+
+ template< typename StackAlloc, typename Fn, typename ... Args >
+ explicit execution_context( preallocated palloc, StackAlloc salloc, Fn && fn, Args && ... args) :
+ // deferred execution of fn and its arguments
+ // arguments are stored in std::tuple<>
+ // non-type template parameter pack via std::index_sequence_for<>
+ // preserves the number of arguments
+ // used to extract the function arguments from std::tuple<>
+ ptr_( create_capture_record( palloc, salloc,
+ std::forward< Fn >( fn),
+ std::make_tuple( std::forward< Args >( args) ... ),
+ std::index_sequence_for< Args ... >(), false) ) {
+ }
+
+ void operator()( bool preserve_fpu = false) noexcept {
+ ptr_->resume();
+ }
+};
+
+}}
+
+# ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+# endif
+
+#endif
+
+#endif // BOOST_CONTEXT_EXECUTION_CONTEXT_H
diff --git a/boost/context/fixedsize_stack.hpp b/boost/context/fixedsize_stack.hpp
index 5acb5f47c0..ab19609e87 100644
--- a/boost/context/fixedsize_stack.hpp
+++ b/boost/context/fixedsize_stack.hpp
@@ -32,6 +32,10 @@ namespace context {
template< typename traitsT >
class basic_fixedsize_stack {
private:
+#if defined(BOOST_USE_WINFIBERS)
+ friend class execution_context;
+#endif
+
std::size_t size_;
public:
@@ -58,8 +62,10 @@ public:
void deallocate( stack_context & sctx) {
BOOST_ASSERT( sctx.sp);
+#if defined(BOOST_USE_WINFIBERS)
BOOST_ASSERT( traits_type::minimum_size() <= sctx.size);
BOOST_ASSERT( traits_type::is_unbounded() || ( traits_type::maximum_size() >= sctx.size) );
+#endif
#if defined(BOOST_USE_VALGRIND)
VALGRIND_STACK_DEREGISTER( sctx.valgrind_stack_id);
diff --git a/boost/context/windows/protected_fixedsize_stack.hpp b/boost/context/windows/protected_fixedsize_stack.hpp
index 478c8c4ae1..e6efee62cf 100644
--- a/boost/context/windows/protected_fixedsize_stack.hpp
+++ b/boost/context/windows/protected_fixedsize_stack.hpp
@@ -31,6 +31,10 @@ namespace context {
template< typename traitsT >
class basic_protected_fixedsize_stack {
private:
+#if defined(BOOST_USE_WINFIBERS)
+ friend class execution_context;
+#endif
+
std::size_t size_;
public:
@@ -74,8 +78,10 @@ public:
void deallocate( stack_context & sctx) {
BOOST_ASSERT( sctx.sp);
+#if defined(BOOST_USE_WINFIBERS)
BOOST_ASSERT( traits_type::minimum_size() <= sctx.size);
BOOST_ASSERT( traits_type::is_unbounded() || ( traits_type::maximum_size() >= sctx.size) );
+#endif
void * vp = static_cast< char * >( sctx.sp) - sctx.size;
::VirtualFree( vp, 0, MEM_RELEASE);
diff --git a/boost/convert.hpp b/boost/convert.hpp
new file mode 100644
index 0000000000..fd38fc1c01
--- /dev/null
+++ b/boost/convert.hpp
@@ -0,0 +1,216 @@
+/// @file
+// Boost.Convert
+// Copyright (c) 2009-2014 Vladimir Batov.
+//
+// Many thanks to Julian Gonggrijp, Rob Stewart, Andrzej Krzemienski, Matus Chochlik, Jeroen Habraken,
+// Hartmut Kaiser, Joel De Guzman, Thijs (M.A.) van den Berg, Roland Bock, Gavin Lambert, Paul Bristow,
+// Alex Hagen-Zanker, Christopher Kormanyos for taking part in the Boost.Convert review.
+//
+// Special thanks to:
+//
+// 1. Alex Hagen-Zanker, Roland Bock, Rob Stewart for their considerable contributions to the design
+// and implementation of the library;
+// 2. Andrzej Krzemienski for helping to partition responsibilities and to ultimately pave
+// the way for the boost::optional and future std::tr2::optional deployment;
+// 3. Edward Diener the Boost Review Manager for helping with the converters' design, his continuous
+// involvement, technical and administrative help, guidance and advice;
+// 4. Joel De Guzman, Rob Stewart and Alex Hagen-Zanker for making sure the performance tests work
+// as they should;
+// 5. Paul Bristow for helping great deal with the documentation;
+// 6. Kevlin Henney and Dave Abrahams for their lexical_cast-related insights and explanations.
+//
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_HPP
+#define BOOST_CONVERT_HPP
+
+#include <boost/convert/detail/is_fun.hpp>
+#include <boost/ref.hpp>
+
+namespace boost
+{
+ namespace detail { enum throw_on_failure {}; }
+
+ /// @details The boost::throw_on_failure is the name of an object of the
+ /// boost::detail::throw_on_failure type that is used to indicate
+ /// desired exception-throwing behavior.
+ detail::throw_on_failure const throw_on_failure = detail::throw_on_failure(0);
+
+ namespace cnv
+ {
+ template<typename, typename, typename> struct reference;
+ struct by_default;
+ }
+
+ /// @brief Boost.Convert main deployment interface
+ /// @param[in] value_in Value of the TypeIn type to be converted to the TyeOut type
+ /// @param[in] converter Converter to be used for conversion
+ /// @return boost::optional<TypeOut> result of conversion together with the indication of
+ /// success or failure of the conversion request.
+ /// @details For example,
+ /// @code
+ /// boost::cnv::cstream cnv;
+ ///
+ /// boost::optional<int> i = boost::convert<int>("12", cnv);
+ /// boost::optional<string> s = boost::convert<string>(123.456, cnv);
+ /// @endcode
+
+ template<typename TypeOut, typename TypeIn, typename Converter>
+ boost::optional<TypeOut>
+ convert(TypeIn const& value_in, Converter const& converter)
+ {
+ optional<TypeOut> result;
+ boost::unwrap_ref(converter)(value_in, result);
+ return result;
+ }
+
+ namespace cnv { namespace detail
+ {
+ template<typename TypeOut, typename TypeIn, typename Converter =boost::cnv::by_default>
+ struct delayed_resolution
+ {
+ static optional<TypeOut> convert(TypeIn const& value_in)
+ {
+ return boost::convert<TypeOut>(value_in, Converter());
+ }
+ };
+ }}
+ /// @brief Boost.Convert deployment interface with the default converter
+ /// @details For example,
+ /// @code
+ /// struct boost::cnv::by_default : public boost::cnv::cstream {};
+ ///
+ /// // boost::cnv::cstream (through boost::cnv::by_default) is deployed
+ /// // as the default converter when no converter is provided explicitly.
+ /// boost::optional<int> i = boost::convert<int>("12");
+ /// boost::optional<string> s = boost::convert<string>(123.456);
+ /// @endcode
+
+ template<typename TypeOut, typename TypeIn>
+ boost::optional<TypeOut>
+ convert(TypeIn const& value_in)
+ {
+ return cnv::detail::delayed_resolution<TypeOut, TypeIn>::convert(value_in);
+ }
+}
+
+namespace boost
+{
+ /// @brief Boost.Convert non-optional deployment interface
+
+ template<typename TypeOut, typename TypeIn, typename Converter>
+ TypeOut
+ convert(TypeIn const& value_in, Converter const& converter, boost::detail::throw_on_failure)
+ {
+ return convert<TypeOut>(value_in, converter).value();
+ }
+
+ template<typename TypeOut, typename TypeIn, typename Converter, typename Fallback>
+ typename enable_if<is_convertible<Fallback, TypeOut>, TypeOut>::type
+ convert(TypeIn const& value_in, Converter const& converter, Fallback const& fallback)
+ {
+ return convert<TypeOut>(value_in, converter).value_or(fallback);
+ }
+
+ template<typename TypeOut, typename TypeIn, typename Converter, typename Fallback>
+ typename enable_if<cnv::is_fun<Fallback, TypeOut>, TypeOut>::type
+ convert(TypeIn const& value_in, Converter const& converter, Fallback fallback)
+ {
+ return convert<TypeOut>(value_in, converter).value_or_eval(fallback);
+ }
+}
+
+namespace boost { namespace cnv
+{
+ template<typename Converter, typename TypeOut, typename TypeIn>
+ struct reference
+ {
+ typedef reference this_type;
+
+ reference(Converter const& cnv) : converter_(cnv) {}
+
+#ifdef BOOST_CONVERT_CXX11
+ reference(Converter&& cnv) : converter_(std::move(cnv)) {}
+#endif
+
+ this_type&
+ value_or(TypeOut const& fallback)
+ {
+ return (fallback_ = fallback, *this);
+ }
+
+ TypeOut
+ operator()(TypeIn const& value_in)
+ {
+ optional<TypeOut> result = convert<TypeOut>(value_in, converter_);
+ return result ? result.get() : fallback_.value();
+ }
+
+ private:
+
+ Converter converter_;
+ optional<TypeOut> fallback_;
+ };
+ template<typename Converter, typename TypeOut>
+ struct reference<Converter, TypeOut, void>
+ {
+ typedef reference this_type;
+
+ reference(Converter const& cnv) : converter_(cnv) {}
+
+#ifdef BOOST_CONVERT_CXX11
+ reference(Converter&& cnv) : converter_(std::move(cnv)) {}
+#endif
+
+ this_type&
+ value_or(TypeOut const& fallback)
+ {
+ return (fallback_ = fallback, *this);
+ }
+
+ template<typename TypeIn>
+ TypeOut
+ operator()(TypeIn const& value_in)
+ {
+ optional<TypeOut> result = convert<TypeOut>(value_in, converter_);
+ return result ? result.get() : fallback_.value();
+ }
+
+ private:
+
+ Converter converter_;
+ optional<TypeOut> fallback_;
+ };
+
+ /// @brief Boost.Convert deployment interface with algorithms
+ /// @details For example,
+ /// @code
+ /// boost::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
+ /// std::vector<int> ints;
+ /// boost::cnv::cstream cnv;
+ ///
+ /// cnv(std::hex)(std::skipws);
+ ///
+ /// std::transform(
+ /// strs.begin(),
+ /// strs.end(),
+ /// std::back_inserter(ints),
+ /// boost::cnv::apply<int>(boost::cref(cnv)).value_or(-1));
+ /// @endcode
+
+ template<typename TypeOut, typename TypeIn, typename Converter>
+ reference<Converter, TypeOut, TypeIn>
+ apply(Converter const& cnv)
+ {
+ return cnv::reference<Converter, TypeOut, TypeIn>(cnv);
+ }
+ template<typename TypeOut, typename Converter>
+ reference<Converter, TypeOut, void>
+ apply(Converter const& cnv)
+ {
+ return cnv::reference<Converter, TypeOut, void>(cnv);
+ }
+}}
+
+#endif // BOOST_CONVERT_HPP
diff --git a/boost/convert/base.hpp b/boost/convert/base.hpp
new file mode 100644
index 0000000000..128c46f3a5
--- /dev/null
+++ b/boost/convert/base.hpp
@@ -0,0 +1,180 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_CONVERTER_BASE_HPP
+#define BOOST_CONVERT_CONVERTER_BASE_HPP
+
+#include <boost/convert/parameters.hpp>
+#include <boost/convert/detail/is_string.hpp>
+#include <cctype>
+#include <cstring>
+
+namespace boost { namespace cnv
+{
+ namespace ARG = boost::cnv::parameter;
+
+ template<typename> struct cnvbase;
+}}
+
+#define BOOST_CNV_TO_STRING \
+ template<typename string_type> \
+ typename boost::enable_if<cnv::is_string<string_type>, void>::type \
+ operator()
+
+#define BOOST_CNV_STRING_TO \
+ template<typename string_type> \
+ typename boost::enable_if<cnv::is_string<string_type>, void>::type \
+ operator()
+
+#define BOOST_CNV_PARAM(param_name, param_type) \
+ derived_type& operator()(boost::parameter::aux::tag<ARG::type::param_name, param_type>::type const& arg)
+
+template<typename derived_type>
+struct boost::cnv::cnvbase
+{
+ typedef cnvbase this_type;
+ typedef int int_type;
+ typedef unsigned int uint_type;
+ typedef long int lint_type;
+ typedef unsigned long int ulint_type;
+ typedef short int sint_type;
+ typedef unsigned short int usint_type;
+ typedef long long int llint_type;
+ typedef unsigned long long int ullint_type;
+ typedef float flt_type;
+ typedef double dbl_type;
+ typedef long double ldbl_type;
+
+ // Integration of user-types via operator>>()
+ template<typename type_in, typename type_out>
+ void
+ operator()(type_in const& in, boost::optional<type_out>& out) const
+ {
+ in >> out;
+ }
+
+ // Basic type to string
+ BOOST_CNV_TO_STRING ( int_type v, optional<string_type>& r) const { to_str_(v, r); }
+ BOOST_CNV_TO_STRING ( uint_type v, optional<string_type>& r) const { to_str_(v, r); }
+ BOOST_CNV_TO_STRING ( lint_type v, optional<string_type>& r) const { to_str_(v, r); }
+ BOOST_CNV_TO_STRING (ulint_type v, optional<string_type>& r) const { to_str_(v, r); }
+ BOOST_CNV_TO_STRING ( sint_type v, optional<string_type>& r) const { to_str_(v, r); }
+ BOOST_CNV_TO_STRING (usint_type v, optional<string_type>& r) const { to_str_(v, r); }
+ BOOST_CNV_TO_STRING ( flt_type v, optional<string_type>& r) const { to_str_(v, r); }
+ BOOST_CNV_TO_STRING ( dbl_type v, optional<string_type>& r) const { to_str_(v, r); }
+ BOOST_CNV_TO_STRING ( ldbl_type v, optional<string_type>& r) const { to_str_(v, r); }
+ // String to basic type
+ BOOST_CNV_STRING_TO (string_type const& s, optional< int_type>& r) const { str_to_(s, r); }
+ BOOST_CNV_STRING_TO (string_type const& s, optional< uint_type>& r) const { str_to_(s, r); }
+ BOOST_CNV_STRING_TO (string_type const& s, optional< lint_type>& r) const { str_to_(s, r); }
+ BOOST_CNV_STRING_TO (string_type const& s, optional<ulint_type>& r) const { str_to_(s, r); }
+ BOOST_CNV_STRING_TO (string_type const& s, optional< sint_type>& r) const { str_to_(s, r); }
+ BOOST_CNV_STRING_TO (string_type const& s, optional<usint_type>& r) const { str_to_(s, r); }
+ BOOST_CNV_STRING_TO (string_type const& s, optional< flt_type>& r) const { str_to_(s, r); }
+ BOOST_CNV_STRING_TO (string_type const& s, optional< dbl_type>& r) const { str_to_(s, r); }
+ BOOST_CNV_STRING_TO (string_type const& s, optional< ldbl_type>& r) const { str_to_(s, r); }
+ // Formatters
+// BOOST_CNV_PARAM (locale, std::locale const) { locale_ = arg[ARG:: locale]; return dncast(); }
+ BOOST_CNV_PARAM (base, base::type const) { base_ = arg[ARG:: base]; return dncast(); }
+ BOOST_CNV_PARAM (adjust, adjust::type const) { adjust_ = arg[ARG:: adjust]; return dncast(); }
+ BOOST_CNV_PARAM (precision, int const) { precision_ = arg[ARG::precision]; return dncast(); }
+ BOOST_CNV_PARAM (precision, int) { precision_ = arg[ARG::precision]; return dncast(); }
+ BOOST_CNV_PARAM (uppercase, bool const) { uppercase_ = arg[ARG::uppercase]; return dncast(); }
+ BOOST_CNV_PARAM (skipws, bool const) { skipws_ = arg[ARG:: skipws]; return dncast(); }
+ BOOST_CNV_PARAM (width, int const) { width_ = arg[ARG:: width]; return dncast(); }
+ BOOST_CNV_PARAM (fill, char const) { fill_ = arg[ARG:: fill]; return dncast(); }
+
+ protected:
+
+ cnvbase()
+ :
+ base_ (10),
+ skipws_ (false),
+ precision_ (0),
+ uppercase_ (false),
+ width_ (0),
+ fill_ (' '),
+ adjust_ (boost::cnv::adjust::right)
+ {}
+
+ template<typename string_type, typename out_type>
+ void
+ str_to_(string_type const& str, optional<out_type>& result_out) const
+ {
+ cnv::range<string_type const> range (str);
+
+ /**/ if (skipws_) for (; std::isspace(*range.begin()); ++range);
+ else if (std::isspace(*range.begin())) return;
+
+ dncast().str_to(range, result_out);
+ }
+ template<typename in_type, typename string_type>
+ void
+ to_str_(in_type value_in, optional<string_type>& result_out) const
+ {
+ typedef typename cnv::range<string_type>::value_type char_type;
+
+ char_type buf[bufsize_];
+ cnv::range<char_type*> range = dncast().to_str(value_in, buf);
+ char_type* beg = range.begin();
+ char_type* end = range.end();
+
+ if (beg < end)
+ {
+ format_(buf, beg, end);
+
+ result_out = string_type(beg, end);
+ }
+ }
+
+ template<typename char_type>
+ void
+ format_(char_type* buf, char_type*& beg, char_type*& end) const
+ {
+ if (uppercase_)
+ {
+ for (char_type* p = beg; p < end; ++p) *p = std::toupper(*p);
+ }
+ if (width_)
+ {
+ int const num_fillers = (std::max)(0, int(width_ - (end - beg)));
+ int const num_left = adjust_ == boost::cnv::adjust::left ? 0
+ : adjust_ == boost::cnv::adjust::right ? num_fillers
+ : (num_fillers / 2);
+ int const num_right = num_fillers - num_left;
+ int const str_size = end - beg;
+ bool const move = (beg < buf + num_left) // No room for left fillers
+ || (buf + bufsize_ < end + num_right); // No room for right fillers
+ if (move)
+ {
+ std::memmove(buf + num_left, beg, str_size * sizeof(char_type));
+ beg = buf + num_left;
+ end = beg + str_size;
+ }
+ for (int k = 0; k < num_left; *(--beg) = fill_, ++k);
+ for (int k = 0; k < num_right; *(end++) = fill_, ++k);
+ }
+ }
+
+ derived_type const& dncast () const { return *static_cast<derived_type const*>(this); }
+ derived_type& dncast () { return *static_cast<derived_type*>(this); }
+
+ // ULONG_MAX(8 bytes) = 18446744073709551615 (20(10) or 32(2) characters)
+ // double (8 bytes) max is 316 chars
+ static int const bufsize_ = 1024;
+ int base_;
+ bool skipws_;
+ int precision_;
+ bool uppercase_;
+ int width_;
+ int fill_;
+ adjust::type adjust_;
+// std::locale locale_;
+};
+
+#undef BOOST_CNV_TO_STRING
+#undef BOOST_CNV_STRING_TO
+#undef BOOST_CNV_PARAM
+
+#endif // BOOST_CONVERT_CONVERTER_BASE_HPP
diff --git a/boost/convert/detail/boost_parameter_ext.hpp b/boost/convert/detail/boost_parameter_ext.hpp
new file mode 100644
index 0000000000..a384018cfb
--- /dev/null
+++ b/boost/convert/detail/boost_parameter_ext.hpp
@@ -0,0 +1,62 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_PARAMETER_EXT_PRIVATE_HPP
+#define BOOST_PARAMETER_EXT_PRIVATE_HPP
+
+#include <boost/parameter/keyword.hpp>
+
+// A Boost.Parameter extension by Andrey Semashev.
+// This should really go to Boost.Parameter in the end.
+
+namespace boost { namespace parameter {
+
+// The metafunction, given the type of the arguments pack and the keyword tag,
+// returns the corresponding parameter type
+template< typename ArgsT, typename KeywordTagT >
+struct parameter_type
+{
+ typedef void type;
+};
+
+template< typename ArgT, typename KeywordTagT >
+struct parameter_type<aux::tagged_argument<KeywordTagT, ArgT>, KeywordTagT>
+{
+ typedef typename aux::tagged_argument< KeywordTagT, ArgT >::value_type type;
+};
+
+template< typename KeywordTagT1, typename ArgT, typename KeywordTagT2 >
+struct parameter_type< aux::tagged_argument< KeywordTagT1, ArgT >, KeywordTagT2 >
+{
+ typedef void type;
+};
+
+template< typename ArgT, typename TailT, typename KeywordTagT >
+struct parameter_type<
+ aux::arg_list<
+ aux::tagged_argument< KeywordTagT, ArgT >,
+ TailT
+ >,
+ KeywordTagT
+>
+{
+ typedef typename aux::tagged_argument< KeywordTagT, ArgT >::value_type type;
+};
+
+template< typename KeywordTagT1, typename ArgT, typename TailT, typename KeywordTagT2 >
+struct parameter_type<
+ aux::arg_list<
+ aux::tagged_argument< KeywordTagT1, ArgT >,
+ TailT
+ >,
+ KeywordTagT2
+> :
+ public parameter_type< TailT, KeywordTagT2 >
+{
+};
+
+}} // boost::parameter
+
+#endif // BOOST_PARAMETER_EXT_PRIVATE_HPP
+
diff --git a/boost/convert/detail/char.hpp b/boost/convert/detail/char.hpp
new file mode 100644
index 0000000000..5b3cbda10e
--- /dev/null
+++ b/boost/convert/detail/char.hpp
@@ -0,0 +1,23 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_DETAIL_IS_CHAR_HPP
+#define BOOST_CONVERT_DETAIL_IS_CHAR_HPP
+
+#include <boost/mpl/bool.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+namespace boost { namespace cnv
+{
+ namespace detail
+ {
+ template<typename T> struct is_char : mpl::false_ {};
+ template<> struct is_char<char> : mpl:: true_ {};
+ template<> struct is_char<wchar_t> : mpl:: true_ {};
+ }
+ template <typename T> struct is_char : detail::is_char<typename remove_const<T>::type> {};
+}}
+
+#endif // BOOST_CONVERT_DETAIL_IS_CHAR_HPP
+
diff --git a/boost/convert/detail/forward.hpp b/boost/convert/detail/forward.hpp
new file mode 100644
index 0000000000..5548aec3fe
--- /dev/null
+++ b/boost/convert/detail/forward.hpp
@@ -0,0 +1,39 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_FORWARD_HPP
+#define BOOST_CONVERT_FORWARD_HPP
+
+#if defined(_MSC_VER)
+# pragma warning(disable: 4244)
+# pragma warning(disable: 4224)
+# pragma warning(disable: 4996)
+# pragma warning(disable: 4180) // qualifier applied to function type has no meaning
+# pragma warning(disable: 4100) // unreferenced formal parameter
+
+#if _MSC_VER < 1900 /* MSVC-14 defines real snprintf()... just about time! */
+# define snprintf _snprintf
+#endif
+
+#endif
+
+#include <boost/config.hpp>
+#include <boost/version.hpp>
+#include <boost/optional.hpp>
+
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#undef BOOST_CONVERT_CXX11
+#else
+#define BOOST_CONVERT_CXX11
+#endif
+
+#if defined(BOOST_INTEL) && (BOOST_INTEL <= 1200) /* Intel 12.0 and lower have broken SFINAE */
+# define BOOST_CONVERT_INTEL_SFINAE_BROKEN
+#endif
+
+#if defined(BOOST_MSVC) && (BOOST_MSVC < 1800) /* MSVC-11 and lower have broken SFINAE */
+# define BOOST_CONVERT_MSVC_SFINAE_BROKEN
+#endif
+
+#endif // BOOST_CONVERT_FORWARD_HPP
diff --git a/boost/convert/detail/has_member.hpp b/boost/convert/detail/has_member.hpp
new file mode 100644
index 0000000000..fafc39f5c4
--- /dev/null
+++ b/boost/convert/detail/has_member.hpp
@@ -0,0 +1,61 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_HAS_MEMBER_HPP
+#define BOOST_CONVERT_HAS_MEMBER_HPP
+
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/detail/yes_no_type.hpp>
+
+// This macro allows to check if a type has a member named "__member_name__"...
+// ... regardless of the signature. If takes advantage of the following behavior related to
+// function resolution. Say, both, foo and base, declare a method with the same name "func":
+//
+// struct foo { int func (int, int) { return 0; } };
+// struct base { void func () {} };
+// struct mixin : public foo, public base {};
+//
+// Now, if we inherit from both -- foo and base -- classes, then the following calls will fail
+// mixin_ptr(0)->func();
+// mixin_ptr(0)->func(5, 5);
+// with the error message (gcc): request for member func is ambiguous
+// regardless if we provide any arguments or not even though one might expect that
+// arg-based signature resolution might kick in. The only way to deploy those methods is:
+//
+// mixin_ptr(0)->foo::func();
+// mixin_ptr(0)->base::func(5, 5);
+//
+// C2. The actual signature of __member_name__ is not taken into account. If
+// __T__::__member_name__(any-signature) exists, then the introduced base::__member_name__
+// will cause mixin->__member_name__() call to fail to compile (due to ambiguity).
+// C3. &U::__member_name__ (a.k.a. &mixin::__member_name__)
+// has the type of func_type only if __T__::__member_name__ does not exist.
+// If __T__::member_name does exist, then mixin::__member_name__ is ambiguous
+// and "yes_type test (...)" kicks in instead.
+// C4. Need to find some unique/ugly name so that it does not clash if this macro is
+// used inside some other template class;
+
+#define BOOST_DECLARE_HAS_MEMBER(__trait_name__, __member_name__) \
+ \
+ template <typename __boost_has_member_T__> /*C4*/ \
+ class __trait_name__ \
+ { \
+ typedef typename ::boost::remove_const<__boost_has_member_T__>::type check_type; \
+ typedef ::boost::type_traits::yes_type yes_type; \
+ typedef ::boost::type_traits:: no_type no_type; \
+ \
+ struct base { void __member_name__(/*C2*/) {}}; \
+ struct mixin : public base, public check_type {}; \
+ \
+ template <void (base::*)()> struct aux {}; \
+ \
+ template <typename U> static no_type test(aux<&U::__member_name__>*); /*C3*/ \
+ template <typename U> static yes_type test(...); \
+ \
+ public: \
+ \
+ BOOST_STATIC_CONSTANT(bool, value = (sizeof(yes_type) == sizeof(test<mixin>(0)))); \
+ }
+
+#endif // BOOST_CONVERT_HAS_MEMBER_HPP
diff --git a/boost/convert/detail/is_callable.hpp b/boost/convert/detail/is_callable.hpp
new file mode 100644
index 0000000000..d516fdc05b
--- /dev/null
+++ b/boost/convert/detail/is_callable.hpp
@@ -0,0 +1,100 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_IS_CALLABLE_HPP
+#define BOOST_CONVERT_IS_CALLABLE_HPP
+
+#include <boost/convert/detail/has_member.hpp>
+
+namespace boost { namespace cnv { namespace detail
+{
+ typedef ::boost::type_traits::yes_type yes_type;
+ typedef ::boost::type_traits:: no_type no_type;
+
+ struct not_found {};
+ struct void_return_substitute {};
+
+ // The overloaded comma operator only kicks in for U != void essentially short-circuiting
+ // itself ineffective. Otherwise, when U=void, the standard op,() kicks in and returns
+ // 'void_return_substitute'.
+ template<typename U> U const& operator, (U const&, void_return_substitute);
+ template<typename U> U& operator, (U&, void_return_substitute);
+
+ template <typename src, typename dst> struct match_const { typedef dst type; };
+ template <typename src, typename dst> struct match_const<src const, dst> { typedef dst const type; };
+
+ template<typename T, typename return_type>
+ struct redirect
+ {
+ static no_type test (...);
+ static yes_type test (return_type);
+ };
+
+ template<typename T>
+ struct redirect<T, void>
+ {
+ static yes_type test (...);
+ static no_type test (not_found);
+ };
+}}}
+
+// No-args case needs to be implemented differently and has not been implemented yet.
+// template <typename R>
+// struct check<true, R ()>
+
+// C1. Need to find some unique/ugly names so that they do not clash if this macro is
+// used inside some other template class;
+// C2. Body of the function is not actually used anywhere.
+// However, Intel C++ compiler treats it as an error. So, we provide the body.
+
+#define BOOST_DECLARE_IS_CALLABLE(__trait_name__, __member_name__) \
+ \
+template <typename __boost_is_callable_T__, typename __boost_is_callable_signature__> \
+class __trait_name__ \
+{ \
+ typedef __boost_is_callable_T__ class_type; /*C1*/ \
+ typedef __boost_is_callable_signature__ signature; /*C1*/ \
+ typedef boost::cnv::detail::not_found not_found; \
+ \
+ BOOST_DECLARE_HAS_MEMBER(has_member, __member_name__); \
+ \
+ struct mixin : public class_type \
+ { \
+ using class_type::__member_name__; \
+ not_found __member_name__(...) const { return not_found(); /*C2*/} \
+ }; \
+ \
+ typedef typename boost::cnv::detail::match_const<class_type, mixin>::type* mixin_ptr; \
+ \
+ template <bool has, typename F> struct check { static bool const value = false; }; \
+ \
+ template <typename Arg1, typename R> \
+ struct check<true, R (Arg1)> \
+ { \
+ typedef typename boost::decay<Arg1>::type* a1; \
+ \
+ static bool const value = sizeof(boost::type_traits::yes_type) \
+ == sizeof(boost::cnv::detail::redirect<class_type, R>::test( \
+ (mixin_ptr(0)->__member_name__(*a1(0)), \
+ boost::cnv::detail::void_return_substitute()))); \
+ }; \
+ template <typename Arg1, typename Arg2, typename R> \
+ struct check<true, R (Arg1, Arg2)> \
+ { \
+ typedef typename boost::decay<Arg1>::type* a1; \
+ typedef typename boost::decay<Arg2>::type* a2; \
+ \
+ static bool const value = sizeof(boost::type_traits::yes_type) \
+ == sizeof(boost::cnv::detail::redirect<class_type, R>::test( \
+ (mixin_ptr(0)->__member_name__(*a1(0), *a2(0)), \
+ boost::cnv::detail::void_return_substitute()))); \
+ }; \
+ \
+ public: \
+ \
+ /* Check the existence of __member_name__ first, then the signature. */ \
+ static bool const value = check<has_member<class_type>::value, signature>::value; \
+}
+
+#endif // BOOST_CONVERT_IS_CALLABLE_HPP
diff --git a/boost/convert/detail/is_converter.hpp b/boost/convert/detail/is_converter.hpp
new file mode 100644
index 0000000000..b35470cd19
--- /dev/null
+++ b/boost/convert/detail/is_converter.hpp
@@ -0,0 +1,47 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_IS_CONVERTER_HPP
+#define BOOST_CONVERT_IS_CONVERTER_HPP
+
+#include <boost/convert/detail/forward.hpp>
+#include <boost/convert/detail/is_callable.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/ref.hpp>
+
+namespace boost { namespace cnv
+{
+ template<typename, typename, typename, typename =void>
+ struct is_cnv { BOOST_STATIC_CONSTANT(bool, value = false); };
+
+ template<typename Class, typename TypeIn, typename TypeOut>
+ struct is_cnv<Class, TypeIn, TypeOut, typename enable_if<is_class<Class>, void>::type>
+ {
+ typedef typename ::boost::unwrap_reference<Class>::type class_type;
+ typedef void signature_type(TypeIn const&, optional<TypeOut>&);
+
+ BOOST_DECLARE_IS_CALLABLE(is_callable, operator());
+
+ BOOST_STATIC_CONSTANT(bool, value = (is_callable<class_type, signature_type>::value));
+ };
+
+ template<typename Function, typename TypeIn, typename TypeOut>
+ struct is_cnv<Function, TypeIn, TypeOut,
+ typename enable_if_c<is_function<Function>::value && function_types::function_arity<Function>::value == 2,
+ void>::type>
+ {
+ typedef TypeIn in_type;
+ typedef optional<TypeOut>& out_type;
+ typedef typename function_traits<Function>::arg1_type func_in_type;
+ typedef typename function_traits<Function>::arg2_type func_out_type;
+
+ BOOST_STATIC_CONSTANT(bool, in_good = (is_convertible<in_type, func_in_type>::value));
+ BOOST_STATIC_CONSTANT(bool, out_good = (is_same<out_type, func_out_type>::value));
+ BOOST_STATIC_CONSTANT(bool, value = (in_good && out_good));
+ };
+}}
+
+#endif // BOOST_CONVERT_IS_CONVERTER_HPP
+
diff --git a/boost/convert/detail/is_fun.hpp b/boost/convert/detail/is_fun.hpp
new file mode 100644
index 0000000000..5e1eae2ca6
--- /dev/null
+++ b/boost/convert/detail/is_fun.hpp
@@ -0,0 +1,61 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_IS_FUNCTION_HPP
+#define BOOST_CONVERT_IS_FUNCTION_HPP
+
+#include <boost/convert/detail/forward.hpp>
+#include <boost/convert/detail/has_member.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/function_types/is_function_pointer.hpp>
+#include <boost/function_types/function_arity.hpp>
+#include <boost/function_types/result_type.hpp>
+
+namespace boost { namespace cnv
+{
+ typedef ::boost::type_traits::yes_type yes_type;
+ typedef ::boost::type_traits:: no_type no_type;
+
+ template <bool has_operator, typename Functor, typename TypeOut>
+ struct check_functor { BOOST_STATIC_CONSTANT(bool, value = false); };
+
+ template<typename Func, typename TypeOut, class Enable =void>
+ struct is_fun { BOOST_STATIC_CONSTANT(bool, value = false); };
+
+ template <typename Functor, typename TypeOut>
+ struct check_functor<true, Functor, TypeOut>
+ {
+ static yes_type test (TypeOut const&);
+ static no_type test (...);
+
+ static const bool value = sizeof(yes_type) == sizeof(test(((Functor*) 0)->operator()()));
+ };
+
+ template<typename Functor, typename TypeOut>
+ struct is_fun<Functor, TypeOut,
+ typename enable_if_c<is_class<Functor>::value && !is_convertible<Functor, TypeOut>::value, void>::type>
+ {
+ BOOST_DECLARE_HAS_MEMBER(has_funop, operator());
+
+ BOOST_STATIC_CONSTANT(bool, value = (check_functor<has_funop<Functor>::value, Functor, TypeOut>::value));
+ };
+
+ template<typename Function, typename TypeOut>
+ struct is_fun<Function, TypeOut,
+ typename enable_if_c<
+ function_types::is_function_pointer<Function>::value &&
+ function_types::function_arity<Function>::value == 0 &&
+ !is_same<Function, TypeOut>::value,
+ void>::type>
+ {
+ typedef TypeOut out_type;
+ typedef typename function_types::result_type<Function>::type func_out_type;
+
+ BOOST_STATIC_CONSTANT(bool, value = (is_convertible<func_out_type, out_type>::value));
+ };
+}}
+
+#endif // BOOST_CONVERT_IS_FUNCTION_HPP
+
diff --git a/boost/convert/detail/is_string.hpp b/boost/convert/detail/is_string.hpp
new file mode 100644
index 0000000000..ab682b0c72
--- /dev/null
+++ b/boost/convert/detail/is_string.hpp
@@ -0,0 +1,34 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_DETAIL_IS_STRING_HPP
+#define BOOST_CONVERT_DETAIL_IS_STRING_HPP
+
+#include <boost/convert/detail/range.hpp>
+
+namespace boost { namespace cnv
+{
+ namespace detail
+ {
+ template<typename T, bool is_range_class> struct is_string : mpl::false_ {};
+
+ template<typename T> struct is_string<T*, false>
+ {
+ static bool const value = cnv::is_char<T>::value;
+ };
+ template <typename T, std::size_t N> struct is_string<T [N], false>
+ {
+ static bool const value = cnv::is_char<T>::value;
+ };
+ template<typename T> struct is_string<T, /*is_range_class=*/true>
+ {
+ static bool const value = cnv::is_char<typename T::value_type>::value;
+ };
+ }
+ template<typename T> struct is_string : detail::is_string<
+ typename remove_const<T>::type,
+ boost::is_class<T>::value && boost::cnv::is_range<T>::value> {};
+}}
+
+#endif // BOOST_CONVERT_DETAIL_IS_STRING_HPP
diff --git a/boost/convert/detail/range.hpp b/boost/convert/detail/range.hpp
new file mode 100644
index 0000000000..439fbf48d0
--- /dev/null
+++ b/boost/convert/detail/range.hpp
@@ -0,0 +1,112 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_DETAIL_RANGE_HPP
+#define BOOST_CONVERT_DETAIL_RANGE_HPP
+
+#include <boost/convert/detail/has_member.hpp>
+#include <boost/convert/detail/char.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/range/iterator.hpp>
+
+namespace boost { namespace cnv
+{
+ namespace detail
+ {
+ template<typename T, bool is_class> struct is_range : mpl::false_ {};
+
+ template<typename T> struct is_range<T, /*is_class=*/true>
+ {
+ BOOST_DECLARE_HAS_MEMBER(has_begin, begin);
+ BOOST_DECLARE_HAS_MEMBER( has_end, end);
+
+ static bool const value = has_begin<T>::value && has_end<T>::value;
+ };
+ }
+ template<typename T> struct is_range : detail::is_range<typename remove_const<T>::type, boost::is_class<T>::value> {};
+ template<typename T, typename enable =void> struct range;
+ template<typename T, typename enable =void> struct iterator;
+
+ template<typename T>
+ struct iterator<T, typename enable_if<is_range<T> >::type>
+ {
+ typedef typename boost::range_iterator<T>::type type;
+ typedef typename boost::range_iterator<T const>::type const_type;
+ typedef typename boost::iterator_value<type>::type value_type;
+ };
+ template<typename T>
+ struct iterator<T*, void>
+ {
+ typedef typename remove_const<T>::type value_type;
+ typedef T* type;
+ typedef value_type const* const_type;
+ };
+ template<typename T>
+ struct range_base
+ {
+ typedef typename cnv::iterator<T>::value_type value_type;
+ typedef typename cnv::iterator<T>::type iterator;
+ typedef typename cnv::iterator<T>::const_type const_iterator;
+ typedef const_iterator sentry_type;
+
+ range_base (iterator b, iterator e) : begin_(b), end_(e) {}
+
+ iterator begin () { return begin_; }
+ iterator end () { return end_; }
+ const_iterator begin () const { return begin_; }
+ const_iterator end () const { return end_; }
+ sentry_type sentry () const { return end_; }
+ void operator++ () { ++begin_; }
+ void operator-- () { --end_; }
+
+ protected:
+
+ iterator begin_;
+ mutable iterator end_;
+ };
+
+ template<typename T>
+ struct range<T, typename enable_if<is_range<T> >::type> : public range_base<T>
+ {
+ typedef range this_type;
+ typedef range_base<T> base_type;
+
+ range (T& r) : base_type(r.begin(), r.end()) {}
+ };
+
+ template<typename T>
+ struct range<T*, typename enable_if<cnv::is_char<T> >::type> : public range_base<T*>
+ {
+ typedef range this_type;
+ typedef range_base<T*> base_type;
+
+ typedef typename remove_const<T>::type value_type;
+ typedef T* iterator;
+ typedef value_type const* const_iterator;
+
+ struct sentry_type
+ {
+ friend bool operator!=(iterator it, sentry_type) { return !!*it; }
+ };
+
+ range (iterator b, iterator e =0) : base_type(b, e) {}
+
+ iterator end () { return base_type::end_ ? base_type::end_ : (base_type::end_ = base_type::begin_ + size()); }
+ const_iterator end () const { return base_type::end_ ? base_type::end_ : (base_type::end_ = base_type::begin_ + size()); }
+ sentry_type sentry () const { return sentry_type(); }
+ std::size_t size () const { return std::char_traits<value_type>::length(base_type::begin_); }
+ };
+ template<typename T>
+ struct range<T* const, void> : public range<T*>
+ {
+ range (T* b, T* e =0) : range<T*>(b, e) {}
+ };
+ template <typename T, std::size_t N>
+ struct range<T [N], void> : public range<T*>
+ {
+ range (T* b, T* e =0) : range<T*>(b, e) {}
+ };
+}}
+
+#endif // BOOST_CONVERT_DETAIL_RANGE_HPP
diff --git a/boost/convert/lexical_cast.hpp b/boost/convert/lexical_cast.hpp
new file mode 100644
index 0000000000..5a9f77b845
--- /dev/null
+++ b/boost/convert/lexical_cast.hpp
@@ -0,0 +1,40 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_LEXICAL_CAST_HPP
+#define BOOST_CONVERT_LEXICAL_CAST_HPP
+
+#include <boost/lexical_cast.hpp>
+
+namespace boost { namespace cnv
+{
+ struct lexical_cast;
+}}
+
+/// @brief boost::lexical_cast-based converter
+/// @details The purpose of the converter is to
+/// * Make use of the boost::lexical_cast functionality and performance that many people have become
+/// accustomed to and comfortable with;
+/// * Demonstrate how existing independent conversion/transformation-related facilities might be
+// incorporated in to the Boost.Convert framework.
+///
+/// The converter can easily replace boost::lexical_cast, adding flexibility and convenience.
+
+struct boost::cnv::lexical_cast
+{
+ template<typename TypeOut, typename TypeIn>
+ void
+ operator()(TypeIn const& value_in, boost::optional<TypeOut>& result_out) const
+ {
+ try
+ {
+ result_out = boost::lexical_cast<TypeOut>(value_in);
+ }
+ catch (boost::bad_lexical_cast const&)
+ {
+ }
+ }
+};
+
+#endif // BOOST_CONVERT_LEXICAL_CAST_HPP
diff --git a/boost/convert/parameters.hpp b/boost/convert/parameters.hpp
new file mode 100644
index 0000000000..ae5511bfae
--- /dev/null
+++ b/boost/convert/parameters.hpp
@@ -0,0 +1,33 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_PARAMETERS_HPP
+#define BOOST_CONVERT_PARAMETERS_HPP
+
+#include <boost/convert/detail/boost_parameter_ext.hpp>
+
+namespace boost
+{
+ namespace cnv
+ {
+ struct adjust { enum type { left, right, center };};
+ struct base { enum type { bin =2, dec =10, hex =16, oct =8 };};
+ struct notation { enum type { fixed, scientific };};
+
+ namespace parameter
+ {
+ BOOST_PARAMETER_KEYWORD(type, adjust)
+ BOOST_PARAMETER_KEYWORD(type, base)
+ BOOST_PARAMETER_KEYWORD(type, fill)
+ BOOST_PARAMETER_KEYWORD(type, locale)
+ BOOST_PARAMETER_KEYWORD(type, notation)
+ BOOST_PARAMETER_KEYWORD(type, precision)
+ BOOST_PARAMETER_KEYWORD(type, skipws)
+ BOOST_PARAMETER_KEYWORD(type, uppercase)
+ BOOST_PARAMETER_KEYWORD(type, width)
+ }
+ }
+}
+
+#endif // BOOST_CONVERT_PARAMETERS_HPP
diff --git a/boost/convert/printf.hpp b/boost/convert/printf.hpp
new file mode 100644
index 0000000000..d33b873d05
--- /dev/null
+++ b/boost/convert/printf.hpp
@@ -0,0 +1,89 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_PRINTF_HPP
+#define BOOST_CONVERT_PRINTF_HPP
+
+#include <boost/convert/base.hpp>
+#include <boost/make_default.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/find.hpp>
+#include <boost/range/as_literal.hpp>
+#include <string>
+#include <cstdio>
+
+namespace boost { namespace cnv
+{
+ struct printf;
+}}
+
+struct boost::cnv::printf : public boost::cnv::cnvbase<boost::cnv::printf>
+{
+ typedef boost::cnv::printf this_type;
+ typedef boost::cnv::cnvbase<this_type> base_type;
+
+ using base_type::operator();
+
+ template<typename in_type>
+ cnv::range<char*>
+ to_str(in_type value_in, char* buf) const
+ {
+ char const* fmt = pformat(pos<in_type>());
+ int const num_chars = snprintf(buf, bufsize_, fmt, precision_, value_in);
+ bool const success = num_chars < bufsize_;
+
+ return cnv::range<char*>(buf, success ? (buf + num_chars) : buf);
+ }
+ template<typename string_type, typename out_type>
+ void
+ str_to(cnv::range<string_type> range, optional<out_type>& result_out) const
+ {
+ out_type result = boost::make_default<out_type>();
+ int const num_read = sscanf(&*range.begin(), format(pos<out_type>()), &result);
+
+ if (num_read == 1)
+ result_out = result;
+ }
+
+ private:
+
+ template<typename Type> int pos() const
+ {
+ typedef boost::mpl::vector<double, float,
+ int, unsigned int,
+ short int, unsigned short int,
+ long int, unsigned long int
+ > managed_types;
+
+ typedef typename boost::mpl::find<managed_types, Type>::type type_iterator;
+ typedef typename type_iterator::pos type_pos;
+
+ return type_pos::value;
+ }
+
+ char const* pformat(int pos) const
+ {
+ static char const* d_format[] = { "%.*f", "%.*f", "%.*d", "%.*u", "%.*hd", "%.*hu", "%.*ld", "%.*lu" }; // Must match managed_types
+ static char const* x_format[] = { "%.*f", "%.*f", "%.*x", "%.*x", "%.*hx", "%.*hx", "%.*lx", "%.*lx" }; // Must match managed_types
+ static char const* o_format[] = { "%.*f", "%.*f", "%.*o", "%.*o", "%.*ho", "%.*ho", "%.*lo", "%.*lo" }; // Must match managed_types
+ char const* format = base_ == 10 ? d_format[pos]
+ : base_ == 16 ? x_format[pos]
+ : base_ == 8 ? o_format[pos]
+ : (BOOST_ASSERT(0), (char const*) 0);
+ return format;
+ }
+ char const* format(int pos) const
+ {
+ static char const* d_format[] = { "%f", "%f", "%d", "%u", "%hd", "%hu", "%ld", "%lu" }; // Must match managed_types
+ static char const* x_format[] = { "%f", "%f", "%x", "%x", "%hx", "%hx", "%lx", "%lx" }; // Must match managed_types
+ static char const* o_format[] = { "%f", "%f", "%o", "%o", "%ho", "%ho", "%lo", "%lo" }; // Must match managed_types
+ char const* format = base_ == 10 ? d_format[pos]
+ : base_ == 16 ? x_format[pos]
+ : base_ == 8 ? o_format[pos]
+ : (BOOST_ASSERT(0), (char const*) 0);
+ return format;
+ }
+};
+
+#endif // BOOST_CONVERT_PRINTF_HPP
diff --git a/boost/convert/spirit.hpp b/boost/convert/spirit.hpp
new file mode 100644
index 0000000000..5ef69d3c78
--- /dev/null
+++ b/boost/convert/spirit.hpp
@@ -0,0 +1,54 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_SPIRIT_BASED_CONVERTER_HPP
+#define BOOST_CONVERT_SPIRIT_BASED_CONVERTER_HPP
+
+#include <boost/convert/base.hpp>
+#include <boost/convert/detail/forward.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/karma.hpp>
+
+namespace boost { namespace cnv
+{
+ struct spirit;
+}}
+
+struct boost::cnv::spirit : public boost::cnv::cnvbase<boost::cnv::spirit>
+{
+ typedef boost::cnv::spirit this_type;
+ typedef boost::cnv::cnvbase<this_type> base_type;
+
+ using base_type::operator();
+
+ template<typename string_type, typename out_type>
+ void
+ str_to(cnv::range<string_type> range, optional<out_type>& result_out) const
+ {
+ typedef typename cnv::range<string_type>::iterator iterator;
+ typedef typename boost::spirit::traits::create_parser<out_type>::type parser;
+
+ iterator beg = range.begin();
+ iterator end = range.end();
+ out_type result;
+
+ if (boost::spirit::qi::parse(beg, end, parser(), result))
+ if (beg == end) // ensure the whole string has been parsed
+ result_out = result;
+ }
+ template<typename in_type, typename char_type>
+ cnv::range<char*>
+ to_str(in_type value_in, char_type* beg) const
+ {
+ typedef typename boost::spirit::traits::create_generator<in_type>::type generator;
+
+ char_type* end = beg;
+ bool good = boost::spirit::karma::generate(end, generator(), value_in);
+
+ return cnv::range<char*>(beg, good ? end : beg);
+ }
+};
+
+#endif // BOOST_CONVERT_SPIRIT_BASED_CONVERTER_HPP
+
diff --git a/boost/convert/stream.hpp b/boost/convert/stream.hpp
new file mode 100644
index 0000000000..04f2bccf98
--- /dev/null
+++ b/boost/convert/stream.hpp
@@ -0,0 +1,196 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_STRINGSTREAM_BASED_CONVERTER_HPP
+#define BOOST_CONVERT_STRINGSTREAM_BASED_CONVERTER_HPP
+
+#include <boost/convert/parameters.hpp>
+#include <boost/convert/detail/is_string.hpp>
+#include <boost/make_default.hpp>
+#include <sstream>
+#include <iomanip>
+
+#define BOOST_CNV_STRING_ENABLE \
+ template<typename string_type, typename type> \
+ typename boost::enable_if<cnv::is_string<string_type>, void>::type \
+ operator()
+
+#define BOOST_CNV_PARAM(PARAM_NAME, PARAM_TYPE) \
+ this_type& \
+ operator()(boost::parameter::aux::tag<boost::cnv::parameter::type::PARAM_NAME, PARAM_TYPE>::type const& arg)
+
+namespace boost { namespace cnv
+{
+ template<class Char> struct basic_stream;
+
+ typedef boost::cnv::basic_stream<char> cstream;
+ typedef boost::cnv::basic_stream<wchar_t> wstream;
+}}
+
+template<class Char>
+struct boost::cnv::basic_stream : boost::noncopyable
+{
+ // C01. In string-to-type conversions the "string" must be a CONTIGUOUS ARRAY of
+ // characters because "ibuffer_type" uses/relies on that (it deals with char_type*).
+ // C02. Use the provided "string_in" as the input (read-from) buffer and, consequently,
+ // avoid the overhead associated with stream_.str(string_in) --
+ // copying of the content into internal buffer.
+ // C03. The "strbuf.gptr() != strbuf.egptr()" check replaces "istream.eof() != true"
+ // which for some reason does not work when we try converting the "true" string
+ // to "bool" with std::boolalpha set. Seems that istream state gets unsynced compared
+ // to the actual underlying buffer.
+
+ typedef Char char_type;
+ typedef boost::cnv::basic_stream<char_type> this_type;
+ typedef std::basic_stringstream<char_type> stream_type;
+ typedef std::basic_istream<char_type> istream_type;
+ typedef std::basic_streambuf<char_type> buffer_type;
+ typedef std::basic_string<char_type> stdstr_type;
+ typedef std::ios_base& (*manipulator_type)(std::ios_base&);
+
+ struct ibuffer_type : public buffer_type
+ {
+ using buffer_type::eback;
+ using buffer_type::gptr;
+ using buffer_type::egptr;
+
+ ibuffer_type(char_type const* beg, std::size_t sz) //C01
+ {
+ char_type* b = const_cast<char_type*>(beg);
+
+ buffer_type::setg(b, b, b + sz);
+ }
+ };
+ struct obuffer_type : public buffer_type
+ {
+ using buffer_type::pbase;
+ using buffer_type::pptr;
+ using buffer_type::epptr;
+ };
+
+ basic_stream() : stream_(std::ios_base::in | std::ios_base::out) {}
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+ basic_stream(this_type&& other) : stream_(std::move(other.stream_)) {}
+#endif
+
+ BOOST_CNV_STRING_ENABLE(type const& v, optional<string_type>& s) const { to_str(v, s); }
+ BOOST_CNV_STRING_ENABLE(string_type const& s, optional<type>& r) const { str_to(cnv::range<string_type const>(s), r); }
+ // Resolve ambiguity of string-to-string
+ template<typename type> void operator()( char_type const* s, optional<type>& r) const { str_to(cnv::range< char_type const*>(s), r); }
+ template<typename type> void operator()(stdstr_type const& s, optional<type>& r) const { str_to(cnv::range<stdstr_type const>(s), r); }
+
+ // Formatters
+ template<typename manipulator>
+ this_type& operator() (manipulator m) { return (stream_ << m, *this); }
+ this_type& operator() (manipulator_type m) { return (m(stream_), *this); }
+ this_type& operator() (std::locale const& l) { return (stream_.imbue(l), *this); }
+
+ BOOST_CNV_PARAM(locale, std::locale const) { return (stream_.imbue(arg[cnv::parameter::locale]), *this); }
+ BOOST_CNV_PARAM(precision, int const) { return (stream_.precision(arg[cnv::parameter::precision]), *this); }
+ BOOST_CNV_PARAM(precision, int) { return (stream_.precision(arg[cnv::parameter::precision]), *this); }
+ BOOST_CNV_PARAM(width, int const) { return (stream_.width(arg[cnv::parameter::width]), *this); }
+ BOOST_CNV_PARAM(fill, char const) { return (stream_.fill(arg[cnv::parameter::fill]), *this); }
+ BOOST_CNV_PARAM(uppercase, bool const)
+ {
+ bool uppercase = arg[cnv::parameter::uppercase];
+ uppercase ? (void) stream_.setf(std::ios::uppercase) : stream_.unsetf(std::ios::uppercase);
+ return *this;
+ }
+ BOOST_CNV_PARAM(skipws, bool const)
+ {
+ bool skipws = arg[cnv::parameter::skipws];
+ skipws ? (void) stream_.setf(std::ios::skipws) : stream_.unsetf(std::ios::skipws);
+ return *this;
+ }
+ BOOST_CNV_PARAM(adjust, boost::cnv::adjust::type const)
+ {
+ cnv::adjust::type adjust = arg[cnv::parameter::adjust];
+
+ /**/ if (adjust == cnv::adjust:: left) stream_.setf(std::ios::adjustfield, std::ios:: left);
+ else if (adjust == cnv::adjust::right) stream_.setf(std::ios::adjustfield, std::ios::right);
+ else BOOST_ASSERT(!"Not implemented");
+
+ return *this;
+ }
+ BOOST_CNV_PARAM(base, boost::cnv::base::type const)
+ {
+ cnv::base::type base = arg[cnv::parameter::base];
+
+ /**/ if (base == cnv::base::dec) std::dec(stream_);
+ else if (base == cnv::base::hex) std::hex(stream_);
+ else if (base == cnv::base::oct) std::oct(stream_);
+ else BOOST_ASSERT(!"Not implemented");
+
+ return *this;
+ }
+ BOOST_CNV_PARAM(notation, boost::cnv::notation::type const)
+ {
+ cnv::notation::type notation = arg[cnv::parameter::notation];
+
+ /**/ if (notation == cnv::notation:: fixed) std::fixed(stream_);
+ else if (notation == cnv::notation::scientific) std::scientific(stream_);
+ else BOOST_ASSERT(!"Not implemented");
+
+ return *this;
+ }
+
+ private:
+
+ template<typename string_type, typename out_type> void str_to(cnv::range<string_type>, optional<out_type>&) const;
+ template<typename string_type, typename in_type> void to_str(in_type const&, optional<string_type>&) const;
+
+ mutable stream_type stream_;
+};
+
+template<typename char_type>
+template<typename string_type, typename in_type>
+inline
+void
+boost::cnv::basic_stream<char_type>::to_str(
+ in_type const& value_in,
+ boost::optional<string_type>& string_out) const
+{
+ stream_.clear(); // Clear the flags
+ stream_.str(stdstr_type()); // Clear/empty the content of the stream
+
+ if (!(stream_ << value_in).fail())
+ {
+ buffer_type* buf = stream_.rdbuf();
+ obuffer_type* obuf = static_cast<obuffer_type*>(buf);
+ char_type const* beg = obuf->pbase();
+ char_type const* end = obuf->pptr();
+
+ string_out = string_type(beg, end); // Instead of stream_.str();
+ }
+}
+
+template<typename char_type>
+template<typename string_type, typename out_type>
+inline
+void
+boost::cnv::basic_stream<char_type>::str_to(
+ boost::cnv::range<string_type> string_in,
+ boost::optional<out_type>& result_out) const
+{
+ istream_type& istream = stream_;
+ buffer_type* oldbuf = istream.rdbuf();
+ char_type const* beg = &*string_in.begin();
+ std::size_t sz = string_in.end() - string_in.begin();
+ ibuffer_type newbuf (beg, sz); //C02
+
+ istream.rdbuf(&newbuf);
+ istream.clear(); // Clear the flags
+
+ istream >> *(result_out = boost::make_default<out_type>());
+
+ if (istream.fail() || newbuf.gptr() != newbuf.egptr()/*C03*/)
+ result_out = boost::none;
+
+ istream.rdbuf(oldbuf);
+}
+
+#undef BOOST_CNV_STRING_ENABLE
+#undef BOOST_CNV_PARAM
+
+#endif // BOOST_CONVERT_STRINGSTREAM_BASED_CONVERTER_HPP
diff --git a/boost/convert/strtol.hpp b/boost/convert/strtol.hpp
new file mode 100644
index 0000000000..bc329c6870
--- /dev/null
+++ b/boost/convert/strtol.hpp
@@ -0,0 +1,218 @@
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_STRTOL_CONVERTER_HPP
+#define BOOST_CONVERT_STRTOL_CONVERTER_HPP
+
+#include <boost/convert/base.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/math/special_functions/round.hpp>
+#include <limits>
+#include <cmath>
+#include <cstdlib>
+#include <climits>
+
+#if __GNUC__ == 4 && __GNUC_MINOR__ <= 2
+namespace std
+{
+ using ::strtold; // Tests indicated that gcc-4.2.1 does not have 'std::strtold'
+}
+#endif
+
+namespace boost { namespace cnv
+{
+ struct strtol;
+}}
+
+/// @brief std::strtol-based extended converter
+/// @details The converter offers a fairly decent overall performance and moderate formatting facilities.
+
+struct boost::cnv::strtol : public boost::cnv::cnvbase<boost::cnv::strtol>
+{
+ // C2. Old C-strings have an advantage over [begin, end) ranges. They do not need the 'end' iterator!
+ // Instead, they provide a sentinel (0 terminator). Consequently, C strings can be traversed
+ // without the need to compare if the 'end' has been reached (i.e. "for (; it != end; ++it)").
+ // Instead, the current character is checked if it's 0 (i.e. "for (; *p; ++p)") which is faster.
+ //
+ // So, the implementation takes advantage of the fact. Namely, we simply check if *cnv_end == 0
+ // instead of traversing once with strlen() to find the end iterator and then comparing to it as in
+ //
+ // char const* str_end = str + strlen(str); // Unnecessary traversal!
+ // ...
+ // bool const good = ... && cnv_end == str_end;
+
+ typedef boost::cnv::strtol this_type;
+ typedef boost::cnv::cnvbase<this_type> base_type;
+
+ using base_type::operator();
+
+ private:
+
+ friend struct boost::cnv::cnvbase<this_type>;
+
+ template<typename string_type> void str_to(cnv::range<string_type> v, optional< int_type>& r) const { str_to_i (v, r); }
+ template<typename string_type> void str_to(cnv::range<string_type> v, optional< sint_type>& r) const { str_to_i (v, r); }
+ template<typename string_type> void str_to(cnv::range<string_type> v, optional< lint_type>& r) const { str_to_i (v, r); }
+ template<typename string_type> void str_to(cnv::range<string_type> v, optional< uint_type>& r) const { str_to_i (v, r); }
+ template<typename string_type> void str_to(cnv::range<string_type> v, optional< usint_type>& r) const { str_to_i (v, r); }
+ template<typename string_type> void str_to(cnv::range<string_type> v, optional< ulint_type>& r) const { str_to_i (v, r); }
+ template<typename string_type> void str_to(cnv::range<string_type> v, optional< flt_type>& r) const { str_to_d (v, r); }
+ template<typename string_type> void str_to(cnv::range<string_type> v, optional< dbl_type>& r) const { str_to_d (v, r); }
+ template<typename string_type> void str_to(cnv::range<string_type> v, optional< ldbl_type>& r) const { str_to_d (v, r); }
+
+ template <typename char_type> cnv::range<char_type*> to_str ( int_type v, char_type* buf) const { return i_to_str(v, buf); }
+ template <typename char_type> cnv::range<char_type*> to_str (lint_type v, char_type* buf) const { return i_to_str(v, buf); }
+ template <typename char_type> cnv::range<char_type*> to_str ( dbl_type v, char_type* buf) const;
+
+ template<typename char_type, typename in_type> cnv::range<char_type*> i_to_str (in_type, char_type*) const;
+ template<typename string_type, typename out_type> void str_to_i (cnv::range<string_type>, optional<out_type>&) const;
+ template<typename string_type, typename out_type> void str_to_d (cnv::range<string_type>, optional<out_type>&) const;
+
+ static double adjust_fraction (double, int);
+ static int get_char (int v) { return (v < 10) ? (v += '0') : (v += 'A' - 10); }
+};
+
+template<typename char_type, typename Type>
+boost::cnv::range<char_type*>
+boost::cnv::strtol::i_to_str(Type value, char_type* buf) const
+{
+ // C1. Base=10 optimization improves performance 10%
+
+ char_type* beg = buf + bufsize_ / 2;
+ char_type* end = beg;
+ bool const is_negative = (value < 0) ? (value = -value, true) : false;
+
+ if (base_ == 10) for (; value; *(--beg) = int(value % 10) + '0', value /= 10); //C1
+ else for (; value; *(--beg) = get_char(value % base_), value /= base_);
+
+ if (beg == end) *(--beg) = '0';
+ if (is_negative) *(--beg) = '-';
+
+ return cnv::range<char_type*>(beg, end);
+}
+
+inline
+double
+boost::cnv::strtol::adjust_fraction(double fraction, int precision)
+{
+ // C1. Bring forward the fraction coming right after precision digits.
+ // That is, say, fraction=0.234567, precision=2. Then brought forward=23.4567
+ // C3. INT_MAX(4bytes)=2,147,483,647. So, 10^8 seems appropriate. If not, drop it down to 4.
+ // C4. ::round() returns the integral value that is nearest to x,
+ // with halfway cases rounded away from zero. Therefore,
+ // round( 0.4) = 0
+ // round( 0.5) = 1
+ // round( 0.6) = 1
+ // round(-0.4) = 0
+ // round(-0.5) = -1
+ // round(-0.6) = -1
+
+ int const tens[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 };
+
+ for (int k = precision / 8; k; --k) fraction *= 100000000; //C3.
+
+ fraction *= tens[precision % 8]; //C1
+
+// return ::rint(fraction); //C4
+ return boost::math::round(fraction); //C4
+}
+
+template <typename char_type>
+inline
+boost::cnv::range<char_type*>
+boost::cnv::strtol::to_str(double value, char_type* buf) const
+{
+ char_type* beg = buf + bufsize_ / 2;
+ char_type* end = beg;
+ char_type* ipos = end - 1;
+ bool const is_negative = (value < 0) ? (value = -value, true) : false;
+ double ipart = std::floor(value);
+ double fpart = adjust_fraction(value - ipart, precision_);
+ int precision = precision_;
+ int const base = 10;
+
+ for (; 1 <= ipart; ipart /= base)
+ *(--beg) = get_char(int(ipart - std::floor(ipart / base) * base));
+
+ if (beg == end) *(--beg) = '0';
+ if (precision) *(end++) = '.';
+
+ for (char_type* fpos = end += precision; precision; --precision, fpart /= base)
+ *(--fpos) = get_char(int(fpart - std::floor(fpart / base) * base));
+
+ if (1 <= fpart)
+ {
+ for (; beg <= ipos; --ipos)
+ if (*ipos == '9') *ipos = '0';
+ else { ++*ipos; break; }
+
+ if (ipos < beg)
+ *(beg = ipos) = '1';
+ }
+ if (is_negative) *(--beg) = '-';
+
+ return cnv::range<char_type*>(beg, end);
+}
+
+template<typename string_type, typename out_type>
+void
+boost::cnv::strtol::str_to_i(cnv::range<string_type> range, boost::optional<out_type>& result_out) const
+{
+
+ typedef typename boost::make_unsigned<out_type>::type unsigned_type;
+ typedef cnv::range<string_type> range_type;
+ typedef typename range_type::iterator iterator;
+
+ iterator s = range.begin();
+ unsigned int ch = *s;
+ bool const is_negative = ch == '-' ? (ch = *++s, true) : ch == '+' ? (ch = *++s, false) : false;
+ bool const is_unsigned = boost::is_same<out_type, unsigned_type>::value;
+ unsigned int base = base_;
+
+ /**/ if (is_negative && is_unsigned) return;
+ else if ((base == 0 || base == 16) && ch == '0' && (*++s == 'x' || *s == 'X')) ++s, base = 16;
+ else if (base == 0) base = ch == '0' ? (++s, 8) : 10;
+
+ unsigned_type const max = (std::numeric_limits<out_type>::max)() + (is_negative ? 1 : 0);
+ unsigned_type const cutoff = max / base;
+ unsigned int const cutlim = max % base;
+ unsigned_type result = 0;
+
+ for (; s != range.sentry(); ++s)
+ {
+ unsigned int ch = *s;
+
+ /**/ if (std::isdigit(ch)) ch -= '0';
+ else if (std::isalpha(ch)) ch -= (std::isupper(ch) ? 'A' : 'a') - 10;
+ else return;
+
+ if (base <= ch || cutoff < result || (result == cutoff && cutlim < ch))
+ return;
+
+ result *= base;
+ result += ch;
+ }
+ result_out = is_negative ? -out_type(result) : out_type(result);
+}
+
+template<typename string_type, typename out_type>
+void
+boost::cnv::strtol::str_to_d(cnv::range<string_type> range, optional<out_type>& result_out) const
+{
+ typedef cnv::range<string_type> range_type;
+ typedef typename range_type::iterator iterator;
+ typedef typename range_type::value_type char_type;
+
+ char_type const* str = &*range.begin(); // Currently only works with 'char'
+ char* cnv_end = 0;
+ ldbl_type const result = strtold(str, &cnv_end);
+ bool const good = result != -HUGE_VALL && result != HUGE_VALL && *cnv_end == 0/*C2*/;
+ out_type const max = (std::numeric_limits<out_type>::max)();
+
+ if (good && -max <= result && result <= max)
+ result_out = out_type(result);
+}
+
+#endif // BOOST_CONVERT_STRTOL_CONVERTER_HPP
diff --git a/boost/core/ignore_unused.hpp b/boost/core/ignore_unused.hpp
index 22047c2e54..994e5f6476 100644
--- a/boost/core/ignore_unused.hpp
+++ b/boost/core/ignore_unused.hpp
@@ -14,53 +14,53 @@ namespace boost {
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
template <typename... Ts>
-inline void ignore_unused(Ts const& ...)
+BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(Ts const& ...)
{}
template <typename... Ts>
-inline void ignore_unused()
+BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused()
{}
#else
template <typename T1>
-inline void ignore_unused(T1 const&)
+BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&)
{}
template <typename T1, typename T2>
-inline void ignore_unused(T1 const&, T2 const&)
+BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&)
{}
template <typename T1, typename T2, typename T3>
-inline void ignore_unused(T1 const&, T2 const&, T3 const&)
+BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&)
{}
template <typename T1, typename T2, typename T3, typename T4>
-inline void ignore_unused(T1 const&, T2 const&, T3 const&, T4 const&)
+BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&, T4 const&)
{}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
-inline void ignore_unused(T1 const&, T2 const&, T3 const&, T4 const&, T5 const&)
+BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&, T4 const&, T5 const&)
{}
template <typename T1>
-inline void ignore_unused()
+BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused()
{}
template <typename T1, typename T2>
-inline void ignore_unused()
+BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused()
{}
template <typename T1, typename T2, typename T3>
-inline void ignore_unused()
+BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused()
{}
template <typename T1, typename T2, typename T3, typename T4>
-inline void ignore_unused()
+BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused()
{}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
-inline void ignore_unused()
+BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused()
{}
#endif
diff --git a/boost/coroutine/asymmetric_coroutine.hpp b/boost/coroutine/asymmetric_coroutine.hpp
index 8ffebf5e39..d9369fae38 100644
--- a/boost/coroutine/asymmetric_coroutine.hpp
+++ b/boost/coroutine/asymmetric_coroutine.hpp
@@ -30,6 +30,7 @@
#include <boost/coroutine/detail/push_coroutine_impl.hpp>
#include <boost/coroutine/detail/push_coroutine_object.hpp>
#include <boost/coroutine/detail/push_coroutine_synthesized.hpp>
+#include <boost/coroutine/stack_context.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
@@ -472,14 +473,13 @@ public:
push_coroutine< R >, R, coroutine_fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -500,14 +500,13 @@ public:
push_coroutine< R >, R, coroutine_fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -528,14 +527,13 @@ public:
push_coroutine< R >, R, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -556,14 +554,13 @@ public:
push_coroutine< R >, R, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -584,14 +581,13 @@ public:
push_coroutine< R >, R, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -612,14 +608,13 @@ public:
push_coroutine< R >, R, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -640,14 +635,13 @@ public:
push_coroutine< R >, R, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -668,14 +662,13 @@ public:
push_coroutine< R >, R, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -807,9 +800,92 @@ public:
}
};
- friend class iterator;
+ class const_iterator : public std::iterator< std::input_iterator_tag, const typename remove_reference< R >::type >
+ {
+ private:
+ pull_coroutine< R > * c_;
+ R * val_;
- struct const_iterator;
+ void fetch_()
+ {
+ BOOST_ASSERT( c_);
+
+ if ( ! ( * c_) )
+ {
+ c_ = 0;
+ val_ = 0;
+ return;
+ }
+ val_ = c_->impl_->get_pointer();
+ }
+
+ void increment_()
+ {
+ BOOST_ASSERT( c_);
+ BOOST_ASSERT( * c_);
+
+ ( * c_)();
+ fetch_();
+ }
+
+ public:
+ typedef typename const_iterator::pointer pointer_t;
+ typedef typename const_iterator::reference reference_t;
+
+ const_iterator() :
+ c_( 0), val_( 0)
+ {}
+
+ explicit const_iterator( pull_coroutine< R > const* c) :
+ c_( const_cast< pull_coroutine< R > * >( c) ),
+ val_( 0)
+ { fetch_(); }
+
+ const_iterator( const_iterator const& other) :
+ c_( other.c_), val_( other.val_)
+ {}
+
+ const_iterator & operator=( const_iterator const& other)
+ {
+ if ( this == & other) return * this;
+ c_ = other.c_;
+ val_ = other.val_;
+ return * this;
+ }
+
+ bool operator==( const_iterator const& other) const
+ { return other.c_ == c_ && other.val_ == val_; }
+
+ bool operator!=( const_iterator const& other) const
+ { return other.c_ != c_ || other.val_ != val_; }
+
+ const_iterator & operator++()
+ {
+ increment_();
+ return * this;
+ }
+
+ const_iterator operator++( int);
+
+ reference_t operator*() const
+ {
+ if ( ! val_)
+ boost::throw_exception(
+ invalid_result() );
+ return * val_;
+ }
+
+ pointer_t operator->() const
+ {
+ if ( ! val_)
+ boost::throw_exception(
+ invalid_result() );
+ return val_;
+ }
+ };
+
+ friend class iterator;
+ friend class const_iterator;
};
template< typename R >
@@ -857,14 +933,13 @@ public:
push_coroutine< R & >, R &, coroutine_fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -885,14 +960,13 @@ public:
push_coroutine< R & >, R &, coroutine_fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -913,14 +987,13 @@ public:
push_coroutine< R & >, R &, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -941,14 +1014,13 @@ public:
push_coroutine< R & >, R &, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -969,14 +1041,13 @@ public:
push_coroutine< R & >, R &, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -997,14 +1068,13 @@ public:
push_coroutine< R & >, R &, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -1025,14 +1095,13 @@ public:
push_coroutine< R & >, R &, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -1053,14 +1122,13 @@ public:
push_coroutine< R & >, R &, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -1105,7 +1173,7 @@ public:
R & get() const
{ return impl_->get(); }
- class iterator : public std::iterator< std::input_iterator_tag, R >
+ class iterator : public std::iterator< std::input_iterator_tag, typename remove_reference< R >::type >
{
private:
pull_coroutine< R & > * c_;
@@ -1188,9 +1256,92 @@ public:
}
};
- friend class iterator;
+ class const_iterator : public std::iterator< std::input_iterator_tag, const typename remove_reference< R >::type >
+ {
+ private:
+ pull_coroutine< R & > * c_;
+ R * val_;
- struct const_iterator;
+ void fetch_()
+ {
+ BOOST_ASSERT( c_);
+
+ if ( ! ( * c_) )
+ {
+ c_ = 0;
+ val_ = 0;
+ return;
+ }
+ val_ = c_->impl_->get_pointer();
+ }
+
+ void increment_()
+ {
+ BOOST_ASSERT( c_);
+ BOOST_ASSERT( * c_);
+
+ ( * c_)();
+ fetch_();
+ }
+
+ public:
+ typedef typename const_iterator::pointer pointer_t;
+ typedef typename const_iterator::reference reference_t;
+
+ const_iterator() :
+ c_( 0), val_( 0)
+ {}
+
+ explicit const_iterator( pull_coroutine< R & > const* c) :
+ c_( const_cast< pull_coroutine< R & > * >( c) ),
+ val_( 0)
+ { fetch_(); }
+
+ const_iterator( const_iterator const& other) :
+ c_( other.c_), val_( other.val_)
+ {}
+
+ const_iterator & operator=( const_iterator const& other)
+ {
+ if ( this == & other) return * this;
+ c_ = other.c_;
+ val_ = other.val_;
+ return * this;
+ }
+
+ bool operator==( const_iterator const& other) const
+ { return other.c_ == c_ && other.val_ == val_; }
+
+ bool operator!=( const_iterator const& other) const
+ { return other.c_ != c_ || other.val_ != val_; }
+
+ const_iterator & operator++()
+ {
+ increment_();
+ return * this;
+ }
+
+ const_iterator operator++( int);
+
+ reference_t operator*() const
+ {
+ if ( ! val_)
+ boost::throw_exception(
+ invalid_result() );
+ return * val_;
+ }
+
+ pointer_t operator->() const
+ {
+ if ( ! val_)
+ boost::throw_exception(
+ invalid_result() );
+ return val_;
+ }
+ };
+
+ friend class iterator;
+ friend class const_iterator;
};
template<>
@@ -1238,14 +1389,13 @@ public:
push_coroutine< void >, void, coroutine_fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -1266,14 +1416,13 @@ public:
push_coroutine< void >, void, coroutine_fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -1294,14 +1443,13 @@ public:
push_coroutine< void >, void, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -1322,14 +1470,13 @@ public:
push_coroutine< void >, void, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -1350,14 +1497,13 @@ public:
push_coroutine< void >, void, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -1378,14 +1524,13 @@ public:
push_coroutine< void >, void, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -1406,14 +1551,13 @@ public:
push_coroutine< void >, void, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -1434,14 +1578,13 @@ public:
push_coroutine< void >, void, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
impl_->pull();
}
@@ -1505,14 +1648,13 @@ push_coroutine< Arg >::push_coroutine( coroutine_fn fn,
pull_coroutine< Arg >, Arg, coroutine_fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1533,14 +1675,13 @@ push_coroutine< Arg >::push_coroutine( coroutine_fn fn,
pull_coroutine< Arg >, Arg, coroutine_fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1560,14 +1701,13 @@ push_coroutine< Arg & >::push_coroutine( coroutine_fn fn,
pull_coroutine< Arg & >, Arg &, coroutine_fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1588,14 +1728,13 @@ push_coroutine< Arg & >::push_coroutine( coroutine_fn fn,
pull_coroutine< Arg & >, Arg &, coroutine_fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1614,14 +1753,13 @@ inline push_coroutine< void >::push_coroutine( coroutine_fn fn,
pull_coroutine< void >, void, coroutine_fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1641,14 +1779,13 @@ push_coroutine< void >::push_coroutine( coroutine_fn fn,
pull_coroutine< void >, void, coroutine_fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
# endif
@@ -1669,14 +1806,13 @@ push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
pull_coroutine< Arg >, Arg, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1697,14 +1833,13 @@ push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
pull_coroutine< Arg >, Arg, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1725,14 +1860,13 @@ push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1753,14 +1887,13 @@ push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1780,14 +1913,13 @@ push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
pull_coroutine< void >, void, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1807,14 +1939,13 @@ push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
pull_coroutine< void >, void, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
#else
@@ -1835,14 +1966,13 @@ push_coroutine< Arg >::push_coroutine( Fn fn,
pull_coroutine< Arg >, Arg, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1863,14 +1993,13 @@ push_coroutine< Arg >::push_coroutine( Fn fn,
pull_coroutine< Arg >, Arg, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1891,14 +2020,13 @@ push_coroutine< Arg & >::push_coroutine( Fn fn,
pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1919,14 +2047,13 @@ push_coroutine< Arg & >::push_coroutine( Fn fn,
pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1946,14 +2073,13 @@ push_coroutine< void >::push_coroutine( Fn fn,
pull_coroutine< void >, void, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -1973,14 +2099,13 @@ push_coroutine< void >::push_coroutine( Fn fn,
pull_coroutine< void >, void, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -2001,14 +2126,13 @@ push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
pull_coroutine< Arg >, Arg, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -2029,14 +2153,13 @@ push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
pull_coroutine< Arg >, Arg, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -2057,14 +2180,13 @@ push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -2085,14 +2207,13 @@ push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -2112,14 +2233,13 @@ push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
pull_coroutine< void >, void, Fn, stack_allocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -2139,14 +2259,13 @@ push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
pull_coroutine< void >, void, Fn, StackAllocator
> object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
#endif
@@ -2165,10 +2284,20 @@ range_begin( pull_coroutine< R > & c)
{ return typename pull_coroutine< R >::iterator( & c); }
template< typename R >
+typename pull_coroutine< R >::const_iterator
+range_begin( pull_coroutine< R > const& c)
+{ return typename pull_coroutine< R >::const_iterator( & c); }
+
+template< typename R >
typename pull_coroutine< R >::iterator
range_end( pull_coroutine< R > &)
{ return typename pull_coroutine< R >::iterator(); }
+template< typename R >
+typename pull_coroutine< R >::const_iterator
+range_end( pull_coroutine< R > const&)
+{ return typename pull_coroutine< R >::const_iterator(); }
+
template< typename Arg >
typename push_coroutine< Arg >::iterator
range_begin( push_coroutine< Arg > & c)
@@ -2200,11 +2329,21 @@ begin( pull_coroutine< R > & c)
{ return boost::begin( c); }
template< typename R >
+typename pull_coroutine< R >::const_iterator
+begin( pull_coroutine< R > const& c)
+{ return boost::begin( c); }
+
+template< typename R >
typename pull_coroutine< R >::iterator
end( pull_coroutine< R > & c)
{ return boost::end( c); }
template< typename R >
+typename pull_coroutine< R >::const_iterator
+end( pull_coroutine< R > const& c)
+{ return boost::end( c); }
+
+template< typename R >
typename push_coroutine< R >::iterator
begin( push_coroutine< R > & c)
{ return boost::begin( c); }
diff --git a/boost/coroutine/detail/coroutine_context.hpp b/boost/coroutine/detail/coroutine_context.hpp
index 6c4ebb68b1..94aa69bd6e 100644
--- a/boost/coroutine/detail/coroutine_context.hpp
+++ b/boost/coroutine/detail/coroutine_context.hpp
@@ -14,6 +14,7 @@
#include <boost/context/fcontext.hpp>
#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/detail/preallocated.hpp>
#include <boost/coroutine/stack_context.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
@@ -26,10 +27,9 @@ namespace detail {
// class hold stack-context and coroutines execution-context
class BOOST_COROUTINES_DECL coroutine_context
-
{
private:
- stack_context stack_ctx_;
+ preallocated palloc_;
context::fcontext_t ctx_;
public:
@@ -41,7 +41,7 @@ public:
// ctor creates a new execution-context running coroutine-fn `fn`
// `ctx_` will be allocated on top of the stack managed by parameter
// `stack_ctx`
- coroutine_context( ctx_fn fn, stack_context const& stack_ctx);
+ coroutine_context( ctx_fn fn, preallocated const& palloc);
coroutine_context( coroutine_context const&);
@@ -50,7 +50,7 @@ public:
intptr_t jump( coroutine_context &, intptr_t = 0, bool = true);
stack_context & stack_ctx()
- { return stack_ctx_; }
+ { return palloc_.sctx; }
};
}}}
diff --git a/boost/coroutine/detail/preallocated.hpp b/boost/coroutine/detail/preallocated.hpp
new file mode 100644
index 0000000000..1658561ac8
--- /dev/null
+++ b/boost/coroutine/detail/preallocated.hpp
@@ -0,0 +1,45 @@
+
+// Copyright Oliver Kowalke 2015.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES_DETAIL_PREALLOCATED_H
+#define BOOST_COROUTINES_DETAIL_PREALLOCATED_H
+
+#include <cstddef>
+
+#include <boost/config.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/stack_context.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+struct preallocated {
+ void * sp;
+ std::size_t size;
+ stack_context sctx;
+
+ preallocated() BOOST_NOEXCEPT :
+ sp( 0), size( 0), sctx() {
+ }
+
+ preallocated( void * sp_, std::size_t size_, stack_context sctx_) BOOST_NOEXCEPT :
+ sp( sp_), size( size_), sctx( sctx_) {
+ }
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_PREALLOCATED_H
diff --git a/boost/coroutine/detail/pull_coroutine_object.hpp b/boost/coroutine/detail/pull_coroutine_object.hpp
index cfe34bd3c9..57ae169d80 100644
--- a/boost/coroutine/detail/pull_coroutine_object.hpp
+++ b/boost/coroutine/detail/pull_coroutine_object.hpp
@@ -16,6 +16,7 @@
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/coroutine_context.hpp>
#include <boost/coroutine/detail/flags.hpp>
+#include <boost/coroutine/detail/preallocated.hpp>
#include <boost/coroutine/detail/pull_coroutine_impl.hpp>
#include <boost/coroutine/detail/trampoline_pull.hpp>
#include <boost/coroutine/exceptions.hpp>
@@ -41,9 +42,9 @@ struct pull_coroutine_context
coroutine_context callee;
template< typename Coro >
- pull_coroutine_context( stack_context const& stack_ctx, Coro *) :
+ pull_coroutine_context( preallocated const& palloc, Coro *) :
caller(),
- callee( trampoline_pull< Coro >, stack_ctx)
+ callee( trampoline_pull< Coro >, palloc)
{}
};
@@ -72,25 +73,23 @@ private:
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
pull_coroutine_object( Fn fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- ctx_t( internal_stack_ctx, this),
+ ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind,
fpu_preserved == attrs.preserve_fpu),
fn_( fn),
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
pull_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- ctx_t( internal_stack_ctx, this),
+ ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind,
@@ -100,7 +99,7 @@ public:
#else
fn_( boost::forward< Fn >( fn) ),
#endif
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
@@ -160,25 +159,23 @@ private:
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
pull_coroutine_object( Fn fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- ctx_t( internal_stack_ctx, this),
+ ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind,
fpu_preserved == attrs.preserve_fpu),
fn_( fn),
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
pull_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- ctx_t( internal_stack_ctx, this),
+ ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind,
@@ -188,7 +185,7 @@ public:
#else
fn_( boost::forward< Fn >( fn) ),
#endif
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
@@ -248,25 +245,23 @@ private:
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
pull_coroutine_object( Fn fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- ctx_t( internal_stack_ctx, this),
+ ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind,
fpu_preserved == attrs.preserve_fpu),
fn_( fn),
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
pull_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- ctx_t( internal_stack_ctx, this),
+ ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind,
@@ -276,7 +271,7 @@ public:
#else
fn_( boost::forward< Fn >( fn) ),
#endif
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
diff --git a/boost/coroutine/detail/push_coroutine_object.hpp b/boost/coroutine/detail/push_coroutine_object.hpp
index 1a39c07230..53d5c7710e 100644
--- a/boost/coroutine/detail/push_coroutine_object.hpp
+++ b/boost/coroutine/detail/push_coroutine_object.hpp
@@ -16,6 +16,7 @@
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/coroutine_context.hpp>
#include <boost/coroutine/detail/flags.hpp>
+#include <boost/coroutine/detail/preallocated.hpp>
#include <boost/coroutine/detail/push_coroutine_impl.hpp>
#include <boost/coroutine/detail/trampoline_push.hpp>
#include <boost/coroutine/exceptions.hpp>
@@ -41,9 +42,9 @@ struct push_coroutine_context
coroutine_context callee;
template< typename Coro >
- push_coroutine_context( stack_context const& stack_ctx, Coro *) :
+ push_coroutine_context( preallocated const& palloc, Coro *) :
caller(),
- callee( trampoline_push< Coro >, stack_ctx)
+ callee( trampoline_push< Coro >, palloc)
{}
};
@@ -53,9 +54,9 @@ struct push_coroutine_context_void
coroutine_context callee;
template< typename Coro >
- push_coroutine_context_void( stack_context const& stack_ctx, Coro *) :
+ push_coroutine_context_void( preallocated const& palloc, Coro *) :
caller(),
- callee( trampoline_push_void< Coro >, stack_ctx)
+ callee( trampoline_push_void< Coro >, palloc)
{}
};
@@ -84,25 +85,23 @@ private:
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
push_coroutine_object( Fn fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- ctx_t( internal_stack_ctx, this),
+ ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind,
fpu_preserved == attrs.preserve_fpu),
fn_( fn),
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
push_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- ctx_t( internal_stack_ctx, this),
+ ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind,
@@ -112,7 +111,7 @@ public:
#else
fn_( boost::forward< Fn >( fn) ),
#endif
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
@@ -172,25 +171,23 @@ private:
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
push_coroutine_object( Fn fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- ctx_t( internal_stack_ctx, this),
+ ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind,
fpu_preserved == attrs.preserve_fpu),
fn_( fn),
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
push_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- ctx_t( internal_stack_ctx, this),
+ ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind,
@@ -200,7 +197,7 @@ public:
#else
fn_( boost::forward< Fn >( fn) ),
#endif
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
@@ -260,25 +257,23 @@ private:
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
push_coroutine_object( Fn fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- ctx_t( internal_stack_ctx, this),
+ ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind,
fpu_preserved == attrs.preserve_fpu),
fn_( fn),
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
push_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- ctx_t( internal_stack_ctx, this),
+ ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind,
@@ -288,7 +283,7 @@ public:
#else
fn_( boost::forward< Fn >( fn) ),
#endif
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
diff --git a/boost/coroutine/detail/symmetric_coroutine_call.hpp b/boost/coroutine/detail/symmetric_coroutine_call.hpp
index a499275636..0b504b8edc 100644
--- a/boost/coroutine/detail/symmetric_coroutine_call.hpp
+++ b/boost/coroutine/detail/symmetric_coroutine_call.hpp
@@ -14,6 +14,7 @@
#include <boost/coroutine/attributes.hpp>
#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/detail/preallocated.hpp>
#include <boost/coroutine/detail/symmetric_coroutine_impl.hpp>
#include <boost/coroutine/detail/symmetric_coroutine_object.hpp>
#include <boost/coroutine/detail/symmetric_coroutine_yield.hpp>
@@ -68,14 +69,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, coroutine_fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -93,14 +93,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, coroutine_fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
# endif
@@ -118,14 +117,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -143,14 +141,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
#else
@@ -168,13 +165,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t( fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -192,13 +189,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t( fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -216,13 +213,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t( fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -240,13 +237,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t( fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
#endif
@@ -328,14 +325,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, coroutine_fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -353,14 +349,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, coroutine_fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
# endif
@@ -378,14 +373,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -403,14 +397,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
#else
@@ -428,13 +421,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t( fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -452,13 +445,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t( fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -476,13 +469,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t( fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -500,13 +493,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t( fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
#endif
@@ -588,14 +581,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, coroutine_fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -613,14 +605,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, coroutine_fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< coroutine_fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
# endif
@@ -638,14 +629,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -663,14 +653,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t(
- boost::forward< Fn >( fn), attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
#else
@@ -688,13 +677,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t( fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -712,13 +701,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t( fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -736,13 +725,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t( fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
@@ -760,13 +749,13 @@ public:
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
- stack_context internal_stack_ctx;
- internal_stack_ctx.sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.sp);
- internal_stack_ctx.size = stack_ctx.size - sizeof( object_t);
- BOOST_ASSERT( 0 < internal_stack_ctx.size);
+ std::size_t size = stack_ctx.size - sizeof( object_t);
+ BOOST_ASSERT( 0 < size);
+ void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
+ BOOST_ASSERT( 0 < sp);
// placement new for internal coroutine
- impl_ = new ( internal_stack_ctx.sp) object_t( fn, attrs, stack_ctx, internal_stack_ctx, stack_alloc);
+ impl_ = new ( sp) object_t(
+ fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
#endif
diff --git a/boost/coroutine/detail/symmetric_coroutine_impl.hpp b/boost/coroutine/detail/symmetric_coroutine_impl.hpp
index 0234ca7765..96d948a49c 100644
--- a/boost/coroutine/detail/symmetric_coroutine_impl.hpp
+++ b/boost/coroutine/detail/symmetric_coroutine_impl.hpp
@@ -16,6 +16,7 @@
#include <boost/coroutine/detail/coroutine_context.hpp>
#include <boost/coroutine/detail/flags.hpp>
#include <boost/coroutine/detail/parameters.hpp>
+#include <boost/coroutine/detail/preallocated.hpp>
#include <boost/coroutine/detail/trampoline.hpp>
#include <boost/coroutine/exceptions.hpp>
#include <boost/coroutine/stack_context.hpp>
@@ -34,11 +35,11 @@ class symmetric_coroutine_impl : private noncopyable
public:
typedef parameters< R > param_type;
- symmetric_coroutine_impl( stack_context const& stack_ctx,
+ symmetric_coroutine_impl( preallocated const& palloc,
bool unwind, bool preserve_fpu) BOOST_NOEXCEPT :
flags_( 0),
caller_(),
- callee_( trampoline< symmetric_coroutine_impl< R > >, stack_ctx)
+ callee_( trampoline< symmetric_coroutine_impl< R > >, palloc)
{
if ( unwind) flags_ |= flag_force_unwind;
if ( preserve_fpu) flags_ |= flag_preserve_fpu;
@@ -182,11 +183,11 @@ class symmetric_coroutine_impl< R & > : private noncopyable
public:
typedef parameters< R & > param_type;
- symmetric_coroutine_impl( stack_context const& stack_ctx,
+ symmetric_coroutine_impl( preallocated const& palloc,
bool unwind, bool preserve_fpu) BOOST_NOEXCEPT :
flags_( 0),
caller_(),
- callee_( trampoline< symmetric_coroutine_impl< R > >, stack_ctx)
+ callee_( trampoline< symmetric_coroutine_impl< R > >, palloc)
{
if ( unwind) flags_ |= flag_force_unwind;
if ( preserve_fpu) flags_ |= flag_preserve_fpu;
@@ -330,11 +331,11 @@ class symmetric_coroutine_impl< void > : private noncopyable
public:
typedef parameters< void > param_type;
- symmetric_coroutine_impl( stack_context const& stack_ctx,
+ symmetric_coroutine_impl( preallocated const& palloc,
bool unwind, bool preserve_fpu) BOOST_NOEXCEPT :
flags_( 0),
caller_(),
- callee_( trampoline_void< symmetric_coroutine_impl< void > >, stack_ctx)
+ callee_( trampoline_void< symmetric_coroutine_impl< void > >, palloc)
{
if ( unwind) flags_ |= flag_force_unwind;
if ( preserve_fpu) flags_ |= flag_preserve_fpu;
@@ -392,7 +393,7 @@ public:
flags_ &= ~flag_running;
}
- inline void yield() BOOST_NOEXCEPT
+ inline void yield()
{
BOOST_ASSERT( is_running() );
BOOST_ASSERT( ! is_complete() );
diff --git a/boost/coroutine/detail/symmetric_coroutine_object.hpp b/boost/coroutine/detail/symmetric_coroutine_object.hpp
index a1c0c052a5..0e528f9611 100644
--- a/boost/coroutine/detail/symmetric_coroutine_object.hpp
+++ b/boost/coroutine/detail/symmetric_coroutine_object.hpp
@@ -13,6 +13,7 @@
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/flags.hpp>
+#include <boost/coroutine/detail/preallocated.hpp>
#include <boost/coroutine/detail/symmetric_coroutine_impl.hpp>
#include <boost/coroutine/detail/symmetric_coroutine_yield.hpp>
#include <boost/coroutine/exceptions.hpp>
@@ -52,23 +53,21 @@ private:
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
symmetric_coroutine_object( Fn fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- impl_t( internal_stack_ctx,
+ impl_t( palloc,
stack_unwind == attrs.do_unwind,
fpu_preserved == attrs.preserve_fpu),
fn_( fn),
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
symmetric_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- impl_t( internal_stack_ctx,
+ impl_t( palloc,
stack_unwind == attrs.do_unwind,
fpu_preserved == attrs.preserve_fpu),
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
@@ -76,7 +75,7 @@ public:
#else
fn_( boost::forward< Fn >( fn) ),
#endif
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
@@ -133,23 +132,21 @@ private:
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
symmetric_coroutine_object( Fn fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- impl_t( internal_stack_ctx,
+ impl_t( palloc,
stack_unwind == attrs.do_unwind,
fpu_preserved == attrs.preserve_fpu),
fn_( fn),
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
symmetric_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- impl_t( internal_stack_ctx,
+ impl_t( palloc,
stack_unwind == attrs.do_unwind,
fpu_preserved == attrs.preserve_fpu),
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
@@ -157,7 +154,7 @@ public:
#else
fn_( boost::forward< Fn >( fn) ),
#endif
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
@@ -214,23 +211,21 @@ private:
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
symmetric_coroutine_object( Fn fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- impl_t( internal_stack_ctx,
+ impl_t( palloc,
stack_unwind == attrs.do_unwind,
fpu_preserved == attrs.preserve_fpu),
fn_( fn),
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
symmetric_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
- stack_context const& stack_ctx,
- stack_context const& internal_stack_ctx,
+ preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
- impl_t( internal_stack_ctx,
+ impl_t( palloc,
stack_unwind == attrs.do_unwind,
fpu_preserved == attrs.preserve_fpu),
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
@@ -238,7 +233,7 @@ public:
#else
fn_( boost::forward< Fn >( fn) ),
#endif
- stack_ctx_( stack_ctx),
+ stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
diff --git a/boost/coroutine/exceptions.hpp b/boost/coroutine/exceptions.hpp
index f263429719..5dbd55f106 100644
--- a/boost/coroutine/exceptions.hpp
+++ b/boost/coroutine/exceptions.hpp
@@ -36,7 +36,8 @@ BOOST_SCOPED_ENUM_DECLARE_BEGIN(coroutine_errc)
}
BOOST_SCOPED_ENUM_DECLARE_END(coroutine_errc)
-BOOST_COROUTINES_DECL system::error_category const& coroutine_category() BOOST_NOEXCEPT;
+BOOST_COROUTINES_DECL
+system::error_category const& coroutine_category() BOOST_NOEXCEPT;
}
@@ -81,9 +82,6 @@ public:
system::error_code const& code() const BOOST_NOEXCEPT
{ return ec_; }
-
- const char* what() const throw()
- { return code().message().c_str(); }
};
class invalid_result : public coroutine_error
diff --git a/boost/coroutine2/all.hpp b/boost/coroutine2/all.hpp
new file mode 100644
index 0000000000..f54b4569eb
--- /dev/null
+++ b/boost/coroutine2/all.hpp
@@ -0,0 +1,15 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_ALL_H
+#define BOOST_COROUTINES2_ALL_H
+
+#include <boost/coroutine2/coroutine.hpp>
+#include <boost/coroutine2/fixedsize_stack.hpp>
+#include <boost/coroutine2/protected_fixedsize_stack.hpp>
+#include <boost/coroutine2/segmented_stack.hpp>
+
+#endif // BOOST_COROUTINES2_ALL_H
diff --git a/boost/coroutine2/coroutine.hpp b/boost/coroutine2/coroutine.hpp
new file mode 100644
index 0000000000..0269299518
--- /dev/null
+++ b/boost/coroutine2/coroutine.hpp
@@ -0,0 +1,39 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_COROUTINE_H
+#define BOOST_COROUTINES2_COROUTINE_H
+
+#include <exception>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+
+#include <boost/coroutine2/detail/coroutine.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+
+template< typename T >
+struct coroutine {
+ typedef detail::pull_coroutine< T > pull_type;
+ typedef detail::push_coroutine< T > push_type;
+};
+
+template< typename T >
+using asymmetric_coroutine = coroutine< T >;
+
+}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_COROUTINE_H
diff --git a/boost/coroutine2/detail/config.hpp b/boost/coroutine2/detail/config.hpp
new file mode 100644
index 0000000000..c439ecc0ea
--- /dev/null
+++ b/boost/coroutine2/detail/config.hpp
@@ -0,0 +1,51 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_DETAIL_CONFIG_H
+#define BOOST_COROUTINES2_DETAIL_CONFIG_H
+
+#include <boost/config.hpp>
+#include <boost/context/detail/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+#ifdef BOOST_COROUTINES2_DECL
+# undef BOOST_COROUTINES2_DECL
+#endif
+
+#if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_COROUTINES2_DYN_LINK) ) && ! defined(BOOST_COROUTINES2_STATIC_LINK)
+# if defined(BOOST_COROUTINES2_SOURCE)
+# define BOOST_COROUTINES2_DECL BOOST_SYMBOL_EXPORT
+# define BOOST_COROUTINES2_BUILD_DLL
+# else
+# define BOOST_COROUTINES2_DECL BOOST_SYMBOL_IMPORT
+# endif
+#endif
+
+#if ! defined(BOOST_COROUTINES2_DECL)
+# define BOOST_COROUTINES2_DECL
+#endif
+
+#if ! defined(BOOST_COROUTINES2_SOURCE) && ! defined(BOOST_ALL_NO_LIB) && ! defined(BOOST_COROUTINES2_NO_LIB)
+# define BOOST_LIB_NAME boost_coroutine
+# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_COROUTINES2_DYN_LINK)
+# define BOOST_DYN_LINK
+# endif
+# include <boost/config/auto_link.hpp>
+#endif
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+# if ! ( (defined(__GNUC__) && __GNUC__ > 3 && __GNUC_MINOR__ > 6) || \
+ (defined(__clang__) && __clang_major__ > 2 && __clang_minor__ > 3) )
+# error "compiler does not support segmented_stack stacks"
+# endif
+# define BOOST_COROUTINES2_SEGMENTS 10
+#endif
+
+#if defined(BOOST_CONTEXT_NO_EXECUTION_CONTEXT)
+# error "execution_context from boost.context not supported"
+#endif
+
+#endif // BOOST_COROUTINES2_DETAIL_CONFIG_H
diff --git a/boost/coroutine2/detail/coroutine.hpp b/boost/coroutine2/detail/coroutine.hpp
new file mode 100644
index 0000000000..55641e443c
--- /dev/null
+++ b/boost/coroutine2/detail/coroutine.hpp
@@ -0,0 +1,44 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_DETAIL_COROUTINE_HPP
+#define BOOST_COROUTINES2_DETAIL_COROUTINE_HPP
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+namespace detail {
+
+template< typename T >
+class pull_coroutine;
+
+template< typename T >
+class push_coroutine;
+
+}}}
+
+#include <boost/coroutine2/detail/pull_coroutine.hpp>
+#include <boost/coroutine2/detail/push_coroutine.hpp>
+
+#include <boost/coroutine2/detail/pull_control_block.hpp>
+#include <boost/coroutine2/detail/push_control_block.hpp>
+
+#include <boost/coroutine2/detail/pull_coroutine.ipp>
+#include <boost/coroutine2/detail/push_coroutine.ipp>
+
+#include <boost/coroutine2/detail/pull_control_block.ipp>
+#include <boost/coroutine2/detail/push_control_block.ipp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_DETAIL_COROUTINE_HPP
diff --git a/boost/coroutine2/detail/forced_unwind.hpp b/boost/coroutine2/detail/forced_unwind.hpp
new file mode 100644
index 0000000000..e04eb72d69
--- /dev/null
+++ b/boost/coroutine2/detail/forced_unwind.hpp
@@ -0,0 +1,33 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_DETAIL_FORCED_UNWIND_HPP
+#define BOOST_COROUTINES2_DETAIL_FORCED_UNWIND_HPP
+
+#include <exception>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+
+#include <boost/context/execution_context.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+namespace detail {
+
+struct forced_unwind {};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_DETAIL_FORCED_UNWIND_HPP
diff --git a/boost/coroutine2/detail/pull_control_block.hpp b/boost/coroutine2/detail/pull_control_block.hpp
new file mode 100644
index 0000000000..1abb34a0db
--- /dev/null
+++ b/boost/coroutine2/detail/pull_control_block.hpp
@@ -0,0 +1,100 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_DETAIL_PULL_CONTROL_BLOCK_HPP
+#define BOOST_COROUTINES2_DETAIL_PULL_CONTROL_BLOCK_HPP
+
+#include <exception>
+
+#include <boost/config.hpp>
+#include <boost/context/execution_context.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+namespace detail {
+
+template< typename T >
+struct pull_coroutine< T >::control_block {
+ typename push_coroutine< T >::control_block * other;
+ boost::context::execution_context caller;
+ boost::context::execution_context callee;
+ bool preserve_fpu;
+ int state;
+ std::exception_ptr except;
+
+ template< typename StackAllocator, typename Fn >
+ control_block( context::preallocated, StackAllocator, Fn &&, bool);
+
+ explicit control_block( typename push_coroutine< T >::control_block *);
+
+ ~control_block();
+
+ control_block( control_block &) = delete;
+ control_block & operator=( control_block &) = delete;
+
+ void resume();
+
+ bool valid() const noexcept;
+};
+
+template< typename T >
+struct pull_coroutine< T & >::control_block {
+ typename push_coroutine< T & >::control_block * other;
+ boost::context::execution_context caller;
+ boost::context::execution_context callee;
+ bool preserve_fpu;
+ int state;
+ std::exception_ptr except;
+
+ template< typename StackAllocator, typename Fn >
+ control_block( context::preallocated, StackAllocator, Fn &&, bool);
+
+ explicit control_block( typename push_coroutine< T & >::control_block *);
+
+ ~control_block();
+
+ control_block( control_block &) = delete;
+ control_block & operator=( control_block &) = delete;
+
+ void resume();
+
+ bool valid() const noexcept;
+};
+
+struct pull_coroutine< void >::control_block {
+ push_coroutine< void >::control_block * other;
+ boost::context::execution_context caller;
+ boost::context::execution_context callee;
+ bool preserve_fpu;
+ int state;
+ std::exception_ptr except;
+
+ template< typename StackAllocator, typename Fn >
+ control_block( context::preallocated, StackAllocator, Fn &&, bool);
+
+ explicit control_block( push_coroutine< void >::control_block *);
+
+ ~control_block();
+
+ control_block( control_block &) = delete;
+ control_block & operator=( control_block &) = delete;
+
+ void resume();
+
+ bool valid() const noexcept;
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_DETAIL_PULL_CONTROL_BLOCK_HPP
diff --git a/boost/coroutine2/detail/pull_control_block.ipp b/boost/coroutine2/detail/pull_control_block.ipp
new file mode 100644
index 0000000000..fd806ecb21
--- /dev/null
+++ b/boost/coroutine2/detail/pull_control_block.ipp
@@ -0,0 +1,258 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_DETAIL_PULL_CONTROL_BLOCK_IPP
+#define BOOST_COROUTINES2_DETAIL_PULL_CONTROL_BLOCK_IPP
+
+#include <exception>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+
+#include <boost/context/execution_context.hpp>
+
+#include <boost/coroutine2/detail/config.hpp>
+#include <boost/coroutine2/detail/forced_unwind.hpp>
+#include <boost/coroutine2/detail/state.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+namespace detail {
+
+// pull_coroutine< T >
+
+template< typename T >
+template< typename StackAllocator, typename Fn >
+pull_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
+ Fn && fn_, bool preserve_fpu_) :
+ other( nullptr),
+ caller( boost::context::execution_context::current() ),
+ callee( palloc, salloc,
+ [=,fn=std::forward< Fn >( fn_)] () mutable -> decltype( auto) {
+ // create synthesized push_coroutine< T >
+ typename push_coroutine< T >::control_block synthesized_cb( this);
+ push_coroutine< T > synthesized( & synthesized_cb);
+ other = & synthesized_cb;
+ try {
+ // call coroutine-fn with synthesized push_coroutine as argument
+ fn( synthesized);
+ } catch ( forced_unwind const&) {
+ // do nothing for unwinding exception
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ // set termination flags
+ state |= static_cast< int >( state_t::complete);
+ // jump back to caller
+ caller( preserve_fpu);
+ BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
+ }),
+ preserve_fpu( preserve_fpu_),
+ state( static_cast< int >( state_t::unwind) ),
+ except() {
+ callee( preserve_fpu);
+}
+
+template< typename T >
+pull_coroutine< T >::control_block::control_block( typename push_coroutine< T >::control_block * cb) :
+ other( cb),
+ caller( other->callee),
+ callee( other->caller),
+ preserve_fpu( other->preserve_fpu),
+ state( 0),
+ except() {
+}
+
+template< typename T >
+pull_coroutine< T >::control_block::~control_block() {
+ if ( 0 == ( state & static_cast< int >( state_t::complete ) ) &&
+ 0 != ( state & static_cast< int >( state_t::unwind) ) ) {
+ // set early-exit flag
+ state |= static_cast< int >( state_t::early_exit);
+ callee( preserve_fpu);
+ }
+}
+
+template< typename T >
+void
+pull_coroutine< T >::control_block::resume() {
+ callee( preserve_fpu);
+ if ( except) {
+ std::rethrow_exception( except);
+ }
+ // test early-exit-flag
+ if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
+ throw forced_unwind();
+ }
+}
+
+template< typename T >
+bool
+pull_coroutine< T >::control_block::valid() const noexcept {
+ return nullptr != other && nullptr != other->t && 0 == ( state & static_cast< int >( state_t::complete) );
+}
+
+
+// pull_coroutine< T & >
+
+template< typename T >
+template< typename StackAllocator, typename Fn >
+pull_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
+ Fn && fn_, bool preserve_fpu_) :
+ other( nullptr),
+ caller( boost::context::execution_context::current() ),
+ callee( palloc, salloc,
+ [=,fn=std::forward< Fn >( fn_)] () mutable -> decltype( auto) {
+ // create synthesized push_coroutine< T >
+ typename push_coroutine< T & >::control_block synthesized_cb( this);
+ push_coroutine< T & > synthesized( & synthesized_cb);
+ other = & synthesized_cb;
+ try {
+ // call coroutine-fn with synthesized push_coroutine as argument
+ fn( synthesized);
+ } catch ( forced_unwind const&) {
+ // do nothing for unwinding exception
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ // set termination flags
+ state |= static_cast< int >( state_t::complete);
+ // jump back to caller
+ caller( preserve_fpu);
+ BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
+ }),
+ preserve_fpu( preserve_fpu_),
+ state( static_cast< int >( state_t::unwind) ),
+ except() {
+ callee( preserve_fpu);
+}
+
+template< typename T >
+pull_coroutine< T & >::control_block::control_block( typename push_coroutine< T & >::control_block * cb) :
+ other( cb),
+ caller( other->callee),
+ callee( other->caller),
+ preserve_fpu( other->preserve_fpu),
+ state( 0),
+ except() {
+}
+
+template< typename T >
+pull_coroutine< T & >::control_block::~control_block() {
+ if ( 0 == ( state & static_cast< int >( state_t::complete ) ) &&
+ 0 != ( state & static_cast< int >( state_t::unwind) ) ) {
+ // set early-exit flag
+ state |= static_cast< int >( state_t::early_exit);
+ callee( preserve_fpu);
+ }
+}
+
+template< typename T >
+void
+pull_coroutine< T & >::control_block::resume() {
+ callee( preserve_fpu);
+ if ( except) {
+ std::rethrow_exception( except);
+ }
+ // test early-exit-flag
+ if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
+ throw forced_unwind();
+ }
+}
+
+template< typename T >
+bool
+pull_coroutine< T & >::control_block::valid() const noexcept {
+ return nullptr != other && nullptr != other->t && 0 == ( state & static_cast< int >( state_t::complete) );
+}
+
+
+// pull_coroutine< void >
+
+template< typename StackAllocator, typename Fn >
+pull_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
+ Fn && fn_, bool preserve_fpu_) :
+ other( nullptr),
+ caller( boost::context::execution_context::current() ),
+ callee( palloc, salloc,
+ [=,fn=std::forward< Fn >( fn_)] () mutable -> decltype( auto) {
+ // create synthesized push_coroutine< T >
+ typename push_coroutine< void >::control_block synthesized_cb( this);
+ push_coroutine< void > synthesized( & synthesized_cb);
+ other = & synthesized_cb;
+ try {
+ // call coroutine-fn with synthesized push_coroutine as argument
+ fn( synthesized);
+ } catch ( forced_unwind const&) {
+ // do nothing for unwinding exception
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ // set termination flags
+ state |= static_cast< int >( state_t::complete);
+ // jump back to caller
+ caller( preserve_fpu);
+ BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
+ }),
+ preserve_fpu( preserve_fpu_),
+ state( static_cast< int >( state_t::unwind) ),
+ except() {
+ callee( preserve_fpu);
+}
+
+inline
+pull_coroutine< void >::control_block::control_block( push_coroutine< void >::control_block * cb) :
+ other( cb),
+ caller( other->callee),
+ callee( other->caller),
+ preserve_fpu( other->preserve_fpu),
+ state( 0),
+ except() {
+}
+
+inline
+pull_coroutine< void >::control_block::~control_block() {
+ if ( 0 == ( state & static_cast< int >( state_t::complete ) ) &&
+ 0 != ( state & static_cast< int >( state_t::unwind) ) ) {
+ // set early-exit flag
+ state |= static_cast< int >( state_t::early_exit);
+ callee( preserve_fpu);
+ }
+}
+
+inline
+void
+pull_coroutine< void >::control_block::resume() {
+ callee( preserve_fpu);
+ if ( except) {
+ std::rethrow_exception( except);
+ }
+ // test early-exit-flag
+ if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
+ throw forced_unwind();
+ }
+}
+
+inline
+bool
+pull_coroutine< void >::control_block::valid() const noexcept {
+ return nullptr != other && 0 == ( state & static_cast< int >( state_t::complete) );
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_DETAIL_PULL_CONTROL_BLOCK_IPP
diff --git a/boost/coroutine2/detail/pull_coroutine.hpp b/boost/coroutine2/detail/pull_coroutine.hpp
new file mode 100644
index 0000000000..ff76bd3aac
--- /dev/null
+++ b/boost/coroutine2/detail/pull_coroutine.hpp
@@ -0,0 +1,312 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_HPP
+#define BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_HPP
+
+#include <iterator>
+#include <type_traits>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/context/execution_context.hpp>
+
+#include <boost/coroutine2/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+namespace detail {
+
+template< typename T >
+class pull_coroutine {
+private:
+ template< typename X >
+ friend class push_coroutine;
+
+ struct control_block;
+
+ control_block * cb_;
+
+ explicit pull_coroutine( control_block *);
+
+ bool has_result_() const;
+
+public:
+ template< typename Fn >
+ explicit pull_coroutine( Fn &&, bool = false);
+
+ template< typename StackAllocator, typename Fn >
+ explicit pull_coroutine( StackAllocator, Fn &&, bool = false);
+
+ ~pull_coroutine();
+
+ pull_coroutine( pull_coroutine const&) = delete;
+ pull_coroutine & operator=( pull_coroutine const&) = delete;
+
+ pull_coroutine( pull_coroutine &&);
+
+ pull_coroutine & operator=( pull_coroutine && other) {
+ if ( this != & other) {
+ cb_ = other.cb_;
+ other.cb_ = nullptr;
+ }
+ return * this;
+ }
+
+ pull_coroutine & operator()();
+
+ explicit operator bool() const noexcept;
+
+ bool operator!() const noexcept;
+
+ T get() const noexcept;
+
+ class iterator : public std::iterator< std::input_iterator_tag, typename std::remove_reference< T >::type > {
+ private:
+ pull_coroutine< T > * c_;
+
+ void fetch_() {
+ BOOST_ASSERT( nullptr != c_);
+ if ( ! ( * c_) ) {
+ c_ = nullptr;
+ return;
+ }
+ }
+
+ void increment_() {
+ BOOST_ASSERT( nullptr != c_);
+ BOOST_ASSERT( * c_);
+ ( * c_)();
+ fetch_();
+ }
+
+ public:
+ typedef typename iterator::pointer pointer_t;
+ typedef typename iterator::reference reference_t;
+
+ iterator() :
+ c_( nullptr) {
+ }
+
+ explicit iterator( pull_coroutine< T > * c) :
+ c_( c) {
+ fetch_();
+ }
+
+ iterator( iterator const& other) :
+ c_( other.c_) {
+ }
+
+ iterator & operator=( iterator const& other) {
+ if ( this == & other) return * this;
+ c_ = other.c_;
+ return * this;
+ }
+
+ bool operator==( iterator const& other) const {
+ return other.c_ == c_;
+ }
+
+ bool operator!=( iterator const& other) const {
+ return other.c_ != c_;
+ }
+
+ iterator & operator++() {
+ increment_();
+ return * this;
+ }
+
+ iterator operator++( int) = delete;
+
+ reference_t operator*() const {
+ return * c_->cb_->other->t;
+ }
+
+ pointer_t operator->() const {
+ return c_->cb_->other->t;
+ }
+ };
+
+ friend class iterator;
+};
+
+template< typename T >
+class pull_coroutine< T & > {
+private:
+ template< typename X >
+ friend class push_coroutine;
+
+ struct control_block;
+
+ control_block * cb_;
+
+ explicit pull_coroutine( control_block *);
+
+ bool has_result_() const;
+
+public:
+ template< typename Fn >
+ explicit pull_coroutine( Fn &&, bool = false);
+
+ template< typename StackAllocator, typename Fn >
+ explicit pull_coroutine( StackAllocator, Fn &&, bool = false);
+
+ ~pull_coroutine();
+
+ pull_coroutine( pull_coroutine const&) = delete;
+ pull_coroutine & operator=( pull_coroutine const&) = delete;
+
+ pull_coroutine( pull_coroutine &&);
+
+ pull_coroutine & operator=( pull_coroutine && other) {
+ if ( this != & other) {
+ cb_ = other.cb_;
+ other.cb_ = nullptr;
+ }
+ return * this;
+ }
+
+ pull_coroutine & operator()();
+
+ explicit operator bool() const noexcept;
+
+ bool operator!() const noexcept;
+
+ T & get() const noexcept;
+
+ class iterator : public std::iterator< std::input_iterator_tag, typename std::remove_reference< T >::type > {
+ private:
+ pull_coroutine< T & > * c_;
+
+ void fetch_() {
+ BOOST_ASSERT( nullptr != c_);
+ if ( ! ( * c_) ) {
+ c_ = nullptr;
+ return;
+ }
+ }
+
+ void increment_() {
+ BOOST_ASSERT( nullptr != c_);
+ BOOST_ASSERT( * c_);
+ ( * c_)();
+ fetch_();
+ }
+
+ public:
+ typedef typename iterator::pointer pointer_t;
+ typedef typename iterator::reference reference_t;
+
+ iterator() :
+ c_( nullptr) {
+ }
+
+ explicit iterator( pull_coroutine< T & > * c) :
+ c_( c) {
+ fetch_();
+ }
+
+ iterator( iterator const& other) :
+ c_( other.c_) {
+ }
+
+ iterator & operator=( iterator const& other) {
+ if ( this == & other) return * this;
+ c_ = other.c_;
+ return * this;
+ }
+
+ bool operator==( iterator const& other) const {
+ return other.c_ == c_;
+ }
+
+ bool operator!=( iterator const& other) const {
+ return other.c_ != c_;
+ }
+
+ iterator & operator++() {
+ increment_();
+ return * this;
+ }
+
+ iterator operator++( int) = delete;
+
+ reference_t operator*() const {
+ return * c_->cb_->other->t;
+ }
+
+ pointer_t operator->() const {
+ return c_->cb_->other->t;
+ }
+ };
+
+ friend class iterator;
+};
+
+template<>
+class pull_coroutine< void > {
+private:
+ template< typename X >
+ friend class push_coroutine;
+
+ struct control_block;
+
+ control_block * cb_;
+
+ explicit pull_coroutine( control_block *);
+
+public:
+ template< typename Fn >
+ explicit pull_coroutine( Fn &&, bool = false);
+
+ template< typename StackAllocator, typename Fn >
+ explicit pull_coroutine( StackAllocator, Fn &&, bool = false);
+
+ ~pull_coroutine();
+
+ pull_coroutine( pull_coroutine const&) = delete;
+ pull_coroutine & operator=( pull_coroutine const&) = delete;
+
+ pull_coroutine( pull_coroutine &&);
+
+ pull_coroutine & operator=( pull_coroutine && other) {
+ if ( this != & other) {
+ cb_ = other.cb_;
+ other.cb_ = nullptr;
+ }
+ return * this;
+ }
+
+ pull_coroutine & operator()();
+
+ explicit operator bool() const noexcept;
+
+ bool operator!() const noexcept;
+};
+
+template< typename T >
+typename pull_coroutine< T >::iterator
+begin( pull_coroutine< T > & c) {
+ return typename pull_coroutine< T >::iterator( & c);
+}
+
+template< typename T >
+typename pull_coroutine< T >::iterator
+end( pull_coroutine< T > &) {
+ return typename pull_coroutine< T >::iterator();
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_HPP
diff --git a/boost/coroutine2/detail/pull_coroutine.ipp b/boost/coroutine2/detail/pull_coroutine.ipp
new file mode 100644
index 0000000000..f59bb3cb5f
--- /dev/null
+++ b/boost/coroutine2/detail/pull_coroutine.ipp
@@ -0,0 +1,271 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_IPP
+#define BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_IPP
+
+#include <algorithm>
+#include <memory>
+#include <utility>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+
+#include <boost/context/execution_context.hpp>
+#include <boost/context/stack_context.hpp>
+
+#include <boost/coroutine2/detail/config.hpp>
+#include <boost/coroutine2/fixedsize_stack.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+namespace detail {
+
+// pull_coroutine< T >
+
+template< typename T >
+pull_coroutine< T >::pull_coroutine( control_block * cb) :
+ cb_( cb) {
+}
+
+template< typename T >
+bool
+pull_coroutine< T >::has_result_() const {
+ return nullptr != cb_->other->t;
+}
+
+template< typename T >
+template< typename Fn >
+pull_coroutine< T >::pull_coroutine( Fn && fn, bool preserve_fpu) :
+ pull_coroutine( fixedsize_stack(), std::forward< Fn >( fn), preserve_fpu) {
+}
+
+template< typename T >
+template< typename StackAllocator, typename Fn >
+pull_coroutine< T >::pull_coroutine( StackAllocator salloc, Fn && fn, bool preserve_fpu) :
+ cb_( nullptr) {
+ context::stack_context sctx( salloc.allocate() );
+ // reserve space for control structure
+#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN)
+ void * sp = static_cast< char * >( sctx.sp) - sizeof( control_block);
+ std::size_t size = sctx.size - sizeof( control_block);
+#else
+ constexpr std::size_t func_alignment = 64; // alignof( control_block);
+ constexpr std::size_t func_size = sizeof( control_block);
+ // reserve space on stack
+ void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment;
+ // align sp pointer
+ std::size_t space = func_size + func_alignment;
+ sp = std::align( func_alignment, func_size, sp, space);
+ BOOST_ASSERT( nullptr != sp);
+ // calculate remaining size
+ std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) );
+#endif
+ // placment new for control structure on coroutine stack
+ cb_ = new ( sp) control_block( context::preallocated( sp, size, sctx),
+ salloc, std::forward< Fn >( fn), preserve_fpu);
+}
+
+template< typename T >
+pull_coroutine< T >::~pull_coroutine() {
+ if ( nullptr != cb_) {
+ cb_->~control_block();
+ }
+}
+
+template< typename T >
+pull_coroutine< T >::pull_coroutine( pull_coroutine && other) :
+ cb_( other.cb_) {
+ other.cb_ = nullptr;
+}
+
+template< typename T >
+pull_coroutine< T > &
+pull_coroutine< T >::operator()() {
+ cb_->resume();
+ return * this;
+}
+
+template< typename T >
+pull_coroutine< T >::operator bool() const noexcept {
+ return nullptr != cb_ && cb_->valid();
+}
+
+template< typename T >
+bool
+pull_coroutine< T >::operator!() const noexcept {
+ return nullptr == cb_ || ! cb_->valid();
+}
+
+template< typename T >
+T
+pull_coroutine< T >::get() const noexcept {
+ return std::move( * cb_->other->t);
+}
+
+
+// pull_coroutine< T & >
+
+template< typename T >
+pull_coroutine< T & >::pull_coroutine( control_block * cb) :
+ cb_( cb) {
+}
+
+template< typename T >
+bool
+pull_coroutine< T & >::has_result_() const {
+ return nullptr != cb_->other->t;
+}
+
+template< typename T >
+template< typename Fn >
+pull_coroutine< T & >::pull_coroutine( Fn && fn, bool preserve_fpu) :
+ pull_coroutine( fixedsize_stack(), std::forward< Fn >( fn), preserve_fpu) {
+}
+
+template< typename T >
+template< typename StackAllocator, typename Fn >
+pull_coroutine< T & >::pull_coroutine( StackAllocator salloc, Fn && fn, bool preserve_fpu) :
+ cb_( nullptr) {
+ context::stack_context sctx( salloc.allocate() );
+ // reserve space for control structure
+#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN)
+ void * sp = static_cast< char * >( sctx.sp) - sizeof( control_block);
+ std::size_t size = sctx.size - sizeof( control_block);
+#else
+ constexpr std::size_t func_alignment = 64; // alignof( control_block);
+ constexpr std::size_t func_size = sizeof( control_block);
+ // reserve space on stack
+ void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment;
+ // align sp pointer
+ std::size_t space = func_size + func_alignment;
+ sp = std::align( func_alignment, func_size, sp, space);
+ BOOST_ASSERT( nullptr != sp);
+ // calculate remaining size
+ std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) );
+#endif
+ // placment new for control structure on coroutine stack
+ cb_ = new ( sp) control_block( context::preallocated( sp, size, sctx),
+ salloc, std::forward< Fn >( fn), preserve_fpu);
+}
+
+template< typename T >
+pull_coroutine< T & >::~pull_coroutine() {
+ if ( nullptr != cb_) {
+ cb_->~control_block();
+ }
+}
+
+template< typename T >
+pull_coroutine< T & >::pull_coroutine( pull_coroutine && other) :
+ cb_( other.cb_) {
+ other.cb_ = nullptr;
+}
+
+template< typename T >
+pull_coroutine< T & > &
+pull_coroutine< T & >::operator()() {
+ cb_->resume();
+ return * this;
+}
+
+template< typename T >
+pull_coroutine< T & >::operator bool() const noexcept {
+ return nullptr != cb_ && cb_->valid();
+}
+
+template< typename T >
+bool
+pull_coroutine< T & >::operator!() const noexcept {
+ return nullptr == cb_ || ! cb_->valid();
+}
+
+template< typename T >
+T &
+pull_coroutine< T & >::get() const noexcept {
+ return * cb_->other->t;
+}
+
+
+// pull_coroutine< void >
+
+inline
+pull_coroutine< void >::pull_coroutine( control_block * cb) :
+ cb_( cb) {
+}
+
+template< typename Fn >
+pull_coroutine< void >::pull_coroutine( Fn && fn, bool preserve_fpu) :
+ pull_coroutine( fixedsize_stack(), std::forward< Fn >( fn), preserve_fpu) {
+}
+
+template< typename StackAllocator, typename Fn >
+pull_coroutine< void >::pull_coroutine( StackAllocator salloc, Fn && fn, bool preserve_fpu) :
+ cb_( nullptr) {
+ context::stack_context sctx( salloc.allocate() );
+ // reserve space for control structure
+#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN)
+ void * sp = static_cast< char * >( sctx.sp) - sizeof( control_block);
+ std::size_t size = sctx.size - sizeof( control_block);
+#else
+ constexpr std::size_t func_alignment = 64; // alignof( control_block);
+ constexpr std::size_t func_size = sizeof( control_block);
+ // reserve space on stack
+ void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment;
+ // align sp pointer
+ std::size_t space = func_size + func_alignment;
+ sp = std::align( func_alignment, func_size, sp, space);
+ BOOST_ASSERT( nullptr != sp);
+ // calculate remaining size
+ std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) );
+#endif
+ // placment new for control structure on coroutine stack
+ cb_ = new ( sp) control_block( context::preallocated( sp, size, sctx),
+ salloc, std::forward< Fn >( fn), preserve_fpu);
+}
+
+inline
+pull_coroutine< void >::~pull_coroutine() {
+ if ( nullptr != cb_) {
+ cb_->~control_block();
+ }
+}
+
+inline
+pull_coroutine< void >::pull_coroutine( pull_coroutine && other) :
+ cb_( other.cb_) {
+ other.cb_ = nullptr;
+}
+
+inline
+pull_coroutine< void > &
+pull_coroutine< void >::operator()() {
+ cb_->resume();
+ return * this;
+}
+
+inline
+pull_coroutine< void >::operator bool() const noexcept {
+ return nullptr != cb_ && cb_->valid();
+}
+
+inline
+bool
+pull_coroutine< void >::operator!() const noexcept {
+ return nullptr == cb_ || ! cb_->valid();
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_IPP
diff --git a/boost/coroutine2/detail/push_control_block.hpp b/boost/coroutine2/detail/push_control_block.hpp
new file mode 100644
index 0000000000..e6c86ffd81
--- /dev/null
+++ b/boost/coroutine2/detail/push_control_block.hpp
@@ -0,0 +1,104 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_HPP
+#define BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_HPP
+
+#include <exception>
+
+#include <boost/config.hpp>
+#include <boost/context/execution_context.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+namespace detail {
+
+template< typename T >
+struct push_coroutine< T >::control_block {
+ typename pull_coroutine< T >::control_block * other;
+ boost::context::execution_context caller;
+ boost::context::execution_context callee;
+ bool preserve_fpu;
+ int state;
+ std::exception_ptr except;
+ T * t;
+
+ template< typename StackAllocator, typename Fn >
+ control_block( context::preallocated, StackAllocator, Fn &&, bool);
+
+ explicit control_block( typename pull_coroutine< T >::control_block *);
+
+ ~control_block();
+
+ control_block( control_block &) = delete;
+ control_block & operator=( control_block &) = delete;
+
+ void resume( T const&);
+
+ void resume( T &&);
+
+ bool valid() const noexcept;
+};
+
+template< typename T >
+struct push_coroutine< T & >::control_block {
+ typename pull_coroutine< T & >::control_block * other;
+ boost::context::execution_context caller;
+ boost::context::execution_context callee;
+ bool preserve_fpu;
+ int state;
+ std::exception_ptr except;
+ T * t;
+
+ template< typename StackAllocator, typename Fn >
+ control_block( context::preallocated, StackAllocator, Fn &&, bool);
+
+ explicit control_block( typename pull_coroutine< T & >::control_block *);
+
+ ~control_block();
+
+ control_block( control_block &) = delete;
+ control_block & operator=( control_block &) = delete;
+
+ void resume( T &);
+
+ bool valid() const noexcept;
+};
+
+struct push_coroutine< void >::control_block {
+ pull_coroutine< void >::control_block * other;
+ boost::context::execution_context caller;
+ boost::context::execution_context callee;
+ bool preserve_fpu;
+ int state;
+ std::exception_ptr except;
+
+ template< typename StackAllocator, typename Fn >
+ control_block( context::preallocated, StackAllocator, Fn &&, bool);
+
+ explicit control_block( pull_coroutine< void >::control_block *);
+
+ ~control_block();
+
+ control_block( control_block &) = delete;
+ control_block & operator=( control_block &) = delete;
+
+ void resume();
+
+ bool valid() const noexcept;
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_HPP
diff --git a/boost/coroutine2/detail/push_control_block.ipp b/boost/coroutine2/detail/push_control_block.ipp
new file mode 100644
index 0000000000..ebef5092b5
--- /dev/null
+++ b/boost/coroutine2/detail/push_control_block.ipp
@@ -0,0 +1,281 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_IPP
+#define BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_IPP
+
+#include <algorithm>
+#include <exception>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+
+#include <boost/context/execution_context.hpp>
+
+#include <boost/coroutine2/detail/config.hpp>
+#include <boost/coroutine2/detail/forced_unwind.hpp>
+#include <boost/coroutine2/detail/state.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+namespace detail {
+
+// push_coroutine< T >
+
+template< typename T >
+template< typename StackAllocator, typename Fn >
+push_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
+ Fn && fn_, bool preserve_fpu_) :
+ other( nullptr),
+ caller( boost::context::execution_context::current() ),
+ callee( palloc, salloc,
+ [=,fn=std::forward< Fn >( fn_)] () mutable -> decltype( auto) {
+ // create synthesized pull_coroutine< T >
+ typename pull_coroutine< T >::control_block synthesized_cb( this);
+ pull_coroutine< T > synthesized( & synthesized_cb);
+ other = & synthesized_cb;
+ try {
+ // call coroutine-fn with synthesized pull_coroutine as argument
+ fn( synthesized);
+ } catch ( forced_unwind const&) {
+ // do nothing for unwinding exception
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ // set termination flags
+ state |= static_cast< int >( state_t::complete);
+ caller( preserve_fpu);
+ BOOST_ASSERT_MSG( false, "push_coroutine is complete");
+ }),
+ preserve_fpu( preserve_fpu_),
+ state( static_cast< int >( state_t::unwind) ),
+ except(),
+ t( nullptr) {
+}
+
+template< typename T >
+push_coroutine< T >::control_block::control_block( typename pull_coroutine< T >::control_block * cb) :
+ other( cb),
+ caller( other->callee),
+ callee( other->caller),
+ preserve_fpu( other->preserve_fpu),
+ state( 0),
+ except(),
+ t( nullptr) {
+}
+
+template< typename T >
+push_coroutine< T >::control_block::~control_block() {
+ if ( 0 == ( state & static_cast< int >( state_t::complete ) ) &&
+ 0 != ( state & static_cast< int >( state_t::unwind) ) ) {
+ // set early-exit flag
+ state |= static_cast< int >( state_t::early_exit);
+ callee( preserve_fpu);
+ }
+}
+
+template< typename T >
+void
+push_coroutine< T >::control_block::resume( T const& t_) {
+ // store data on this stack
+ // pass an pointer (address of tmp) to other context
+ T tmp( t_);
+ t = & tmp;
+ callee( preserve_fpu);
+ t = nullptr;
+ if ( except) {
+ std::rethrow_exception( except);
+ }
+ // test early-exit-flag
+ if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
+ throw forced_unwind();
+ }
+}
+
+template< typename T >
+void
+push_coroutine< T >::control_block::resume( T && t_) {
+ // store data on this stack
+ // pass an pointer (address of tmp) to other context
+ T tmp( std::move( t_) );
+ t = & tmp;
+ callee( preserve_fpu);
+ t = nullptr;
+ if ( except) {
+ std::rethrow_exception( except);
+ }
+ // test early-exit-flag
+ if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
+ throw forced_unwind();
+ }
+}
+
+template< typename T >
+bool
+push_coroutine< T >::control_block::valid() const noexcept {
+ return 0 == ( state & static_cast< int >( state_t::complete) );
+}
+
+
+// push_coroutine< T & >
+
+template< typename T >
+template< typename StackAllocator, typename Fn >
+push_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
+ Fn && fn_, bool preserve_fpu_) :
+ other( nullptr),
+ caller( boost::context::execution_context::current() ),
+ callee( palloc, salloc,
+ [=,fn=std::forward< Fn >( fn_)] () mutable -> decltype( auto) {
+ // create synthesized pull_coroutine< T >
+ typename pull_coroutine< T & >::control_block synthesized_cb( this);
+ pull_coroutine< T & > synthesized( & synthesized_cb);
+ other = & synthesized_cb;
+ try {
+ // call coroutine-fn with synthesized pull_coroutine as argument
+ fn( synthesized);
+ } catch ( forced_unwind const&) {
+ // do nothing for unwinding exception
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ // set termination flags
+ state |= static_cast< int >( state_t::complete);
+ caller( preserve_fpu);
+ BOOST_ASSERT_MSG( false, "push_coroutine is complete");
+ }),
+ preserve_fpu( preserve_fpu_),
+ state( static_cast< int >( state_t::unwind) ),
+ except(),
+ t( nullptr) {
+}
+
+template< typename T >
+push_coroutine< T & >::control_block::control_block( typename pull_coroutine< T & >::control_block * cb) :
+ other( cb),
+ caller( other->callee),
+ callee( other->caller),
+ preserve_fpu( other->preserve_fpu),
+ state( 0),
+ except(),
+ t( nullptr) {
+}
+
+template< typename T >
+push_coroutine< T & >::control_block::~control_block() {
+ if ( 0 == ( state & static_cast< int >( state_t::complete ) ) &&
+ 0 != ( state & static_cast< int >( state_t::unwind) ) ) {
+ // set early-exit flag
+ state |= static_cast< int >( state_t::early_exit);
+ callee( preserve_fpu);
+ }
+}
+
+template< typename T >
+void
+push_coroutine< T & >::control_block::resume( T & t_) {
+ t = & t_;
+ callee( preserve_fpu);
+ t = nullptr;
+ if ( except) {
+ std::rethrow_exception( except);
+ }
+ // test early-exit-flag
+ if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
+ throw forced_unwind();
+ }
+}
+
+template< typename T >
+bool
+push_coroutine< T & >::control_block::valid() const noexcept {
+ return 0 == ( state & static_cast< int >( state_t::complete) );
+}
+
+
+// push_coroutine< void >
+
+template< typename StackAllocator, typename Fn >
+push_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator salloc, Fn && fn_, bool preserve_fpu_) :
+ other( nullptr),
+ caller( boost::context::execution_context::current() ),
+ callee( palloc, salloc,
+ [=,fn=std::forward< Fn >( fn_)] () mutable -> decltype( auto) {
+ // create synthesized pull_coroutine< T >
+ typename pull_coroutine< void >::control_block synthesized_cb( this);
+ pull_coroutine< void > synthesized( & synthesized_cb);
+ other = & synthesized_cb;
+ try {
+ // call coroutine-fn with synthesized pull_coroutine as argument
+ fn( synthesized);
+ } catch ( forced_unwind const&) {
+ // do nothing for unwinding exception
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ // set termination flags
+ state |= static_cast< int >( state_t::complete);
+ caller( preserve_fpu);
+ BOOST_ASSERT_MSG( false, "push_coroutine is complete");
+ }),
+ preserve_fpu( preserve_fpu_),
+ state( static_cast< int >( state_t::unwind) ),
+ except() {
+}
+
+inline
+push_coroutine< void >::control_block::control_block( pull_coroutine< void >::control_block * cb) :
+ other( cb),
+ caller( other->callee),
+ callee( other->caller),
+ preserve_fpu( other->preserve_fpu),
+ state( 0),
+ except() {
+}
+
+inline
+push_coroutine< void >::control_block::~control_block() {
+ if ( 0 == ( state & static_cast< int >( state_t::complete ) ) &&
+ 0 != ( state & static_cast< int >( state_t::unwind) ) ) {
+ // set early-exit flag
+ state |= static_cast< int >( state_t::early_exit);
+ callee( preserve_fpu);
+ }
+}
+
+inline
+void
+push_coroutine< void >::control_block::resume() {
+ callee( preserve_fpu);
+ if ( except) {
+ std::rethrow_exception( except);
+ }
+ // test early-exit-flag
+ if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
+ throw forced_unwind();
+ }
+}
+
+inline
+bool
+push_coroutine< void >::control_block::valid() const noexcept {
+ return 0 == ( state & static_cast< int >( state_t::complete) );
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_IPP
diff --git a/boost/coroutine2/detail/push_coroutine.hpp b/boost/coroutine2/detail/push_coroutine.hpp
new file mode 100644
index 0000000000..1a2d01f67e
--- /dev/null
+++ b/boost/coroutine2/detail/push_coroutine.hpp
@@ -0,0 +1,242 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_DETAIL_PUSH_COROUTINE_HPP
+#define BOOST_COROUTINES2_DETAIL_PUSH_COROUTINE_HPP
+
+#include <iterator>
+#include <type_traits>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/context/execution_context.hpp>
+
+#include <boost/coroutine2/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+namespace detail {
+
+template< typename T >
+class push_coroutine {
+private:
+ template< typename X >
+ friend class pull_coroutine;
+
+ struct control_block;
+
+ control_block * cb_;
+
+ explicit push_coroutine( control_block *);
+
+public:
+ template< typename Fn >
+ explicit push_coroutine( Fn &&, bool = false);
+
+ template< typename StackAllocator, typename Fn >
+ explicit push_coroutine( StackAllocator, Fn &&, bool = false);
+
+ ~push_coroutine();
+
+ push_coroutine( push_coroutine const&) = delete;
+ push_coroutine & operator=( push_coroutine const&) = delete;
+
+ push_coroutine( push_coroutine &&);
+
+ push_coroutine & operator=( push_coroutine && other) {
+ if ( this != & other) {
+ cb_ = other.cb_;
+ other.cb_ = nullptr;
+ }
+ return * this;
+ }
+
+ push_coroutine & operator()( T const&);
+
+ push_coroutine & operator()( T &&);
+
+ explicit operator bool() const noexcept;
+
+ bool operator!() const noexcept;
+
+ class iterator : public std::iterator< std::output_iterator_tag, void, void, void, void > {
+ private:
+ push_coroutine< T > * c_;
+
+ public:
+ iterator() :
+ c_( nullptr) {
+ }
+
+ explicit iterator( push_coroutine< T > * c) :
+ c_( c) {
+ }
+
+ iterator & operator=( T t) {
+ BOOST_ASSERT( c_);
+ if ( ! ( * c_)( t) ) c_ = 0;
+ return * this;
+ }
+
+ bool operator==( iterator const& other) const {
+ return other.c_ == c_;
+ }
+
+ bool operator!=( iterator const& other) const {
+ return other.c_ != c_;
+ }
+
+ iterator & operator*() {
+ return * this;
+ }
+
+ iterator & operator++() {
+ return * this;
+ }
+ };
+};
+
+template< typename T >
+class push_coroutine< T & > {
+private:
+ template< typename X >
+ friend class pull_coroutine;
+
+ struct control_block;
+
+ control_block * cb_;
+
+ explicit push_coroutine( control_block *);
+
+public:
+ template< typename Fn >
+ explicit push_coroutine( Fn &&, bool = false);
+
+ template< typename StackAllocator, typename Fn >
+ explicit push_coroutine( StackAllocator, Fn &&, bool = false);
+
+ ~push_coroutine();
+
+ push_coroutine( push_coroutine const&) = delete;
+ push_coroutine & operator=( push_coroutine const&) = delete;
+
+ push_coroutine( push_coroutine &&);
+
+ push_coroutine & operator=( push_coroutine && other) {
+ if ( this != & other) {
+ cb_ = other.cb_;
+ other.cb_ = nullptr;
+ }
+ return * this;
+ }
+
+ push_coroutine & operator()( T &);
+
+ explicit operator bool() const noexcept;
+
+ bool operator!() const noexcept;
+
+ class iterator : public std::iterator< std::output_iterator_tag, void, void, void, void > {
+ private:
+ push_coroutine< T & > * c_;
+
+ public:
+ iterator() :
+ c_( nullptr) {
+ }
+
+ explicit iterator( push_coroutine< T & > * c) :
+ c_( c) {
+ }
+
+ iterator & operator=( T & t) {
+ BOOST_ASSERT( c_);
+ if ( ! ( * c_)( t) ) c_ = 0;
+ return * this;
+ }
+
+ bool operator==( iterator const& other) const {
+ return other.c_ == c_;
+ }
+
+ bool operator!=( iterator const& other) const {
+ return other.c_ != c_;
+ }
+
+ iterator & operator*() {
+ return * this;
+ }
+
+ iterator & operator++() {
+ return * this;
+ }
+ };
+};
+
+template<>
+class push_coroutine< void > {
+private:
+ template< typename X >
+ friend class pull_coroutine;
+
+ struct control_block;
+
+ control_block * cb_;
+
+ explicit push_coroutine( control_block *);
+
+public:
+ template< typename Fn >
+ explicit push_coroutine( Fn &&, bool = false);
+
+ template< typename StackAllocator, typename Fn >
+ explicit push_coroutine( StackAllocator, Fn &&, bool = false);
+
+ ~push_coroutine();
+
+ push_coroutine( push_coroutine const&) = delete;
+ push_coroutine & operator=( push_coroutine const&) = delete;
+
+ push_coroutine( push_coroutine &&);
+
+ push_coroutine & operator=( push_coroutine && other) {
+ if ( this != & other) {
+ cb_ = other.cb_;
+ other.cb_ = nullptr;
+ }
+ return * this;
+ }
+
+ push_coroutine & operator()();
+
+ explicit operator bool() const noexcept;
+
+ bool operator!() const noexcept;
+};
+
+template< typename T >
+typename push_coroutine< T >::iterator
+begin( push_coroutine< T > & c) {
+ return typename push_coroutine< T >::iterator( & c);
+}
+
+template< typename T >
+typename push_coroutine< T >::iterator
+end( push_coroutine< T > &) {
+ return typename push_coroutine< T >::iterator();
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_DETAIL_PUSH_COROUTINE_HPP
diff --git a/boost/coroutine2/detail/push_coroutine.ipp b/boost/coroutine2/detail/push_coroutine.ipp
new file mode 100644
index 0000000000..4617e73aac
--- /dev/null
+++ b/boost/coroutine2/detail/push_coroutine.ipp
@@ -0,0 +1,253 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_DETAIL_PUSH_COROUTINE_IPP
+#define BOOST_COROUTINES2_DETAIL_PUSH_COROUTINE_IPP
+
+#include <memory>
+#include <utility>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+
+#include <boost/context/execution_context.hpp>
+#include <boost/context/stack_context.hpp>
+
+#include <boost/coroutine2/detail/config.hpp>
+#include <boost/coroutine2/fixedsize_stack.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+namespace detail {
+
+// push_coroutine< T >
+
+template< typename T >
+push_coroutine< T >::push_coroutine( control_block * cb) :
+ cb_( cb) {
+}
+
+template< typename T >
+template< typename Fn >
+push_coroutine< T >::push_coroutine( Fn && fn, bool preserve_fpu) :
+ push_coroutine( fixedsize_stack(), std::forward< Fn >( fn), preserve_fpu) {
+}
+
+template< typename T >
+template< typename StackAllocator, typename Fn >
+push_coroutine< T >::push_coroutine( StackAllocator salloc, Fn && fn, bool preserve_fpu) :
+ cb_( nullptr) {
+ context::stack_context sctx( salloc.allocate() );
+ // reserve space for control structure
+#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN)
+ void * sp = static_cast< char * >( sctx.sp) - sizeof( control_block);
+ std::size_t size = sctx.size - sizeof( control_block);
+#else
+ constexpr std::size_t func_alignment = 64; // alignof( control_block);
+ constexpr std::size_t func_size = sizeof( control_block);
+ // reserve space on stack
+ void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment;
+ // align sp pointer
+ std::size_t space = func_size + func_alignment;
+ sp = std::align( func_alignment, func_size, sp, space);
+ BOOST_ASSERT( nullptr != sp);
+ // calculate remaining size
+ std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) );
+#endif
+ // placment new for control structure on coroutine stack
+ cb_= new ( sp) control_block( context::preallocated( sp, size, sctx),
+ salloc, std::forward< Fn >( fn), preserve_fpu);
+}
+
+template< typename T >
+push_coroutine< T >::~push_coroutine() {
+ if ( nullptr != cb_) {
+ cb_->~control_block();
+ }
+}
+
+template< typename T >
+push_coroutine< T >::push_coroutine( push_coroutine && other) :
+ cb_( other.cb_) {
+ other.cb_ = nullptr;
+}
+
+template< typename T >
+push_coroutine< T > &
+push_coroutine< T >::operator()( T const& t) {
+ cb_->resume( t);
+ return * this;
+}
+
+template< typename T >
+push_coroutine< T > &
+push_coroutine< T >::operator()( T && t) {
+ cb_->resume( std::forward< T >( t) );
+ return * this;
+}
+
+template< typename T >
+push_coroutine< T >::operator bool() const noexcept {
+ return nullptr != cb_ && cb_->valid();
+}
+
+template< typename T >
+bool
+push_coroutine< T >::operator!() const noexcept {
+ return nullptr == cb_ || ! cb_->valid();
+}
+
+
+// push_coroutine< T & >
+
+template< typename T >
+push_coroutine< T & >::push_coroutine( control_block * cb) :
+ cb_( cb) {
+}
+
+template< typename T >
+template< typename Fn >
+push_coroutine< T & >::push_coroutine( Fn && fn, bool preserve_fpu) :
+ push_coroutine( fixedsize_stack(), std::forward< Fn >( fn), preserve_fpu) {
+}
+
+template< typename T >
+template< typename StackAllocator, typename Fn >
+push_coroutine< T & >::push_coroutine( StackAllocator salloc, Fn && fn, bool preserve_fpu) :
+ cb_( nullptr) {
+ context::stack_context sctx( salloc.allocate() );
+ // reserve space for control structure
+#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN)
+ void * sp = static_cast< char * >( sctx.sp) - sizeof( control_block);
+ std::size_t size = sctx.size - sizeof( control_block);
+#else
+ constexpr std::size_t func_alignment = 64; // alignof( control_block);
+ constexpr std::size_t func_size = sizeof( control_block);
+ // reserve space on stack
+ void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment;
+ // align sp pointer
+ std::size_t space = func_size + func_alignment;
+ sp = std::align( func_alignment, func_size, sp, space);
+ BOOST_ASSERT( nullptr != sp);
+ // calculate remaining size
+ std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) );
+#endif
+ // placment new for control structure on coroutine stack
+ cb_ = new ( sp) control_block( context::preallocated( sp, size, sctx),
+ salloc, std::forward< Fn >( fn), preserve_fpu);
+}
+
+template< typename T >
+push_coroutine< T & >::~push_coroutine() {
+ if ( nullptr != cb_) {
+ cb_->~control_block();
+ }
+}
+
+template< typename T >
+push_coroutine< T & >::push_coroutine( push_coroutine && other) :
+ cb_( other.cb_) {
+ other.cb_ = nullptr;
+}
+
+template< typename T >
+push_coroutine< T & > &
+push_coroutine< T & >::operator()( T & t) {
+ cb_->resume( t);
+ return * this;
+}
+
+template< typename T >
+push_coroutine< T & >::operator bool() const noexcept {
+ return nullptr != cb_ && cb_->valid();
+}
+
+template< typename T >
+bool
+push_coroutine< T & >::operator!() const noexcept {
+ return nullptr == cb_ || ! cb_->valid();
+}
+
+
+// push_coroutine< void >
+
+inline
+push_coroutine< void >::push_coroutine( control_block * cb) :
+ cb_( cb) {
+}
+
+template< typename Fn >
+push_coroutine< void >::push_coroutine( Fn && fn, bool preserve_fpu) :
+ push_coroutine( fixedsize_stack(), std::forward< Fn >( fn), preserve_fpu) {
+}
+
+template< typename StackAllocator, typename Fn >
+push_coroutine< void >::push_coroutine( StackAllocator salloc, Fn && fn, bool preserve_fpu) :
+ cb_( nullptr) {
+ context::stack_context sctx( salloc.allocate() );
+ // reserve space for control structure
+#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN)
+ void * sp = static_cast< char * >( sctx.sp) - sizeof( control_block);
+ std::size_t size = sctx.size - sizeof( control_block);
+#else
+ constexpr std::size_t func_alignment = 64; // alignof( control_block);
+ constexpr std::size_t func_size = sizeof( control_block);
+ // reserve space on stack
+ void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment;
+ // align sp pointer
+ std::size_t space = func_size + func_alignment;
+ sp = std::align( func_alignment, func_size, sp, space);
+ BOOST_ASSERT( nullptr != sp);
+ // calculate remaining size
+ std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) );
+#endif
+ // placment new for control structure on coroutine stack
+ cb_ = new ( sp) control_block( context::preallocated( sp, size, sctx),
+ salloc, std::forward< Fn >( fn), preserve_fpu);
+}
+
+inline
+push_coroutine< void >::~push_coroutine() {
+ if ( nullptr != cb_) {
+ cb_->~control_block();
+ }
+}
+
+inline
+push_coroutine< void >::push_coroutine( push_coroutine && other) :
+ cb_( other.cb_) {
+ other.cb_ = nullptr;
+}
+
+inline
+push_coroutine< void > &
+push_coroutine< void >::operator()() {
+ cb_->resume();
+ return * this;
+}
+
+inline
+push_coroutine< void >::operator bool() const noexcept {
+ return nullptr != cb_ && cb_->valid();
+}
+
+inline
+bool
+push_coroutine< void >::operator!() const noexcept {
+ return nullptr == cb_ || ! cb_->valid();
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_DETAIL_PUSH_COROUTINE_IPP
diff --git a/boost/coroutine2/detail/state.hpp b/boost/coroutine2/detail/state.hpp
new file mode 100644
index 0000000000..714548ff63
--- /dev/null
+++ b/boost/coroutine2/detail/state.hpp
@@ -0,0 +1,37 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_DETAIL_ASYMMETRIC_COROUTINE_HPP
+#define BOOST_COROUTINES2_DETAIL_ASYMMETRIC_COROUTINE_HPP
+
+#include <exception>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+
+#include <boost/coroutine2/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+namespace detail {
+
+enum class state_t : unsigned int {
+ complete = 1 << 1,
+ unwind = 1 << 2,
+ early_exit = 1 << 3
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_DETAIL_ASYMMETRIC_COROUTINE_HPP
diff --git a/boost/coroutine2/fixedsize_stack.hpp b/boost/coroutine2/fixedsize_stack.hpp
new file mode 100644
index 0000000000..56523ab29a
--- /dev/null
+++ b/boost/coroutine2/fixedsize_stack.hpp
@@ -0,0 +1,33 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_FIXEDSIZE_H
+#define BOOST_COROUTINES2_FIXEDSIZE_H
+
+#include <exception>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/context/fixedsize_stack.hpp>
+
+#include <boost/coroutine2/detail/coroutine.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+
+typedef boost::context::fixedsize_stack fixedsize_stack;
+
+}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_FIXEDSIZE_H
diff --git a/boost/coroutine2/protected_fixedsize_stack.hpp b/boost/coroutine2/protected_fixedsize_stack.hpp
new file mode 100644
index 0000000000..d2ee279775
--- /dev/null
+++ b/boost/coroutine2/protected_fixedsize_stack.hpp
@@ -0,0 +1,33 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_PROTECTED_FIXEDSIZE_H
+#define BOOST_COROUTINES2_PROTECTED_FIXEDSIZE_H
+
+#include <exception>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/context/protected_fixedsize_stack.hpp>
+
+#include <boost/coroutine2/detail/coroutine.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+
+typedef boost::context::protected_fixedsize_stack protected_fixedsize_stack;
+
+}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_PROTECTED_FIXEDSIZE_H
diff --git a/boost/coroutine2/segmented_stack.hpp b/boost/coroutine2/segmented_stack.hpp
new file mode 100644
index 0000000000..a252ae445f
--- /dev/null
+++ b/boost/coroutine2/segmented_stack.hpp
@@ -0,0 +1,37 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_SEGMENTED_H
+#define BOOST_COROUTINES2_SEGMENTED_H
+
+#include <exception>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/context/segmented_stack.hpp>
+
+#include <boost/coroutine2/detail/coroutine.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+# if ! defined(BOOST_WINDOWS)
+typedef boost::context::segmented_stack segmented_stack;
+# endif
+#endif
+
+}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_SEGMENTED_H
diff --git a/boost/format/exceptions.hpp b/boost/format/exceptions.hpp
index 9b2de834cf..56ee30dce0 100644
--- a/boost/format/exceptions.hpp
+++ b/boost/format/exceptions.hpp
@@ -73,7 +73,7 @@ namespace boost {
std::size_t get_expected() const { return expected_; }
virtual const char *what() const throw() {
return "boost::too_many_args: "
- "format-string referred to less arguments than were passed";
+ "format-string referred to fewer arguments than were passed";
}
};
diff --git a/boost/format/feed_args.hpp b/boost/format/feed_args.hpp
index dcfd955b36..95bbe5e252 100644
--- a/boost/format/feed_args.hpp
+++ b/boost/format/feed_args.hpp
@@ -274,7 +274,7 @@ namespace detail {
template< class Ch, class Tr, class Alloc, class T>
void distribute (basic_format<Ch,Tr, Alloc>& self, T x) {
- // call put(x, ..) on every occurence of the current argument :
+ // call put(x, ..) on every occurrence of the current argument :
if(self.cur_arg_ >= self.num_args_) {
if( self.exceptions() & too_many_args_bit )
boost::throw_exception(too_many_args(self.cur_arg_, self.num_args_));
diff --git a/boost/format/parsing.hpp b/boost/format/parsing.hpp
index 27c53ba8d7..04ddf368e1 100644
--- a/boost/format/parsing.hpp
+++ b/boost/format/parsing.hpp
@@ -50,7 +50,7 @@ namespace detail {
# else
(void) fac; // remove "unused parameter" warning
using namespace std;
- return isdigit(c);
+ return isdigit(c) != 0;
#endif
}
diff --git a/boost/function/function_base.hpp b/boost/function/function_base.hpp
index 9e01ef94af..35c1995ece 100644
--- a/boost/function/function_base.hpp
+++ b/boost/function/function_base.hpp
@@ -25,7 +25,6 @@
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/composite_traits.hpp>
-#include <boost/type_traits/ice.hpp>
#include <boost/ref.hpp>
#include <boost/mpl/if.hpp>
#include <boost/detail/workaround.hpp>
@@ -72,19 +71,10 @@
# define BOOST_FUNCTION_TARGET_FIX(x)
#endif // __ICL etc
-#if !BOOST_WORKAROUND(__BORLANDC__, < 0x5A0)
# define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type) \
- typename ::boost::enable_if_c<(::boost::type_traits::ice_not< \
- (::boost::is_integral<Functor>::value)>::value), \
+ typename ::boost::enable_if_c< \
+ !(::boost::is_integral<Functor>::value), \
Type>::type
-#else
-// BCC doesn't recognize this depends on a template argument and complains
-// about the use of 'typename'
-# define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type) \
- ::boost::enable_if_c<(::boost::type_traits::ice_not< \
- (::boost::is_integral<Functor>::value)>::value), \
- Type>::type
-#endif
namespace boost {
namespace detail {
diff --git a/boost/function/function_template.hpp b/boost/function/function_template.hpp
index ab7abc5143..211b81dbe3 100644
--- a/boost/function/function_template.hpp
+++ b/boost/function/function_template.hpp
@@ -717,9 +717,8 @@ namespace boost {
template<typename Functor>
BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
#ifndef BOOST_NO_SFINAE
- ,typename enable_if_c<
- (boost::type_traits::ice_not<
- (is_integral<Functor>::value)>::value),
+ ,typename boost::enable_if_c<
+ !(is_integral<Functor>::value),
int>::type = 0
#endif // BOOST_NO_SFINAE
) :
@@ -730,9 +729,8 @@ namespace boost {
template<typename Functor,typename Allocator>
BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a
#ifndef BOOST_NO_SFINAE
- ,typename enable_if_c<
- (boost::type_traits::ice_not<
- (is_integral<Functor>::value)>::value),
+ ,typename boost::enable_if_c<
+ !(is_integral<Functor>::value),
int>::type = 0
#endif // BOOST_NO_SFINAE
) :
@@ -780,9 +778,8 @@ namespace boost {
// construct.
template<typename Functor>
#ifndef BOOST_NO_SFINAE
- typename enable_if_c<
- (boost::type_traits::ice_not<
- (is_integral<Functor>::value)>::value),
+ typename boost::enable_if_c<
+ !(is_integral<Functor>::value),
BOOST_FUNCTION_FUNCTION&>::type
#else
BOOST_FUNCTION_FUNCTION&
@@ -1068,9 +1065,8 @@ public:
template<typename Functor>
function(Functor f
#ifndef BOOST_NO_SFINAE
- ,typename enable_if_c<
- (boost::type_traits::ice_not<
- (is_integral<Functor>::value)>::value),
+ ,typename boost::enable_if_c<
+ !(is_integral<Functor>::value),
int>::type = 0
#endif
) :
@@ -1080,9 +1076,8 @@ public:
template<typename Functor,typename Allocator>
function(Functor f, Allocator a
#ifndef BOOST_NO_SFINAE
- ,typename enable_if_c<
- (boost::type_traits::ice_not<
- (is_integral<Functor>::value)>::value),
+ ,typename boost::enable_if_c<
+ !(is_integral<Functor>::value),
int>::type = 0
#endif
) :
@@ -1120,9 +1115,8 @@ public:
template<typename Functor>
#ifndef BOOST_NO_SFINAE
- typename enable_if_c<
- (boost::type_traits::ice_not<
- (is_integral<Functor>::value)>::value),
+ typename boost::enable_if_c<
+ !(is_integral<Functor>::value),
self_type&>::type
#else
self_type&
diff --git a/boost/function_types/components.hpp b/boost/function_types/components.hpp
index d348682b82..6f22098d58 100644
--- a/boost/function_types/components.hpp
+++ b/boost/function_types/components.hpp
@@ -15,7 +15,6 @@
#include <boost/detail/workaround.hpp>
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/type_traits/integral_constant.hpp>
@@ -416,8 +415,6 @@ namespace boost
} } // namespace function_types::detail
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::components)
-
} // namespace ::boost
#include <boost/function_types/detail/components_as_mpl_sequence.hpp>
diff --git a/boost/function_types/detail/classifier.hpp b/boost/function_types/detail/classifier.hpp
index 03f3419b9f..b5c5e71ebe 100644
--- a/boost/function_types/detail/classifier.hpp
+++ b/boost/function_types/detail/classifier.hpp
@@ -11,7 +11,6 @@
#include <boost/type.hpp>
#include <boost/config.hpp>
-#include <boost/type_traits/config.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/add_reference.hpp>
@@ -31,7 +30,13 @@ template<bits_t Flags, bits_t CCID, std::size_t Arity> struct encode_charr
>::type type;
};
-char BOOST_TT_DECL classifier_impl(...);
+#if defined(BOOST_MSVC) || (defined(__BORLANDC__) && !defined(BOOST_DISABLE_WIN32))
+# define BOOST_FT_DECL __cdecl
+#else
+# define BOOST_FT_DECL /**/
+#endif
+
+char BOOST_FT_DECL classifier_impl(...);
#define BOOST_FT_variations BOOST_FT_function|BOOST_FT_pointer|\
BOOST_FT_member_pointer
diff --git a/boost/function_types/function_arity.hpp b/boost/function_types/function_arity.hpp
index 40f0f653cc..a81001be3f 100644
--- a/boost/function_types/function_arity.hpp
+++ b/boost/function_types/function_arity.hpp
@@ -13,7 +13,6 @@
#include <boost/mpl/if.hpp>
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/function_types/is_callable_builtin.hpp>
#include <boost/function_types/components.hpp>
@@ -31,7 +30,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,function_arity,(T))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1,function_types::function_arity)
}
#endif
diff --git a/boost/function_types/function_pointer.hpp b/boost/function_types/function_pointer.hpp
index a8b832f32b..cb139187f0 100644
--- a/boost/function_types/function_pointer.hpp
+++ b/boost/function_types/function_pointer.hpp
@@ -10,7 +10,6 @@
#define BOOST_FT_FUNCTION_POINTER_HPP_INCLUDED
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/function_types/function_type.hpp>
@@ -25,7 +24,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,function_pointer,(Types,Tag))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::function_pointer)
}
#endif
diff --git a/boost/function_types/function_reference.hpp b/boost/function_types/function_reference.hpp
index 5fe7e3cc8b..3eceae00ea 100644
--- a/boost/function_types/function_reference.hpp
+++ b/boost/function_types/function_reference.hpp
@@ -10,7 +10,6 @@
#define BOOST_FT_FUNCTION_REFERENCE_HPP_INCLUDED
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/function_types/function_type.hpp>
@@ -25,7 +24,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,function_reference,(Types,Tag))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::function_reference)
}
#endif
diff --git a/boost/function_types/function_type.hpp b/boost/function_types/function_type.hpp
index c3b2c96b94..afe3654a7c 100644
--- a/boost/function_types/function_type.hpp
+++ b/boost/function_types/function_type.hpp
@@ -22,7 +22,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,function_type,(Types,Tag))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::function_type)
}
#endif
diff --git a/boost/function_types/is_callable_builtin.hpp b/boost/function_types/is_callable_builtin.hpp
index b1a7c833ba..3b826ea580 100644
--- a/boost/function_types/is_callable_builtin.hpp
+++ b/boost/function_types/is_callable_builtin.hpp
@@ -10,7 +10,6 @@
#define BOOST_FT_IS_CALLABLE_BUILTIN_HPP_INCLUDED
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/function_types/components.hpp>
@@ -28,7 +27,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_callable_builtin,(T,Tag))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::is_callable_builtin)
}
#endif
diff --git a/boost/function_types/is_function.hpp b/boost/function_types/is_function.hpp
index d29229bb69..09f75b1c18 100644
--- a/boost/function_types/is_function.hpp
+++ b/boost/function_types/is_function.hpp
@@ -9,7 +9,6 @@
#define BOOST_FT_IS_FUNCTION_HPP_INCLUDED
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/function_types/components.hpp>
@@ -27,7 +26,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_function,(T,Tag))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::is_function)
}
#endif
diff --git a/boost/function_types/is_function_pointer.hpp b/boost/function_types/is_function_pointer.hpp
index 5bff6d36d9..67a04026f4 100644
--- a/boost/function_types/is_function_pointer.hpp
+++ b/boost/function_types/is_function_pointer.hpp
@@ -10,7 +10,6 @@
#define BOOST_FT_IS_FUNCTION_POINTER_HPP_INCLUDED
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/function_types/components.hpp>
@@ -28,7 +27,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_function_pointer,(T,Tag))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::is_function_pointer)
}
#endif
diff --git a/boost/function_types/is_function_reference.hpp b/boost/function_types/is_function_reference.hpp
index f2e4c1c605..6bf908dc5d 100644
--- a/boost/function_types/is_function_reference.hpp
+++ b/boost/function_types/is_function_reference.hpp
@@ -10,7 +10,6 @@
#define BOOST_FT_IS_FUNCTION_REFERENCE_HPP_INCLUDED
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/function_types/components.hpp>
@@ -27,7 +26,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_function_reference,(T,Tag))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::is_function_reference)
}
#endif
diff --git a/boost/function_types/is_member_function_pointer.hpp b/boost/function_types/is_member_function_pointer.hpp
index a51903520b..ef547657a3 100644
--- a/boost/function_types/is_member_function_pointer.hpp
+++ b/boost/function_types/is_member_function_pointer.hpp
@@ -10,7 +10,6 @@
#define BOOST_FT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/function_types/components.hpp>
@@ -27,7 +26,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_member_function_pointer,(T,Tag))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::is_member_function_pointer)
}
#endif
diff --git a/boost/function_types/is_member_object_pointer.hpp b/boost/function_types/is_member_object_pointer.hpp
index 77527d9a3d..10bc89a163 100644
--- a/boost/function_types/is_member_object_pointer.hpp
+++ b/boost/function_types/is_member_object_pointer.hpp
@@ -10,7 +10,6 @@
#define BOOST_FT_IS_MEMBER_OBJECT_POINTER_HPP_INCLUDED
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/function_types/components.hpp>
@@ -27,7 +26,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_member_object_pointer,(T))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1,function_types::is_member_object_pointer)
}
#endif
diff --git a/boost/function_types/is_member_pointer.hpp b/boost/function_types/is_member_pointer.hpp
index f53e0beb71..db1da29dc4 100644
--- a/boost/function_types/is_member_pointer.hpp
+++ b/boost/function_types/is_member_pointer.hpp
@@ -9,7 +9,6 @@
#define BOOST_FT_IS_MEMBER_POINTER_HPP_INCLUDED
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/function_types/components.hpp>
@@ -27,7 +26,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_member_pointer,(T,Tag))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::is_member_pointer)
}
#endif
diff --git a/boost/function_types/is_nonmember_callable_builtin.hpp b/boost/function_types/is_nonmember_callable_builtin.hpp
index 3a27a2e7f7..61052858b7 100644
--- a/boost/function_types/is_nonmember_callable_builtin.hpp
+++ b/boost/function_types/is_nonmember_callable_builtin.hpp
@@ -10,7 +10,6 @@
#define BOOST_FT_IS_NONMEMBER_CALLABLE_BUILTIN_HPP_INCLUDED
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/function_types/components.hpp>
@@ -28,7 +27,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_nonmember_callable_builtin,(T,Tag))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::is_nonmember_callable_builtin)
}
#endif
diff --git a/boost/function_types/member_function_pointer.hpp b/boost/function_types/member_function_pointer.hpp
index eab61118cb..104271f103 100644
--- a/boost/function_types/member_function_pointer.hpp
+++ b/boost/function_types/member_function_pointer.hpp
@@ -10,7 +10,6 @@
#define BOOST_FT_MEMBER_FUNCTION_POINTER_HPP_INCLUDED
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/function_types/detail/synthesize.hpp>
#include <boost/function_types/detail/to_sequence.hpp>
@@ -26,7 +25,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,member_function_pointer,(Types,Tag))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::member_function_pointer)
}
#endif
diff --git a/boost/function_types/member_object_pointer.hpp b/boost/function_types/member_object_pointer.hpp
index d0aa3f3418..1951654550 100644
--- a/boost/function_types/member_object_pointer.hpp
+++ b/boost/function_types/member_object_pointer.hpp
@@ -10,7 +10,6 @@
#define BOOST_FT_MEMBER_OBJECT_POINTER_HPP_INCLUDED
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/function_types/detail/synthesize.hpp>
#include <boost/function_types/detail/to_sequence.hpp>
@@ -26,7 +25,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,member_object_pointer,(Types))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1,function_types::member_object_pointer)
}
#endif
diff --git a/boost/function_types/parameter_types.hpp b/boost/function_types/parameter_types.hpp
index 5e049bf59c..227ad27325 100644
--- a/boost/function_types/parameter_types.hpp
+++ b/boost/function_types/parameter_types.hpp
@@ -13,7 +13,6 @@
#include <boost/mpl/if.hpp>
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/mpl/pop_front.hpp>
@@ -48,7 +47,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,parameter_types,(T,ClassTypeTransform))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::parameter_types)
}
#endif
diff --git a/boost/function_types/result_type.hpp b/boost/function_types/result_type.hpp
index 1fcaba6622..db642c88c6 100644
--- a/boost/function_types/result_type.hpp
+++ b/boost/function_types/result_type.hpp
@@ -13,7 +13,6 @@
#include <boost/mpl/if.hpp>
#include <boost/mpl/aux_/lambda_support.hpp>
-#include <boost/type_traits/detail/template_arity_spec.hpp>
#include <boost/mpl/at.hpp>
@@ -43,7 +42,6 @@ namespace boost
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,result_type,(T))
};
}
- BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1,function_types::result_type)
}
#endif
diff --git a/boost/fusion/adapted/std_tuple/detail/build_std_tuple.hpp b/boost/fusion/adapted/std_tuple/detail/build_std_tuple.hpp
index 41e0d434e8..b60dc76fcc 100644
--- a/boost/fusion/adapted/std_tuple/detail/build_std_tuple.hpp
+++ b/boost/fusion/adapted/std_tuple/detail/build_std_tuple.hpp
@@ -7,26 +7,26 @@
#if !defined(BOOST_FUSION_BUILD_STD_TUPLE_05292014_0100)
#define BOOST_FUSION_BUILD_STD_TUPLE_05292014_0100
-#include <boost/mpl/eval_if.hpp>
-#include <boost/mpl/identity.hpp>
#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/support/detail/index_sequence.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/iterator/next.hpp>
#include <boost/fusion/iterator/value_of.hpp>
#include <boost/fusion/iterator/deref.hpp>
#include <tuple>
+#include <cstddef>
namespace boost { namespace fusion { namespace detail
{
- template <typename First, typename Last
- , bool is_empty = result_of::equal_to<First, Last>::value
- >
+ template <typename First, typename Last,
+ bool is_empty = result_of::equal_to<First, Last>::value>
struct build_std_tuple;
template <typename First, typename Last>
struct build_std_tuple<First, Last, true>
{
typedef std::tuple<> type;
+
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
static type
call(First const&, Last const&)
@@ -35,35 +35,18 @@ namespace boost { namespace fusion { namespace detail
}
};
- template <int ...> struct indexed_tuple { };
-
- template <int, typename = indexed_tuple<>>
- struct make_indexed_tuple;
-
- template <int Head, int ...Tail>
- struct make_indexed_tuple<Head, indexed_tuple<Tail...>>
- {
- typedef typename
- boost::mpl::eval_if_c<
- (Head == 0),
- boost::mpl::identity<indexed_tuple<Tail...>>,
- make_indexed_tuple<Head - 1, indexed_tuple<Head - 1, Tail...>>
- >::type
- type;
- };
-
template <typename T, typename Rest>
struct push_front_std_tuple;
template <typename T, typename ...Rest>
- struct push_front_std_tuple<T, std::tuple<Rest...>>
+ struct push_front_std_tuple<T, std::tuple<Rest...> >
{
typedef std::tuple<T, Rest...> type;
- template <int ...I>
+ template <std::size_t ...I>
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
static type
- indexed_call(T const& first, std::tuple<Rest...> const& rest, indexed_tuple<I...>)
+ indexed_call(T const& first, std::tuple<Rest...> const& rest, index_sequence<I...>)
{
return type(first, std::get<I>(rest)...);
}
@@ -72,7 +55,7 @@ namespace boost { namespace fusion { namespace detail
static type
call(T const& first, std::tuple<Rest...> const& rest)
{
- typedef typename make_indexed_tuple<sizeof...(Rest)>::type gen;
+ typedef typename make_index_sequence<sizeof...(Rest)>::type gen;
return indexed_call(first, rest, gen());
}
};
diff --git a/boost/fusion/adapted/struct/adapt_struct.hpp b/boost/fusion/adapted/struct/adapt_struct.hpp
index e96e7c76d2..2744f5b218 100644
--- a/boost/fusion/adapted/struct/adapt_struct.hpp
+++ b/boost/fusion/adapted/struct/adapt_struct.hpp
@@ -17,6 +17,8 @@
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/comparison/less.hpp>
#include <boost/preprocessor/comparison/equal.hpp>
+#include <boost/preprocessor/seq/seq.hpp>
+#include <boost/preprocessor/variadic/to_seq.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/add_const.hpp>
@@ -61,25 +63,28 @@
(1)NAME_SEQ, \
struct_tag, \
0, \
- BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER(__VA_ARGS__), \
+ BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER( \
+ BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)), \
BOOST_FUSION_ADAPT_STRUCT_C)
-# define BOOST_FUSION_ADAPT_STRUCT(NAME, ...) \
+# define BOOST_FUSION_ADAPT_STRUCT(...) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(0), \
- (0)(NAME), \
+ (0)(BOOST_PP_SEQ_HEAD(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))), \
struct_tag, \
0, \
- BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER(__VA_ARGS__), \
+ BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER( \
+ BOOST_PP_SEQ_TAIL(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))), \
BOOST_FUSION_ADAPT_STRUCT_C)
-# define BOOST_FUSION_ADAPT_STRUCT_AS_VIEW(NAME, ...) \
+# define BOOST_FUSION_ADAPT_STRUCT_AS_VIEW(...) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(0), \
- (0)(NAME), \
+ (0)(BOOST_PP_SEQ_HEAD(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))), \
struct_tag, \
1, \
- BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER(__VA_ARGS__), \
+ BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER( \
+ BOOST_PP_SEQ_TAIL(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))), \
BOOST_FUSION_ADAPT_STRUCT_C)
#else // BOOST_PP_VARIADICS
diff --git a/boost/fusion/adapted/struct/detail/adapt_base_attr_filler.hpp b/boost/fusion/adapted/struct/detail/adapt_base_attr_filler.hpp
index 69d5b204ce..7a83bb347c 100644
--- a/boost/fusion/adapted/struct/detail/adapt_base_attr_filler.hpp
+++ b/boost/fusion/adapted/struct/detail/adapt_base_attr_filler.hpp
@@ -49,14 +49,16 @@
# define BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER_OP(r, unused, elem) \
BOOST_PP_IF(BOOST_FUSION_PP_IS_SEQ(elem), \
BOOST_PP_CAT( BOOST_FUSION_ADAPT_STRUCT_FILLER_0 elem ,_END), \
- BOOST_FUSION_ADAPT_STRUCT_WRAP_ATTR(BOOST_FUSION_ADAPT_AUTO, \
- elem))
+ BOOST_PP_IF(BOOST_PP_IS_EMPTY(elem), \
+ BOOST_PP_EMPTY(), \
+ BOOST_FUSION_ADAPT_STRUCT_WRAP_ATTR(BOOST_FUSION_ADAPT_AUTO,elem))\
+ )
-# define BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER(...) \
+# define BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER(VA_ARGS_SEQ) \
BOOST_PP_SEQ_PUSH_FRONT( \
BOOST_PP_SEQ_FOR_EACH( \
BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER_OP, \
- unused, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)), \
+ unused, VA_ARGS_SEQ), \
(0,0))
#endif // BOOST_PP_VARIADICS
diff --git a/boost/fusion/adapted/struct/detail/define_struct.hpp b/boost/fusion/adapted/struct/detail/define_struct.hpp
index 25542920ad..ce3737ea97 100644
--- a/boost/fusion/adapted/struct/detail/define_struct.hpp
+++ b/boost/fusion/adapted/struct/detail/define_struct.hpp
@@ -69,7 +69,7 @@
ATTRIBUTES_SEQ, ATTRIBUTE_TUPEL_SIZE) \
\
template<typename Seq> \
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
+ BOOST_FUSION_GPU_ENABLED \
self_type& \
operator=(Seq const& seq) \
{ \
@@ -128,7 +128,7 @@
ATTRIBUTE_TUPEL_SIZE, \
ATTRIBUTES_SEQ) \
\
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
+ BOOST_FUSION_GPU_ENABLED \
NAME() \
: BOOST_PP_SEQ_FOR_EACH_I_R( \
1, \
@@ -137,7 +137,7 @@
ATTRIBUTES_SEQ) \
{} \
\
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
+ BOOST_FUSION_GPU_ENABLED \
NAME(self_type const& other_self) \
: BOOST_PP_SEQ_FOR_EACH_I_R( \
1, \
@@ -147,7 +147,7 @@
{} \
\
template<typename Seq> \
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
+ BOOST_FUSION_GPU_ENABLED \
NAME(Seq const& seq \
BOOST_PP_IF( \
BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ)), \
@@ -167,7 +167,7 @@
#define BOOST_FUSION_DEFINE_STRUCT_CTOR_1( \
NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPEL_SIZE) \
\
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
+ BOOST_FUSION_GPU_ENABLED \
explicit \
NAME(boost::call_traits< \
BOOST_PP_TUPLE_ELEM( \
@@ -180,7 +180,7 @@
#define BOOST_FUSION_DEFINE_TPL_STRUCT_CTOR_1( \
TEMPLATE_PARAMS_SEQ, NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPEL_SIZE) \
\
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
+ BOOST_FUSION_GPU_ENABLED \
explicit \
NAME(typename boost::call_traits< \
typename boost::fusion::detail::get_first_arg< \
@@ -217,7 +217,7 @@
#define BOOST_FUSION_DEFINE_TPL_STRUCT_CTOR_N( \
TEMPLATE_PARAMS_SEQ, NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPEL_SIZE) \
\
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
+ BOOST_FUSION_GPU_ENABLED \
NAME(BOOST_PP_SEQ_FOR_EACH_I_R( \
1, \
BOOST_FUSION_DEFINE_TPL_STRUCT_CTOR_ARG_I, \
@@ -245,7 +245,7 @@
#define BOOST_FUSION_DEFINE_STRUCT_CTOR_N( \
NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPEL_SIZE) \
\
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
+ BOOST_FUSION_GPU_ENABLED \
NAME(BOOST_PP_SEQ_FOR_EACH_I_R( \
1, \
BOOST_FUSION_DEFINE_STRUCT_CTOR_ARG_I, \
diff --git a/boost/fusion/adapted/struct/detail/define_struct_inline.hpp b/boost/fusion/adapted/struct/detail/define_struct_inline.hpp
index a5a3ae0628..a037ffe549 100644
--- a/boost/fusion/adapted/struct/detail/define_struct_inline.hpp
+++ b/boost/fusion/adapted/struct/detail/define_struct_inline.hpp
@@ -66,7 +66,7 @@
#define BOOST_FUSION_IGNORE_2(ARG1, ARG2)
#define BOOST_FUSION_MAKE_COPY_CONSTRUCTOR(NAME, ATTRIBUTES_SEQ) \
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
+ BOOST_FUSION_GPU_ENABLED \
NAME(BOOST_PP_SEQ_FOR_EACH_I( \
BOOST_FUSION_MAKE_CONST_REF_PARAM, \
~, \
@@ -337,7 +337,7 @@
typedef boost::mpl::int_<N> index; \
typedef boost_fusion_detail_Seq sequence_type; \
\
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
+ BOOST_FUSION_GPU_ENABLED \
BOOST_FUSION_ITERATOR_NAME(NAME)(boost_fusion_detail_Seq& seq) \
: seq_(seq) \
BOOST_FUSION_DEFINE_ITERATOR_WKND_INIT_LIST_ENTRIES( \
diff --git a/boost/fusion/algorithm/iteration/reverse_fold.hpp b/boost/fusion/algorithm/iteration/reverse_fold.hpp
index 76e6bf2575..dffff79e14 100644
--- a/boost/fusion/algorithm/iteration/reverse_fold.hpp
+++ b/boost/fusion/algorithm/iteration/reverse_fold.hpp
@@ -10,6 +10,7 @@
#define BOOST_FUSION_ALGORITHM_ITERATION_REVERSE_FOLD_HPP
#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/support/detail/result_of.hpp>
#include <boost/fusion/algorithm/iteration/reverse_fold_fwd.hpp>
#include <boost/config.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
diff --git a/boost/fusion/algorithm/iteration/reverse_iter_fold.hpp b/boost/fusion/algorithm/iteration/reverse_iter_fold.hpp
index e49f8b8310..d36861f37b 100644
--- a/boost/fusion/algorithm/iteration/reverse_iter_fold.hpp
+++ b/boost/fusion/algorithm/iteration/reverse_iter_fold.hpp
@@ -9,6 +9,7 @@
#define BOOST_FUSION_ALGORITHM_ITERATION_REVERSE_ITER_FOLD_HPP
#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/support/detail/result_of.hpp>
#include <boost/fusion/algorithm/iteration/reverse_iter_fold_fwd.hpp>
#include <boost/config.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
diff --git a/boost/fusion/container/deque/detail/cpp03/deque.hpp b/boost/fusion/container/deque/detail/cpp03/deque.hpp
index 7c9417e53b..db8a967ab0 100644
--- a/boost/fusion/container/deque/detail/cpp03/deque.hpp
+++ b/boost/fusion/container/deque/detail/cpp03/deque.hpp
@@ -94,13 +94,13 @@ namespace boost { namespace fusion {
{}
template<BOOST_PP_ENUM_PARAMS(FUSION_MAX_DEQUE_SIZE, typename U)>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(deque<BOOST_PP_ENUM_PARAMS(FUSION_MAX_DEQUE_SIZE, U)> const& seq)
: base(seq)
{}
template<typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(Sequence const& seq, typename disable_if<is_convertible<Sequence, T0> >::type* /*dummy*/ = 0)
: base(base::from_iterator(fusion::begin(seq)))
{}
@@ -129,7 +129,7 @@ FUSION_HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \
(defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
template <typename T0_>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
explicit deque(T0_&& t0
, typename enable_if<is_convertible<T0_, T0> >::type* /*dummy*/ = 0
)
@@ -140,7 +140,7 @@ FUSION_HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
: base(std::forward<deque>(rhs))
{}
template<BOOST_PP_ENUM_PARAMS(FUSION_MAX_DEQUE_SIZE, typename U)>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(deque<BOOST_PP_ENUM_PARAMS(FUSION_MAX_DEQUE_SIZE, U)>&& seq
, typename disable_if<
is_convertible<deque<BOOST_PP_ENUM_PARAMS(FUSION_MAX_DEQUE_SIZE, U)>, T0>
diff --git a/boost/fusion/container/deque/detail/cpp03/deque_keyed_values.hpp b/boost/fusion/container/deque/detail/cpp03/deque_keyed_values.hpp
index 21b4934546..fcbd74a7e9 100644
--- a/boost/fusion/container/deque/detail/cpp03/deque_keyed_values.hpp
+++ b/boost/fusion/container/deque/detail/cpp03/deque_keyed_values.hpp
@@ -24,7 +24,6 @@
#include <boost/mpl/plus.hpp>
#include <boost/mpl/int.hpp>
-#include <boost/mpl/print.hpp>
#define FUSION_VOID(z, n, _) void_
diff --git a/boost/fusion/container/deque/detail/cpp03/limits.hpp b/boost/fusion/container/deque/detail/cpp03/limits.hpp
index 7892ba1a82..16e25fa081 100644
--- a/boost/fusion/container/deque/detail/cpp03/limits.hpp
+++ b/boost/fusion/container/deque/detail/cpp03/limits.hpp
@@ -12,7 +12,7 @@
#error "C++03 only! This file should not have been included"
#endif
-#include <boost/fusion/container/vector/limits.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/limits.hpp>
#if !defined(FUSION_MAX_DEQUE_SIZE)
# define FUSION_MAX_DEQUE_SIZE FUSION_MAX_VECTOR_SIZE
diff --git a/boost/fusion/container/deque/detail/cpp03/preprocessed/deque10.hpp b/boost/fusion/container/deque/detail/cpp03/preprocessed/deque10.hpp
index 7f71696143..ae1828a5f7 100644
--- a/boost/fusion/container/deque/detail/cpp03/preprocessed/deque10.hpp
+++ b/boost/fusion/container/deque/detail/cpp03/preprocessed/deque10.hpp
@@ -195,12 +195,12 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
: base(rhs)
{}
template<typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9> const& seq)
: base(seq)
{}
template<typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(Sequence const& seq, typename disable_if<is_convertible<Sequence, T0> >::type* = 0)
: base(base::from_iterator(fusion::begin(seq)))
{}
@@ -222,7 +222,7 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
}
# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename T0_>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
explicit deque(T0_&& t0
, typename enable_if<is_convertible<T0_, T0> >::type* = 0
)
@@ -233,7 +233,7 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
: base(std::forward<deque>(rhs))
{}
template<typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9>&& seq
, typename disable_if<
is_convertible<deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9>, T0>
diff --git a/boost/fusion/container/deque/detail/cpp03/preprocessed/deque20.hpp b/boost/fusion/container/deque/detail/cpp03/preprocessed/deque20.hpp
index 949b2a4590..78224634bb 100644
--- a/boost/fusion/container/deque/detail/cpp03/preprocessed/deque20.hpp
+++ b/boost/fusion/container/deque/detail/cpp03/preprocessed/deque20.hpp
@@ -375,12 +375,12 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
: base(rhs)
{}
template<typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19> const& seq)
: base(seq)
{}
template<typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(Sequence const& seq, typename disable_if<is_convertible<Sequence, T0> >::type* = 0)
: base(base::from_iterator(fusion::begin(seq)))
{}
@@ -402,7 +402,7 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
}
# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename T0_>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
explicit deque(T0_&& t0
, typename enable_if<is_convertible<T0_, T0> >::type* = 0
)
@@ -413,7 +413,7 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
: base(std::forward<deque>(rhs))
{}
template<typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19>&& seq
, typename disable_if<
is_convertible<deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19>, T0>
diff --git a/boost/fusion/container/deque/detail/cpp03/preprocessed/deque30.hpp b/boost/fusion/container/deque/detail/cpp03/preprocessed/deque30.hpp
index 65a9264d86..8653217bc0 100644
--- a/boost/fusion/container/deque/detail/cpp03/preprocessed/deque30.hpp
+++ b/boost/fusion/container/deque/detail/cpp03/preprocessed/deque30.hpp
@@ -555,12 +555,12 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
: base(rhs)
{}
template<typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29> const& seq)
: base(seq)
{}
template<typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(Sequence const& seq, typename disable_if<is_convertible<Sequence, T0> >::type* = 0)
: base(base::from_iterator(fusion::begin(seq)))
{}
@@ -582,7 +582,7 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
}
# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename T0_>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
explicit deque(T0_&& t0
, typename enable_if<is_convertible<T0_, T0> >::type* = 0
)
@@ -593,7 +593,7 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
: base(std::forward<deque>(rhs))
{}
template<typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29>&& seq
, typename disable_if<
is_convertible<deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29>, T0>
diff --git a/boost/fusion/container/deque/detail/cpp03/preprocessed/deque40.hpp b/boost/fusion/container/deque/detail/cpp03/preprocessed/deque40.hpp
index 13bf4213c1..3bfd488af2 100644
--- a/boost/fusion/container/deque/detail/cpp03/preprocessed/deque40.hpp
+++ b/boost/fusion/container/deque/detail/cpp03/preprocessed/deque40.hpp
@@ -735,12 +735,12 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
: base(rhs)
{}
template<typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39> const& seq)
: base(seq)
{}
template<typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(Sequence const& seq, typename disable_if<is_convertible<Sequence, T0> >::type* = 0)
: base(base::from_iterator(fusion::begin(seq)))
{}
@@ -762,7 +762,7 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
}
# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename T0_>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
explicit deque(T0_&& t0
, typename enable_if<is_convertible<T0_, T0> >::type* = 0
)
@@ -773,7 +773,7 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
: base(std::forward<deque>(rhs))
{}
template<typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39>&& seq
, typename disable_if<
is_convertible<deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39>, T0>
diff --git a/boost/fusion/container/deque/detail/cpp03/preprocessed/deque50.hpp b/boost/fusion/container/deque/detail/cpp03/preprocessed/deque50.hpp
index 51ae53d2a5..04441da66c 100644
--- a/boost/fusion/container/deque/detail/cpp03/preprocessed/deque50.hpp
+++ b/boost/fusion/container/deque/detail/cpp03/preprocessed/deque50.hpp
@@ -915,12 +915,12 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
: base(rhs)
{}
template<typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43 , typename U44 , typename U45 , typename U46 , typename U47 , typename U48 , typename U49>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44 , U45 , U46 , U47 , U48 , U49> const& seq)
: base(seq)
{}
template<typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(Sequence const& seq, typename disable_if<is_convertible<Sequence, T0> >::type* = 0)
: base(base::from_iterator(fusion::begin(seq)))
{}
@@ -942,7 +942,7 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
}
# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename T0_>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
explicit deque(T0_&& t0
, typename enable_if<is_convertible<T0_, T0> >::type* = 0
)
@@ -953,7 +953,7 @@ deque(T_0 && t0 , T_1 && t1 , T_2 && t2 , T_3 && t3 , T_4 && t4 , T_5 && t5 , T_
: base(std::forward<deque>(rhs))
{}
template<typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43 , typename U44 , typename U45 , typename U46 , typename U47 , typename U48 , typename U49>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
deque(deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44 , U45 , U46 , U47 , U48 , U49>&& seq
, typename disable_if<
is_convertible<deque<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44 , U45 , U46 , U47 , U48 , U49>, T0>
diff --git a/boost/fusion/container/generation/detail/pp_list_tie.hpp b/boost/fusion/container/generation/detail/pp_list_tie.hpp
new file mode 100644
index 0000000000..be25627ae8
--- /dev/null
+++ b/boost/fusion/container/generation/detail/pp_list_tie.hpp
@@ -0,0 +1,102 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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_PP_IS_ITERATING
+#if !defined(FUSION_PP_LIST_TIE_07192005_0109)
+#define FUSION_PP_LIST_TIE_07192005_0109
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/fusion/container/list/list.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/generation/detail/preprocessed/list_tie.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/list_tie" FUSION_MAX_LIST_SIZE_STR".hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct void_;
+
+ namespace result_of
+ {
+ template <
+ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ FUSION_MAX_LIST_SIZE, typename T, void_)
+ , typename Extra = void_
+ >
+ struct list_tie;
+ }
+
+// $$$ shouldn't we remove_reference first to allow references? $$$
+#define BOOST_FUSION_REF(z, n, data) BOOST_PP_CAT(T, n)&
+
+#define BOOST_PP_FILENAME_1 <boost/fusion/container/generation/detail/pp_list_tie.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_LIST_SIZE)
+#include BOOST_PP_ITERATE()
+
+#undef BOOST_FUSION_REF
+
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+#else // defined(BOOST_PP_IS_ITERATING)
+///////////////////////////////////////////////////////////////////////////////
+//
+// Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define N BOOST_PP_ITERATION()
+
+ namespace result_of
+ {
+ template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+ #define TEXT(z, n, text) , text
+ struct list_tie< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_LIST_SIZE, TEXT, void_) >
+ #undef TEXT
+ {
+ typedef list<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)> type;
+ };
+ }
+
+ template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ inline list<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)>
+ list_tie(BOOST_PP_ENUM_BINARY_PARAMS(N, T, & arg))
+ {
+ return list<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)>(
+ BOOST_PP_ENUM_PARAMS(N, arg));
+ }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
diff --git a/boost/fusion/container/generation/detail/pp_make_list.hpp b/boost/fusion/container/generation/detail/pp_make_list.hpp
new file mode 100644
index 0000000000..989bf36bd9
--- /dev/null
+++ b/boost/fusion/container/generation/detail/pp_make_list.hpp
@@ -0,0 +1,115 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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_PP_IS_ITERATING
+#if !defined(FUSION_PP_MAKE_LIST_07192005_1239)
+#define FUSION_PP_MAKE_LIST_07192005_1239
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/fusion/container/list/list.hpp>
+#include <boost/fusion/support/detail/as_fusion_element.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/generation/detail/preprocessed/make_list.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/make_list" FUSION_MAX_LIST_SIZE_STR".hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct void_;
+
+ namespace result_of
+ {
+ template <
+ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ FUSION_MAX_LIST_SIZE, typename T, void_)
+ , typename Extra = void_
+ >
+ struct make_list;
+
+ template <>
+ struct make_list<>
+ {
+ typedef list<> type;
+ };
+ }
+
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ inline list<>
+ make_list()
+ {
+ return list<>();
+ }
+
+#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \
+ typename detail::as_fusion_element<BOOST_PP_CAT(T, n)>::type
+
+#define BOOST_PP_FILENAME_1 <boost/fusion/container/generation/detail/pp_make_list.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_LIST_SIZE)
+#include BOOST_PP_ITERATE()
+
+#undef BOOST_FUSION_AS_FUSION_ELEMENT
+
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+#else // defined(BOOST_PP_IS_ITERATING)
+///////////////////////////////////////////////////////////////////////////////
+//
+// Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define N BOOST_PP_ITERATION()
+
+ namespace result_of
+ {
+ template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+ #define TEXT(z, n, text) , text
+ struct make_list< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_LIST_SIZE, TEXT, void_) >
+ #undef TEXT
+ {
+ typedef list<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)> type;
+ };
+ }
+
+ template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ inline list<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>
+ make_list(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& arg))
+ {
+ return list<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>(
+ BOOST_PP_ENUM_PARAMS(N, arg));
+ }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
diff --git a/boost/fusion/container/generation/detail/pp_make_set.hpp b/boost/fusion/container/generation/detail/pp_make_set.hpp
new file mode 100644
index 0000000000..f3f9a9e8fc
--- /dev/null
+++ b/boost/fusion/container/generation/detail/pp_make_set.hpp
@@ -0,0 +1,134 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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_PP_IS_ITERATING
+#if !defined(FUSION_MAKE_SET_09162005_1125)
+#define FUSION_MAKE_SET_09162005_1125
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/set/set.hpp>
+#include <boost/fusion/support/detail/as_fusion_element.hpp>
+#include <boost/fusion/support/pair.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/generation/detail/preprocessed/make_set.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/make_set" FUSION_MAX_SET_SIZE_STR".hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#define FUSION_HASH #
+#endif
+
+namespace boost { namespace fusion
+{
+ struct void_;
+
+ namespace result_of
+ {
+ template <
+ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ FUSION_MAX_VECTOR_SIZE, typename T, void_)
+ , typename Extra = void_
+ >
+ struct make_set;
+
+ template <>
+ struct make_set<>
+ {
+ typedef set<> type;
+ };
+ }
+
+ // XXX:
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+FUSION_HASH if defined(BOOST_CLANG)
+ BOOST_CXX14_CONSTEXPR
+FUSION_HASH else
+ BOOST_CONSTEXPR
+FUSION_HASH endif
+#else
+#if defined(BOOST_CLANG)
+ BOOST_CXX14_CONSTEXPR
+#else
+ BOOST_CONSTEXPR
+#endif
+#endif
+ BOOST_FUSION_GPU_ENABLED
+ inline set<>
+ make_set()
+ {
+ return set<>();
+ }
+
+#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \
+ typename detail::as_fusion_element<BOOST_PP_CAT(T, n)>::type
+
+#define BOOST_PP_FILENAME_1 <boost/fusion/container/generation/detail/pp_make_set.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
+#include BOOST_PP_ITERATE()
+
+#undef BOOST_FUSION_ELEMENT
+#undef BOOST_FUSION_AS_ELEMENT
+
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#undef FUSION_HASH
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+#else // defined(BOOST_PP_IS_ITERATING)
+///////////////////////////////////////////////////////////////////////////////
+//
+// Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define N BOOST_PP_ITERATION()
+
+ namespace result_of
+ {
+ template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+ #define TEXT(z, n, text) , text
+ struct make_set< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_SET_SIZE, TEXT, void_) >
+ #undef TEXT
+ {
+ typedef set<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)> type;
+ };
+ }
+
+ template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ inline set<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>
+ make_set(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& arg))
+ {
+ return set<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>(
+ BOOST_PP_ENUM_PARAMS(N, arg));
+ }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
diff --git a/boost/fusion/container/generation/detail/pp_make_vector.hpp b/boost/fusion/container/generation/detail/pp_make_vector.hpp
new file mode 100644
index 0000000000..b19cf35457
--- /dev/null
+++ b/boost/fusion/container/generation/detail/pp_make_vector.hpp
@@ -0,0 +1,115 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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_PP_IS_ITERATING
+#if !defined(FUSION_MAKE_VECTOR_07162005_0243)
+#define FUSION_MAKE_VECTOR_07162005_0243
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/fusion/container/vector/vector.hpp>
+#include <boost/fusion/support/detail/as_fusion_element.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/generation/detail/preprocessed/make_vector.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/make_vector" FUSION_MAX_VECTOR_SIZE_STR".hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct void_;
+
+ namespace result_of
+ {
+ template <
+ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ FUSION_MAX_VECTOR_SIZE, typename T, void_)
+ , typename Extra = void_
+ >
+ struct make_vector;
+
+ template <>
+ struct make_vector<>
+ {
+ typedef vector0<> type;
+ };
+ }
+
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ inline vector0<>
+ make_vector()
+ {
+ return vector0<>();
+ }
+
+#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \
+ typename detail::as_fusion_element<BOOST_PP_CAT(T, n)>::type
+
+#define BOOST_PP_FILENAME_1 <boost/fusion/container/generation/detail/pp_make_vector.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
+#include BOOST_PP_ITERATE()
+
+#undef BOOST_FUSION_AS_FUSION_ELEMENT
+
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+#else // defined(BOOST_PP_IS_ITERATING)
+///////////////////////////////////////////////////////////////////////////////
+//
+// Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define N BOOST_PP_ITERATION()
+
+ namespace result_of
+ {
+ template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+ #define TEXT(z, n, text) , text
+ struct make_vector< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_VECTOR_SIZE, TEXT, void_) >
+ #undef TEXT
+ {
+ typedef BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)> type;
+ };
+ }
+
+ template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ inline BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>
+ make_vector(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& arg))
+ {
+ return BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>(
+ BOOST_PP_ENUM_PARAMS(N, arg));
+ }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
diff --git a/boost/fusion/container/generation/detail/pp_vector_tie.hpp b/boost/fusion/container/generation/detail/pp_vector_tie.hpp
new file mode 100644
index 0000000000..132c38afe9
--- /dev/null
+++ b/boost/fusion/container/generation/detail/pp_vector_tie.hpp
@@ -0,0 +1,100 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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_PP_IS_ITERATING
+#if !defined(FUSION_VECTOR_TIE_07192005_1242)
+#define FUSION_VECTOR_TIE_07192005_1242
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/fusion/container/vector/vector.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/generation/detail/preprocessed/vector_tie.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/vector_tie" FUSION_MAX_VECTOR_SIZE_STR".hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct void_;
+
+ namespace result_of
+ {
+ template <
+ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ FUSION_MAX_VECTOR_SIZE, typename T, void_)
+ , typename Extra = void_
+ >
+ struct vector_tie;
+ }
+
+#define BOOST_FUSION_REF(z, n, data) BOOST_PP_CAT(T, n)&
+
+#define BOOST_PP_FILENAME_1 <boost/fusion/container/generation/detail/pp_vector_tie.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
+#include BOOST_PP_ITERATE()
+
+#undef BOOST_FUSION_REF
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+#else // defined(BOOST_PP_IS_ITERATING)
+///////////////////////////////////////////////////////////////////////////////
+//
+// Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define N BOOST_PP_ITERATION()
+
+ namespace result_of
+ {
+ template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+ #define TEXT(z, n, text) , text
+ struct vector_tie< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_VECTOR_SIZE, TEXT, void_) >
+ #undef TEXT
+ {
+ typedef vector<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)> type;
+ };
+ }
+
+ template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ inline vector<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)>
+ vector_tie(BOOST_PP_ENUM_BINARY_PARAMS(N, T, & arg))
+ {
+ return vector<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)>(
+ BOOST_PP_ENUM_PARAMS(N, arg));
+ }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
diff --git a/boost/fusion/container/generation/ignore.hpp b/boost/fusion/container/generation/ignore.hpp
index 15ce15d4a1..781966322f 100644
--- a/boost/fusion/container/generation/ignore.hpp
+++ b/boost/fusion/container/generation/ignore.hpp
@@ -9,6 +9,8 @@
#if !defined(FUSION_IGNORE_07192005_0329)
#define FUSION_IGNORE_07192005_0329
+#include <boost/fusion/support/config.hpp>
+
namespace boost { namespace fusion
{
// Swallows any assignment (by Doug Gregor)
@@ -17,7 +19,7 @@ namespace boost { namespace fusion
struct swallow_assign
{
template<typename T>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_CONSTEXPR_THIS BOOST_FUSION_GPU_ENABLED
swallow_assign const&
operator=(const T&) const
{
@@ -27,7 +29,7 @@ namespace boost { namespace fusion
}
// "ignore" allows tuple positions to be ignored when using "tie".
- BOOST_CONSTEXPR detail::swallow_assign const ignore = detail::swallow_assign();
+ BOOST_CONSTEXPR_OR_CONST detail::swallow_assign ignore = detail::swallow_assign();
}}
#endif
diff --git a/boost/fusion/container/generation/list_tie.hpp b/boost/fusion/container/generation/list_tie.hpp
index 1dccb5151e..9190716740 100644
--- a/boost/fusion/container/generation/list_tie.hpp
+++ b/boost/fusion/container/generation/list_tie.hpp
@@ -1,102 +1,44 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2015 Kohei Takahashi
Distributed under the 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_PP_IS_ITERATING
-#if !defined(FUSION_LIST_TIE_07192005_0109)
-#define FUSION_LIST_TIE_07192005_0109
+#ifndef FUSION_LIST_TIE_06182015_0825
+#define FUSION_LIST_TIE_06182015_0825
-#include <boost/preprocessor/iterate.hpp>
-#include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
-#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/fusion/support/config.hpp>
#include <boost/fusion/container/list/list.hpp>
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/generation/detail/preprocessed/list_tie.hpp>
+#if !defined(BOOST_FUSION_HAS_VARIADIC_LIST)
+# include <boost/fusion/container/generation/detail/pp_list_tie.hpp>
#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/list_tie" FUSION_MAX_LIST_SIZE_STR".hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion
-{
- struct void_;
-
- namespace result_of
- {
- template <
- BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
- FUSION_MAX_LIST_SIZE, typename T, void_)
- , typename Extra = void_
- >
- struct list_tie;
- }
-// $$$ shouldn't we remove_reference first to allow references? $$$
-#define BOOST_FUSION_REF(z, n, data) BOOST_PP_CAT(T, n)&
-
-#define BOOST_PP_FILENAME_1 <boost/fusion/container/generation/list_tie.hpp>
-#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_LIST_SIZE)
-#include BOOST_PP_ITERATE()
-
-#undef BOOST_FUSION_REF
-
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
-#endif
-#else // defined(BOOST_PP_IS_ITERATING)
///////////////////////////////////////////////////////////////////////////////
-//
-// Preprocessor vertical repetition code
-//
+// C++11 variadic interface
///////////////////////////////////////////////////////////////////////////////
-#define N BOOST_PP_ITERATION()
-
+namespace boost { namespace fusion
+{
namespace result_of
{
- template <BOOST_PP_ENUM_PARAMS(N, typename T)>
- #define TEXT(z, n, text) , text
- struct list_tie< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_LIST_SIZE, TEXT, void_) >
- #undef TEXT
+ template <typename ...T>
+ struct list_tie
{
- typedef list<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)> type;
+ typedef list<T&...> type;
};
}
- template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+ template <typename ...T>
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- inline list<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)>
- list_tie(BOOST_PP_ENUM_BINARY_PARAMS(N, T, & arg))
+ inline list<T&...>
+ list_tie(T&... arg)
{
- return list<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)>(
- BOOST_PP_ENUM_PARAMS(N, arg));
+ return list<T&...>(arg...);
}
+}}
+
+#endif
-#undef N
-#endif // defined(BOOST_PP_IS_ITERATING)
+#endif
diff --git a/boost/fusion/container/generation/make_list.hpp b/boost/fusion/container/generation/make_list.hpp
index 8cfc7e6227..e88f553a26 100644
--- a/boost/fusion/container/generation/make_list.hpp
+++ b/boost/fusion/container/generation/make_list.hpp
@@ -1,115 +1,46 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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_PP_IS_ITERATING
-#if !defined(FUSION_MAKE_LIST_07192005_1239)
-#define FUSION_MAKE_LIST_07192005_1239
+#ifndef FUSION_MAKE_LIST_10262014_0647
+#define FUSION_MAKE_LIST_10262014_0647
-#include <boost/preprocessor/iterate.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
-#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/fusion/support/config.hpp>
#include <boost/fusion/container/list/list.hpp>
-#include <boost/fusion/support/detail/as_fusion_element.hpp>
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/generation/detail/preprocessed/make_list.hpp>
+#if !defined(BOOST_FUSION_HAS_VARIADIC_LIST)
+# include <boost/fusion/container/generation/detail/pp_make_list.hpp>
#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/make_list" FUSION_MAX_LIST_SIZE_STR".hpp")
-#endif
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+// C++11 variadic interface
+///////////////////////////////////////////////////////////////////////////////
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
+#include <boost/fusion/support/detail/as_fusion_element.hpp>
namespace boost { namespace fusion
{
- struct void_;
-
namespace result_of
{
- template <
- BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
- FUSION_MAX_LIST_SIZE, typename T, void_)
- , typename Extra = void_
- >
- struct make_list;
-
- template <>
- struct make_list<>
+ template <typename ...T>
+ struct make_list
{
- typedef list<> type;
+ typedef list<typename detail::as_fusion_element<T>::type...> type;
};
}
+ template <typename ...T>
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- inline list<>
- make_list()
+ inline typename result_of::make_list<T...>::type
+ make_list(T const&... arg)
{
- return list<>();
+ return typename result_of::make_list<T...>::type(arg...);
}
+ }}
-#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \
- typename detail::as_fusion_element<BOOST_PP_CAT(T, n)>::type
-
-#define BOOST_PP_FILENAME_1 <boost/fusion/container/generation/make_list.hpp>
-#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_LIST_SIZE)
-#include BOOST_PP_ITERATE()
-
-#undef BOOST_FUSION_AS_FUSION_ELEMENT
-
-}}
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
#endif
-#else // defined(BOOST_PP_IS_ITERATING)
-///////////////////////////////////////////////////////////////////////////////
-//
-// Preprocessor vertical repetition code
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define N BOOST_PP_ITERATION()
-
- namespace result_of
- {
- template <BOOST_PP_ENUM_PARAMS(N, typename T)>
- #define TEXT(z, n, text) , text
- struct make_list< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_LIST_SIZE, TEXT, void_) >
- #undef TEXT
- {
- typedef list<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)> type;
- };
- }
-
- template <BOOST_PP_ENUM_PARAMS(N, typename T)>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- inline list<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>
- make_list(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& arg))
- {
- return list<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>(
- BOOST_PP_ENUM_PARAMS(N, arg));
- }
-
-#undef N
-#endif // defined(BOOST_PP_IS_ITERATING)
diff --git a/boost/fusion/container/generation/make_set.hpp b/boost/fusion/container/generation/make_set.hpp
index 0bde4a9c49..705ec582a8 100644
--- a/boost/fusion/container/generation/make_set.hpp
+++ b/boost/fusion/container/generation/make_set.hpp
@@ -1,134 +1,16 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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_PP_IS_ITERATING
-#if !defined(FUSION_MAKE_SET_09162005_1125)
-#define FUSION_MAKE_SET_09162005_1125
+#ifndef FUSION_MAKE_SET_11112014_2255
+#define FUSION_MAKE_SET_11112014_2255
-#include <boost/preprocessor/iterate.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
-#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/container/set/set.hpp>
-#include <boost/fusion/support/detail/as_fusion_element.hpp>
-#include <boost/fusion/support/pair.hpp>
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/generation/detail/preprocessed/make_set.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/make_set" FUSION_MAX_SET_SIZE_STR".hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#define FUSION_HASH #
-#endif
-
-namespace boost { namespace fusion
-{
- struct void_;
+# include <boost/fusion/container/generation/detail/pp_make_set.hpp>
- namespace result_of
- {
- template <
- BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
- FUSION_MAX_VECTOR_SIZE, typename T, void_)
- , typename Extra = void_
- >
- struct make_set;
-
- template <>
- struct make_set<>
- {
- typedef set<> type;
- };
- }
-
- // XXX:
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-FUSION_HASH if defined(BOOST_CLANG)
- BOOST_CXX14_CONSTEXPR
-FUSION_HASH else
- BOOST_CONSTEXPR
-FUSION_HASH endif
-#else
-#if defined(BOOST_CLANG)
- BOOST_CXX14_CONSTEXPR
-#else
- BOOST_CONSTEXPR
-#endif
#endif
- BOOST_FUSION_GPU_ENABLED
- inline set<>
- make_set()
- {
- return set<>();
- }
-
-#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \
- typename detail::as_fusion_element<BOOST_PP_CAT(T, n)>::type
-
-#define BOOST_PP_FILENAME_1 <boost/fusion/container/generation/make_set.hpp>
-#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
-#include BOOST_PP_ITERATE()
-
-#undef BOOST_FUSION_ELEMENT
-#undef BOOST_FUSION_AS_ELEMENT
-
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#undef FUSION_HASH
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
-#endif
-#else // defined(BOOST_PP_IS_ITERATING)
-///////////////////////////////////////////////////////////////////////////////
-//
-// Preprocessor vertical repetition code
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define N BOOST_PP_ITERATION()
-
- namespace result_of
- {
- template <BOOST_PP_ENUM_PARAMS(N, typename T)>
- #define TEXT(z, n, text) , text
- struct make_set< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_SET_SIZE, TEXT, void_) >
- #undef TEXT
- {
- typedef set<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)> type;
- };
- }
-
- template <BOOST_PP_ENUM_PARAMS(N, typename T)>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- inline set<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>
- make_set(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& arg))
- {
- return set<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>(
- BOOST_PP_ENUM_PARAMS(N, arg));
- }
-
-#undef N
-#endif // defined(BOOST_PP_IS_ITERATING)
diff --git a/boost/fusion/container/generation/make_vector.hpp b/boost/fusion/container/generation/make_vector.hpp
index 57cd9b1003..8f0674815e 100644
--- a/boost/fusion/container/generation/make_vector.hpp
+++ b/boost/fusion/container/generation/make_vector.hpp
@@ -1,115 +1,16 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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_PP_IS_ITERATING
-#if !defined(FUSION_MAKE_VECTOR_07162005_0243)
-#define FUSION_MAKE_VECTOR_07162005_0243
+#ifndef FUSION_MAKE_VECTOR_11112014_2252
+#define FUSION_MAKE_VECTOR_11112014_2252
-#include <boost/preprocessor/iterate.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
-#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/fusion/support/config.hpp>
#include <boost/fusion/container/vector/vector.hpp>
-#include <boost/fusion/support/detail/as_fusion_element.hpp>
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/generation/detail/preprocessed/make_vector.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/make_vector" FUSION_MAX_VECTOR_SIZE_STR".hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+# include <boost/fusion/container/generation/detail/pp_make_vector.hpp>
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
#endif
-namespace boost { namespace fusion
-{
- struct void_;
-
- namespace result_of
- {
- template <
- BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
- FUSION_MAX_VECTOR_SIZE, typename T, void_)
- , typename Extra = void_
- >
- struct make_vector;
-
- template <>
- struct make_vector<>
- {
- typedef vector0<> type;
- };
- }
-
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- inline vector0<>
- make_vector()
- {
- return vector0<>();
- }
-
-#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \
- typename detail::as_fusion_element<BOOST_PP_CAT(T, n)>::type
-
-#define BOOST_PP_FILENAME_1 <boost/fusion/container/generation/make_vector.hpp>
-#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
-#include BOOST_PP_ITERATE()
-
-#undef BOOST_FUSION_AS_FUSION_ELEMENT
-
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
-#endif
-#else // defined(BOOST_PP_IS_ITERATING)
-///////////////////////////////////////////////////////////////////////////////
-//
-// Preprocessor vertical repetition code
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define N BOOST_PP_ITERATION()
-
- namespace result_of
- {
- template <BOOST_PP_ENUM_PARAMS(N, typename T)>
- #define TEXT(z, n, text) , text
- struct make_vector< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_VECTOR_SIZE, TEXT, void_) >
- #undef TEXT
- {
- typedef BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)> type;
- };
- }
-
- template <BOOST_PP_ENUM_PARAMS(N, typename T)>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- inline BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>
- make_vector(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& arg))
- {
- return BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>(
- BOOST_PP_ENUM_PARAMS(N, arg));
- }
-
-#undef N
-#endif // defined(BOOST_PP_IS_ITERATING)
-
diff --git a/boost/fusion/container/generation/vector_tie.hpp b/boost/fusion/container/generation/vector_tie.hpp
index 28efa3bdfb..5bb4face4d 100644
--- a/boost/fusion/container/generation/vector_tie.hpp
+++ b/boost/fusion/container/generation/vector_tie.hpp
@@ -1,100 +1,15 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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_PP_IS_ITERATING
-#if !defined(FUSION_VECTOR_TIE_07192005_1242)
-#define FUSION_VECTOR_TIE_07192005_1242
+#ifndef FUSION_VECTOR_TIE_11112014_2302
+#define FUSION_VECTOR_TIE_11112014_2302
-#include <boost/preprocessor/iterate.hpp>
-#include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
-#include <boost/preprocessor/repetition/repeat_from_to.hpp>
-#include <boost/fusion/container/vector/vector.hpp>
+#include <boost/fusion/support/config.hpp>
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/generation/detail/preprocessed/vector_tie.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/vector_tie" FUSION_MAX_VECTOR_SIZE_STR".hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion
-{
- struct void_;
+# include <boost/fusion/container/generation/detail/pp_vector_tie.hpp>
- namespace result_of
- {
- template <
- BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
- FUSION_MAX_VECTOR_SIZE, typename T, void_)
- , typename Extra = void_
- >
- struct vector_tie;
- }
-
-#define BOOST_FUSION_REF(z, n, data) BOOST_PP_CAT(T, n)&
-
-#define BOOST_PP_FILENAME_1 <boost/fusion/container/generation/vector_tie.hpp>
-#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
-#include BOOST_PP_ITERATE()
-
-#undef BOOST_FUSION_REF
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
#endif
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
-#endif
-#else // defined(BOOST_PP_IS_ITERATING)
-///////////////////////////////////////////////////////////////////////////////
-//
-// Preprocessor vertical repetition code
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define N BOOST_PP_ITERATION()
-
- namespace result_of
- {
- template <BOOST_PP_ENUM_PARAMS(N, typename T)>
- #define TEXT(z, n, text) , text
- struct vector_tie< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_VECTOR_SIZE, TEXT, void_) >
- #undef TEXT
- {
- typedef vector<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)> type;
- };
- }
-
- template <BOOST_PP_ENUM_PARAMS(N, typename T)>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- inline vector<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)>
- vector_tie(BOOST_PP_ENUM_BINARY_PARAMS(N, T, & arg))
- {
- return vector<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)>(
- BOOST_PP_ENUM_PARAMS(N, arg));
- }
-
-#undef N
-#endif // defined(BOOST_PP_IS_ITERATING)
-
diff --git a/boost/fusion/container/list.hpp b/boost/fusion/container/list.hpp
index bdb5dc9a02..e3a1d8eff0 100644
--- a/boost/fusion/container/list.hpp
+++ b/boost/fusion/container/list.hpp
@@ -10,7 +10,6 @@
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/container/list/cons.hpp>
#include <boost/fusion/container/list/cons_iterator.hpp>
-#include <boost/fusion/container/list/limits.hpp>
#include <boost/fusion/container/list/list.hpp>
#include <boost/fusion/container/list/list_fwd.hpp>
#include <boost/fusion/container/list/convert.hpp>
diff --git a/boost/fusion/container/list/cons.hpp b/boost/fusion/container/list/cons.hpp
index 61d8dbcfe1..e05b62eb48 100644
--- a/boost/fusion/container/list/cons.hpp
+++ b/boost/fusion/container/list/cons.hpp
@@ -23,6 +23,7 @@
#include <boost/fusion/container/list/detail/value_at_impl.hpp>
#include <boost/fusion/container/list/detail/empty_impl.hpp>
#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_base_of.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/fusion/support/sequence_base.hpp>
#include <boost/fusion/support/is_sequence.hpp>
@@ -73,12 +74,13 @@ namespace boost { namespace fusion
: car(rhs.car), cdr(rhs.cdr) {}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
cons(
Sequence const& seq
, typename boost::enable_if<
mpl::and_<
traits::is_sequence<Sequence>
+ , mpl::not_<is_base_of<cons, Sequence> >
, mpl::not_<is_convertible<Sequence, Car> > > // use copy to car instead
>::type* /*dummy*/ = 0
)
diff --git a/boost/fusion/container/list/limits.hpp b/boost/fusion/container/list/detail/cpp03/limits.hpp
index cc64ad7224..cc64ad7224 100644
--- a/boost/fusion/container/list/limits.hpp
+++ b/boost/fusion/container/list/detail/cpp03/limits.hpp
diff --git a/boost/fusion/container/list/detail/cpp03/list.hpp b/boost/fusion/container/list/detail/cpp03/list.hpp
new file mode 100644
index 0000000000..b39489b0b7
--- /dev/null
+++ b/boost/fusion/container/list/detail/cpp03/list.hpp
@@ -0,0 +1,102 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_LIST_07172005_1153)
+#define FUSION_LIST_07172005_1153
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/list/detail/cpp03/list_fwd.hpp>
+#include <boost/fusion/container/list/detail/cpp03/list_to_cons.hpp>
+#include <boost/fusion/support/is_sequence.hpp>
+#include <boost/core/enable_if.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/list" FUSION_MAX_LIST_SIZE_STR ".hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct nil_;
+ struct void_;
+
+ template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, typename T)>
+ struct list
+ : detail::list_to_cons<BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, T)>::type
+ {
+ private:
+ typedef
+ detail::list_to_cons<BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, T)>
+ list_to_cons;
+ typedef typename list_to_cons::type inherited_type;
+
+ public:
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ list()
+ : inherited_type() {}
+
+ template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, typename U)>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ list(list<BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, U)> const& rhs)
+ : inherited_type(rhs) {}
+
+ template <typename Sequence>
+ BOOST_FUSION_GPU_ENABLED
+ list(Sequence const& rhs
+ , typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
+ : inherited_type(rhs) {}
+
+ // Expand a couple of forwarding constructors for arguments
+ // of type (T0), (T0, T1), (T0, T1, T2) etc. Exanple:
+ //
+ // list(
+ // typename detail::call_param<T0>::type arg0
+ // , typename detail::call_param<T1>::type arg1)
+ // : inherited_type(list_to_cons::call(arg0, arg1)) {}
+ #include <boost/fusion/container/list/detail/cpp03/list_forward_ctor.hpp>
+
+ template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, typename U)>
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ list&
+ operator=(list<BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, U)> const& rhs)
+ {
+ inherited_type::operator=(rhs);
+ return *this;
+ }
+
+ template <typename Sequence>
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ typename boost::enable_if<traits::is_sequence<Sequence>, list&>::type
+ operator=(Sequence const& rhs)
+ {
+ inherited_type::operator=(rhs);
+ return *this;
+ }
+ };
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
diff --git a/boost/fusion/container/list/detail/list_forward_ctor.hpp b/boost/fusion/container/list/detail/cpp03/list_forward_ctor.hpp
index a5c8aa66c9..f9a706786b 100644
--- a/boost/fusion/container/list/detail/list_forward_ctor.hpp
+++ b/boost/fusion/container/list/detail/cpp03/list_forward_ctor.hpp
@@ -18,7 +18,7 @@
#define FUSION_LIST_CL_PAREN(z, n, type) )
#define BOOST_PP_FILENAME_1 \
- <boost/fusion/container/list/detail/list_forward_ctor.hpp>
+ <boost/fusion/container/list/detail/cpp03/list_forward_ctor.hpp>
#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_LIST_SIZE)
#include BOOST_PP_ITERATE()
diff --git a/boost/fusion/container/list/detail/cpp03/list_fwd.hpp b/boost/fusion/container/list/detail/cpp03/list_fwd.hpp
new file mode 100644
index 0000000000..cedc700343
--- /dev/null
+++ b/boost/fusion/container/list/detail/cpp03/list_fwd.hpp
@@ -0,0 +1,51 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_LIST_FORWARD_07172005_0224)
+#define FUSION_LIST_FORWARD_07172005_0224
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/list/detail/cpp03/limits.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list_fwd.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/list" FUSION_MAX_LIST_SIZE_STR "_fwd.hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct void_;
+
+ template <
+ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ FUSION_MAX_LIST_SIZE, typename T, void_)
+ >
+ struct list;
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
diff --git a/boost/fusion/container/list/detail/cpp03/list_to_cons.hpp b/boost/fusion/container/list/detail/cpp03/list_to_cons.hpp
new file mode 100644
index 0000000000..989e91abe3
--- /dev/null
+++ b/boost/fusion/container/list/detail/cpp03/list_to_cons.hpp
@@ -0,0 +1,76 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_LIST_TO_CONS_07172005_1041)
+#define FUSION_LIST_TO_CONS_07172005_1041
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/list/cons.hpp>
+#include <boost/fusion/container/list/detail/cpp03/limits.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+#include <boost/preprocessor/arithmetic/dec.hpp>
+
+#define FUSION_VOID(z, n, _) void_
+
+namespace boost { namespace fusion
+{
+ struct nil_;
+ struct void_;
+}}
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/list_to_cons" FUSION_MAX_LIST_SIZE_STR ".hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion { namespace detail
+{
+ template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, typename T)>
+ struct list_to_cons
+ {
+ typedef T0 head_type;
+ typedef list_to_cons<
+ BOOST_PP_ENUM_SHIFTED_PARAMS(FUSION_MAX_LIST_SIZE, T), void_>
+ tail_list_to_cons;
+ typedef typename tail_list_to_cons::type tail_type;
+
+ typedef cons<head_type, tail_type> type;
+
+ #include <boost/fusion/container/list/detail/cpp03/list_to_cons_call.hpp>
+ };
+
+ template <>
+ struct list_to_cons<BOOST_PP_ENUM(FUSION_MAX_LIST_SIZE, FUSION_VOID, _)>
+ {
+ typedef nil_ type;
+ };
+}}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#undef FUSION_VOID
+#endif
diff --git a/boost/fusion/container/list/detail/list_to_cons_call.hpp b/boost/fusion/container/list/detail/cpp03/list_to_cons_call.hpp
index fbae58009e..e49db4a840 100644
--- a/boost/fusion/container/list/detail/list_to_cons_call.hpp
+++ b/boost/fusion/container/list/detail/cpp03/list_to_cons_call.hpp
@@ -13,7 +13,7 @@
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#define BOOST_PP_FILENAME_1 \
- <boost/fusion/container/list/detail/list_to_cons_call.hpp>
+ <boost/fusion/container/list/detail/cpp03/list_to_cons_call.hpp>
#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_LIST_SIZE)
#include BOOST_PP_ITERATE()
diff --git a/boost/fusion/container/list/detail/preprocessed/list.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list.hpp
index 315ffcf7ee..7af66f4964 100644
--- a/boost/fusion/container/list/detail/preprocessed/list.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list.hpp
@@ -8,15 +8,15 @@
==============================================================================*/
#if FUSION_MAX_LIST_SIZE <= 10
-#include <boost/fusion/container/list/detail/preprocessed/list10.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list10.hpp>
#elif FUSION_MAX_LIST_SIZE <= 20
-#include <boost/fusion/container/list/detail/preprocessed/list20.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list20.hpp>
#elif FUSION_MAX_LIST_SIZE <= 30
-#include <boost/fusion/container/list/detail/preprocessed/list30.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list30.hpp>
#elif FUSION_MAX_LIST_SIZE <= 40
-#include <boost/fusion/container/list/detail/preprocessed/list40.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list40.hpp>
#elif FUSION_MAX_LIST_SIZE <= 50
-#include <boost/fusion/container/list/detail/preprocessed/list50.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list50.hpp>
#else
#error "FUSION_MAX_LIST_SIZE out of bounds for preprocessed headers"
#endif
diff --git a/boost/fusion/container/list/detail/preprocessed/list10.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list10.hpp
index 9a289365cd..47db8f588c 100644
--- a/boost/fusion/container/list/detail/preprocessed/list10.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list10.hpp
@@ -18,8 +18,8 @@ namespace boost { namespace fusion
typedef
detail::list_to_cons<T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9>
list_to_cons;
- public:
typedef typename list_to_cons::type inherited_type;
+ public:
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
list()
: inherited_type() {}
@@ -28,7 +28,7 @@ namespace boost { namespace fusion
list(list<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9> const& rhs)
: inherited_type(rhs) {}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
list(Sequence const& rhs
, typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
: inherited_type(rhs) {}
diff --git a/boost/fusion/container/list/detail/preprocessed/list10_fwd.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list10_fwd.hpp
index f513a99194..f513a99194 100644
--- a/boost/fusion/container/list/detail/preprocessed/list10_fwd.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list10_fwd.hpp
diff --git a/boost/fusion/container/list/detail/preprocessed/list20.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list20.hpp
index a201cb44de..8eb7d2d2df 100644
--- a/boost/fusion/container/list/detail/preprocessed/list20.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list20.hpp
@@ -18,8 +18,8 @@ namespace boost { namespace fusion
typedef
detail::list_to_cons<T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19>
list_to_cons;
- public:
typedef typename list_to_cons::type inherited_type;
+ public:
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
list()
: inherited_type() {}
@@ -28,7 +28,7 @@ namespace boost { namespace fusion
list(list<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19> const& rhs)
: inherited_type(rhs) {}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
list(Sequence const& rhs
, typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
: inherited_type(rhs) {}
diff --git a/boost/fusion/container/list/detail/preprocessed/list20_fwd.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list20_fwd.hpp
index 2eedc8b293..2eedc8b293 100644
--- a/boost/fusion/container/list/detail/preprocessed/list20_fwd.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list20_fwd.hpp
diff --git a/boost/fusion/container/list/detail/preprocessed/list30.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list30.hpp
index ef9e65fc6a..fb24e8d47b 100644
--- a/boost/fusion/container/list/detail/preprocessed/list30.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list30.hpp
@@ -18,8 +18,8 @@ namespace boost { namespace fusion
typedef
detail::list_to_cons<T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29>
list_to_cons;
- public:
typedef typename list_to_cons::type inherited_type;
+ public:
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
list()
: inherited_type() {}
@@ -28,7 +28,7 @@ namespace boost { namespace fusion
list(list<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29> const& rhs)
: inherited_type(rhs) {}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
list(Sequence const& rhs
, typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
: inherited_type(rhs) {}
diff --git a/boost/fusion/container/list/detail/preprocessed/list30_fwd.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list30_fwd.hpp
index 32bfc606f7..32bfc606f7 100644
--- a/boost/fusion/container/list/detail/preprocessed/list30_fwd.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list30_fwd.hpp
diff --git a/boost/fusion/container/list/detail/preprocessed/list40.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list40.hpp
index 570b2ccdda..49437dee5e 100644
--- a/boost/fusion/container/list/detail/preprocessed/list40.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list40.hpp
@@ -18,8 +18,8 @@ namespace boost { namespace fusion
typedef
detail::list_to_cons<T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39>
list_to_cons;
- public:
typedef typename list_to_cons::type inherited_type;
+ public:
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
list()
: inherited_type() {}
@@ -28,7 +28,7 @@ namespace boost { namespace fusion
list(list<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39> const& rhs)
: inherited_type(rhs) {}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
list(Sequence const& rhs
, typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
: inherited_type(rhs) {}
diff --git a/boost/fusion/container/list/detail/preprocessed/list40_fwd.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list40_fwd.hpp
index 5d0da6df4b..5d0da6df4b 100644
--- a/boost/fusion/container/list/detail/preprocessed/list40_fwd.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list40_fwd.hpp
diff --git a/boost/fusion/container/list/detail/preprocessed/list50.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list50.hpp
index d237cdf998..3ebbf19586 100644
--- a/boost/fusion/container/list/detail/preprocessed/list50.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list50.hpp
@@ -18,8 +18,8 @@ namespace boost { namespace fusion
typedef
detail::list_to_cons<T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 , T47 , T48 , T49>
list_to_cons;
- public:
typedef typename list_to_cons::type inherited_type;
+ public:
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
list()
: inherited_type() {}
@@ -28,7 +28,7 @@ namespace boost { namespace fusion
list(list<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44 , U45 , U46 , U47 , U48 , U49> const& rhs)
: inherited_type(rhs) {}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
list(Sequence const& rhs
, typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
: inherited_type(rhs) {}
diff --git a/boost/fusion/container/list/detail/preprocessed/list50_fwd.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list50_fwd.hpp
index 2b3ae66cb6..2b3ae66cb6 100644
--- a/boost/fusion/container/list/detail/preprocessed/list50_fwd.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list50_fwd.hpp
diff --git a/boost/fusion/container/list/detail/preprocessed/list_fwd.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list_fwd.hpp
index b9be34752f..8a4037da48 100644
--- a/boost/fusion/container/list/detail/preprocessed/list_fwd.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list_fwd.hpp
@@ -8,15 +8,15 @@
==============================================================================*/
#if FUSION_MAX_LIST_SIZE <= 10
-#include <boost/fusion/container/list/detail/preprocessed/list10_fwd.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list10_fwd.hpp>
#elif FUSION_MAX_LIST_SIZE <= 20
-#include <boost/fusion/container/list/detail/preprocessed/list20_fwd.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list20_fwd.hpp>
#elif FUSION_MAX_LIST_SIZE <= 30
-#include <boost/fusion/container/list/detail/preprocessed/list30_fwd.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list30_fwd.hpp>
#elif FUSION_MAX_LIST_SIZE <= 40
-#include <boost/fusion/container/list/detail/preprocessed/list40_fwd.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list40_fwd.hpp>
#elif FUSION_MAX_LIST_SIZE <= 50
-#include <boost/fusion/container/list/detail/preprocessed/list50_fwd.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list50_fwd.hpp>
#else
#error "FUSION_MAX_LIST_SIZE out of bounds for preprocessed headers"
#endif
diff --git a/boost/fusion/container/list/detail/preprocessed/list_to_cons.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons.hpp
index 0326bef1e5..d9ee9bb245 100644
--- a/boost/fusion/container/list/detail/preprocessed/list_to_cons.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons.hpp
@@ -8,15 +8,15 @@
==============================================================================*/
#if FUSION_MAX_LIST_SIZE <= 10
-#include <boost/fusion/container/list/detail/preprocessed/list_to_cons10.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons10.hpp>
#elif FUSION_MAX_LIST_SIZE <= 20
-#include <boost/fusion/container/list/detail/preprocessed/list_to_cons20.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons20.hpp>
#elif FUSION_MAX_LIST_SIZE <= 30
-#include <boost/fusion/container/list/detail/preprocessed/list_to_cons30.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons30.hpp>
#elif FUSION_MAX_LIST_SIZE <= 40
-#include <boost/fusion/container/list/detail/preprocessed/list_to_cons40.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons40.hpp>
#elif FUSION_MAX_LIST_SIZE <= 50
-#include <boost/fusion/container/list/detail/preprocessed/list_to_cons50.hpp>
+#include <boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons50.hpp>
#else
#error "FUSION_MAX_LIST_SIZE out of bounds for preprocessed headers"
#endif
diff --git a/boost/fusion/container/list/detail/preprocessed/list_to_cons10.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons10.hpp
index a98a8cc55f..a98a8cc55f 100644
--- a/boost/fusion/container/list/detail/preprocessed/list_to_cons10.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons10.hpp
diff --git a/boost/fusion/container/list/detail/preprocessed/list_to_cons20.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons20.hpp
index 3adce01d8d..3adce01d8d 100644
--- a/boost/fusion/container/list/detail/preprocessed/list_to_cons20.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons20.hpp
diff --git a/boost/fusion/container/list/detail/preprocessed/list_to_cons30.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons30.hpp
index 7a834a7064..7a834a7064 100644
--- a/boost/fusion/container/list/detail/preprocessed/list_to_cons30.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons30.hpp
diff --git a/boost/fusion/container/list/detail/preprocessed/list_to_cons40.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons40.hpp
index 731782dbfa..731782dbfa 100644
--- a/boost/fusion/container/list/detail/preprocessed/list_to_cons40.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons40.hpp
diff --git a/boost/fusion/container/list/detail/preprocessed/list_to_cons50.hpp b/boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons50.hpp
index e25371b5ae..e25371b5ae 100644
--- a/boost/fusion/container/list/detail/preprocessed/list_to_cons50.hpp
+++ b/boost/fusion/container/list/detail/cpp03/preprocessed/list_to_cons50.hpp
diff --git a/boost/fusion/container/list/detail/list_to_cons.hpp b/boost/fusion/container/list/detail/list_to_cons.hpp
index bc8718631c..1ce1cfbafb 100644
--- a/boost/fusion/container/list/detail/list_to_cons.hpp
+++ b/boost/fusion/container/list/detail/list_to_cons.hpp
@@ -1,76 +1,61 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014-2015 Kohei Takahashi
Distributed under the 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(FUSION_LIST_TO_CONS_07172005_1041)
-#define FUSION_LIST_TO_CONS_07172005_1041
+#ifndef FUSION_LIST_MAIN_10262014_0447
+#define FUSION_LIST_MAIN_10262014_0447
+#include <boost/config.hpp>
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/container/list/cons.hpp>
-#include <boost/fusion/container/list/limits.hpp>
-#include <boost/preprocessor/repetition/enum.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
-#include <boost/preprocessor/arithmetic/dec.hpp>
-
-#define FUSION_VOID(z, n, _) void_
-
-namespace boost { namespace fusion
-{
- struct nil_;
- struct void_;
-}}
+#include <boost/fusion/container/list/list_fwd.hpp>
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/list/detail/preprocessed/list_to_cons.hpp>
+///////////////////////////////////////////////////////////////////////////////
+// Without variadics, we will use the PP version
+///////////////////////////////////////////////////////////////////////////////
+#if !defined(BOOST_FUSION_HAS_VARIADIC_LIST)
+# include <boost/fusion/container/list/detail/cpp03/list_to_cons.hpp>
#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "preprocessed/list_to_cons" FUSION_MAX_LIST_SIZE_STR ".hpp")
-#endif
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+///////////////////////////////////////////////////////////////////////////////
+// C++11 interface
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/fusion/container/list/cons.hpp>
+#include <boost/fusion/support/detail/access.hpp>
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+namespace boost { namespace fusion { namespace detail
+{
+ template <typename ...T>
+ struct list_to_cons;
- This is an auto-generated file. Do not edit!
-==============================================================================*/
+ template <>
+ struct list_to_cons<>
+ {
+ typedef nil_ type;
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ static type call() { return type(); }
+ };
-namespace boost { namespace fusion { namespace detail
-{
- template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, typename T)>
- struct list_to_cons
+ template <typename Head, typename ...Tail>
+ struct list_to_cons<Head, Tail...>
{
- typedef T0 head_type;
- typedef list_to_cons<
- BOOST_PP_ENUM_SHIFTED_PARAMS(FUSION_MAX_LIST_SIZE, T), void_>
- tail_list_to_cons;
+ typedef Head head_type;
+ typedef list_to_cons<Tail...> tail_list_to_cons;
typedef typename tail_list_to_cons::type tail_type;
typedef cons<head_type, tail_type> type;
- #include <boost/fusion/container/list/detail/list_to_cons_call.hpp>
- };
-
- template <>
- struct list_to_cons<BOOST_PP_ENUM(FUSION_MAX_LIST_SIZE, FUSION_VOID, _)>
- {
- typedef nil_ type;
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ static type
+ call(typename detail::call_param<Head>::type _h,
+ typename detail::call_param<Tail>::type ..._t)
+ {
+ return type(_h, tail_list_to_cons::call(_t...));
+ }
};
}}}
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
-#undef FUSION_VOID
#endif
diff --git a/boost/fusion/container/list/list.hpp b/boost/fusion/container/list/list.hpp
index 5b584131cc..865a6d7def 100644
--- a/boost/fusion/container/list/list.hpp
+++ b/boost/fusion/container/list/list.hpp
@@ -1,103 +1,127 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014-2015 Kohei Takahashi
Distributed under the 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(FUSION_LIST_07172005_1153)
-#define FUSION_LIST_07172005_1153
+#ifndef FUSION_LIST_10262014_0537
+#define FUSION_LIST_10262014_0537
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/container/list/list_fwd.hpp>
-#include <boost/fusion/container/list/detail/list_to_cons.hpp>
-#include <boost/fusion/support/is_sequence.hpp>
-#include <boost/core/enable_if.hpp>
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/list/detail/preprocessed/list.hpp>
+///////////////////////////////////////////////////////////////////////////////
+// Without variadics, we will use the PP version
+///////////////////////////////////////////////////////////////////////////////
+#if !defined(BOOST_FUSION_HAS_VARIADIC_LIST)
+# include <boost/fusion/container/list/detail/cpp03/list.hpp>
#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/list" FUSION_MAX_LIST_SIZE_STR ".hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
+///////////////////////////////////////////////////////////////////////////////
+// C++11 interface
+///////////////////////////////////////////////////////////////////////////////
+#include <utility>
+#include <boost/fusion/container/list/detail/list_to_cons.hpp>
namespace boost { namespace fusion
{
struct nil_;
- struct void_;
- template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, typename T)>
- struct list
- : detail::list_to_cons<BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, T)>::type
+ template <>
+ struct list<>
+ : detail::list_to_cons<>::type
{
private:
- typedef
- detail::list_to_cons<BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, T)>
- list_to_cons;
+ typedef detail::list_to_cons<> list_to_cons;
+ typedef list_to_cons::type inherited_type;
public:
- typedef typename list_to_cons::type inherited_type;
-
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
list()
: inherited_type() {}
- template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, typename U)>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- list(list<BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, U)> const& rhs)
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <typename Sequence>
+ BOOST_FUSION_GPU_ENABLED
+ list(Sequence const& rhs)
: inherited_type(rhs) {}
template <typename Sequence>
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ list&
+ operator=(Sequence const& rhs)
+ {
+ inherited_type::operator=(rhs);
+ return *this;
+ }
+#else
+ template <typename Sequence>
+ BOOST_FUSION_GPU_ENABLED
+ list(Sequence&& rhs)
+ : inherited_type(std::forward<Sequence>(rhs)) {}
+
+ template <typename Sequence>
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ list&
+ operator=(Sequence&& rhs)
+ {
+ inherited_type::operator=(std::forward<Sequence>(rhs));
+ return *this;
+ }
+#endif
+ };
+
+ template <typename ...T>
+ struct list
+ : detail::list_to_cons<T...>::type
+ {
+ private:
+ typedef detail::list_to_cons<T...> list_to_cons;
+ typedef typename list_to_cons::type inherited_type;
+
+ public:
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- list(Sequence const& rhs
- , typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
+ list()
+ : inherited_type() {}
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <typename Sequence>
+ BOOST_FUSION_GPU_ENABLED
+ list(Sequence const& rhs)
: inherited_type(rhs) {}
+#else
+ template <typename Sequence>
+ BOOST_FUSION_GPU_ENABLED
+ list(Sequence&& rhs)
+ : inherited_type(std::forward<Sequence>(rhs)) {}
+#endif
- // Expand a couple of forwarding constructors for arguments
- // of type (T0), (T0, T1), (T0, T1, T2) etc. Exanple:
- //
- // list(
- // typename detail::call_param<T0>::type arg0
- // , typename detail::call_param<T1>::type arg1)
- // : inherited_type(list_to_cons::call(arg0, arg1)) {}
- #include <boost/fusion/container/list/detail/list_forward_ctor.hpp>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ explicit
+ list(typename detail::call_param<T>::type ...args)
+ : inherited_type(list_to_cons::call(args...)) {}
- template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, typename U)>
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <typename Sequence>
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
list&
- operator=(list<BOOST_PP_ENUM_PARAMS(FUSION_MAX_LIST_SIZE, U)> const& rhs)
+ operator=(Sequence const& rhs)
{
inherited_type::operator=(rhs);
return *this;
}
-
+#else
template <typename Sequence>
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- typename boost::enable_if<traits::is_sequence<Sequence>, list&>::type
- operator=(Sequence const& rhs)
+ list&
+ operator=(Sequence&& rhs)
{
- inherited_type::operator=(rhs);
+ inherited_type::operator=(std::forward<Sequence>(rhs));
return *this;
}
+#endif
};
}}
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
#endif
diff --git a/boost/fusion/container/list/list_fwd.hpp b/boost/fusion/container/list/list_fwd.hpp
index d827d283e8..c5f2619267 100644
--- a/boost/fusion/container/list/list_fwd.hpp
+++ b/boost/fusion/container/list/list_fwd.hpp
@@ -1,51 +1,43 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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(FUSION_LIST_FORWARD_07172005_0224)
-#define FUSION_LIST_FORWARD_07172005_0224
+#ifndef FUSION_LIST_FORWARD_10262014_0528
+#define FUSION_LIST_FORWARD_10262014_0528
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/container/list/limits.hpp>
-#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/config.hpp>
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/list/detail/preprocessed/list_fwd.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) \
+ || (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
+# if defined(BOOST_FUSION_HAS_VARIADIC_LIST)
+# undef BOOST_FUSION_HAS_VARIADIC_LIST
+# endif
#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/list" FUSION_MAX_LIST_SIZE_STR "_fwd.hpp")
+# if !defined(BOOST_FUSION_HAS_VARIADIC_LIST)
+# define BOOST_FUSION_HAS_VARIADIC_LIST
+# endif
#endif
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
+///////////////////////////////////////////////////////////////////////////////
+// With no variadics, we will use the C++03 version
+///////////////////////////////////////////////////////////////////////////////
+#if !defined(BOOST_FUSION_HAS_VARIADIC_LIST)
+# include <boost/fusion/container/list/detail/cpp03/list_fwd.hpp>
+#else
+///////////////////////////////////////////////////////////////////////////////
+// C++11 interface
+///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace fusion
{
struct void_;
- template <
- BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
- FUSION_MAX_LIST_SIZE, typename T, void_)
- >
+ template <typename ...T>
struct list;
}}
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
#endif
diff --git a/boost/fusion/container/map/detail/cpp03/limits.hpp b/boost/fusion/container/map/detail/cpp03/limits.hpp
index 43b5abb261..1eaa528c44 100644
--- a/boost/fusion/container/map/detail/cpp03/limits.hpp
+++ b/boost/fusion/container/map/detail/cpp03/limits.hpp
@@ -8,7 +8,7 @@
#define FUSION_MAP_LIMITS_07212005_1104
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/container/vector/limits.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/limits.hpp>
#if !defined(FUSION_MAX_MAP_SIZE)
# define FUSION_MAX_MAP_SIZE FUSION_MAX_VECTOR_SIZE
diff --git a/boost/fusion/container/map/detail/cpp03/map.hpp b/boost/fusion/container/map/detail/cpp03/map.hpp
index e2f471b5d3..3ff1d05d82 100644
--- a/boost/fusion/container/map/detail/cpp03/map.hpp
+++ b/boost/fusion/container/map/detail/cpp03/map.hpp
@@ -85,7 +85,7 @@ namespace boost { namespace fusion
: data(rhs.data) {}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
map(Sequence const& rhs)
: data(rhs) {}
diff --git a/boost/fusion/container/map/detail/cpp03/preprocessed/map10.hpp b/boost/fusion/container/map/detail/cpp03/preprocessed/map10.hpp
index 7b21767038..9721bb6245 100644
--- a/boost/fusion/container/map/detail/cpp03/preprocessed/map10.hpp
+++ b/boost/fusion/container/map/detail/cpp03/preprocessed/map10.hpp
@@ -28,7 +28,7 @@ namespace boost { namespace fusion
map(map const& rhs)
: data(rhs.data) {}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
map(Sequence const& rhs)
: data(rhs) {}
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
diff --git a/boost/fusion/container/map/detail/cpp03/preprocessed/map20.hpp b/boost/fusion/container/map/detail/cpp03/preprocessed/map20.hpp
index 1edb7a7d90..88075f454d 100644
--- a/boost/fusion/container/map/detail/cpp03/preprocessed/map20.hpp
+++ b/boost/fusion/container/map/detail/cpp03/preprocessed/map20.hpp
@@ -28,7 +28,7 @@ namespace boost { namespace fusion
map(map const& rhs)
: data(rhs.data) {}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
map(Sequence const& rhs)
: data(rhs) {}
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
diff --git a/boost/fusion/container/map/detail/cpp03/preprocessed/map30.hpp b/boost/fusion/container/map/detail/cpp03/preprocessed/map30.hpp
index 3ee6cf8b29..78730efc6b 100644
--- a/boost/fusion/container/map/detail/cpp03/preprocessed/map30.hpp
+++ b/boost/fusion/container/map/detail/cpp03/preprocessed/map30.hpp
@@ -28,7 +28,7 @@ namespace boost { namespace fusion
map(map const& rhs)
: data(rhs.data) {}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
map(Sequence const& rhs)
: data(rhs) {}
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
diff --git a/boost/fusion/container/map/detail/cpp03/preprocessed/map40.hpp b/boost/fusion/container/map/detail/cpp03/preprocessed/map40.hpp
index 6e28c907c6..2bfcdb57ca 100644
--- a/boost/fusion/container/map/detail/cpp03/preprocessed/map40.hpp
+++ b/boost/fusion/container/map/detail/cpp03/preprocessed/map40.hpp
@@ -28,7 +28,7 @@ namespace boost { namespace fusion
map(map const& rhs)
: data(rhs.data) {}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
map(Sequence const& rhs)
: data(rhs) {}
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
diff --git a/boost/fusion/container/map/detail/cpp03/preprocessed/map50.hpp b/boost/fusion/container/map/detail/cpp03/preprocessed/map50.hpp
index e91d145512..ec2792641f 100644
--- a/boost/fusion/container/map/detail/cpp03/preprocessed/map50.hpp
+++ b/boost/fusion/container/map/detail/cpp03/preprocessed/map50.hpp
@@ -28,7 +28,7 @@ namespace boost { namespace fusion
map(map const& rhs)
: data(rhs.data) {}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
map(Sequence const& rhs)
: data(rhs) {}
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
diff --git a/boost/fusion/container/map/map.hpp b/boost/fusion/container/map/map.hpp
index f93a693f74..e90d28a939 100644
--- a/boost/fusion/container/map/map.hpp
+++ b/boost/fusion/container/map/map.hpp
@@ -66,21 +66,21 @@ namespace boost { namespace fusion
{}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
map(Sequence const& seq
, typename enable_if<traits::is_sequence<Sequence>>::type* /*dummy*/ = 0)
: base_type(begin(seq), detail::map_impl_from_iterator())
{}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
map(Sequence& seq
, typename enable_if<traits::is_sequence<Sequence>>::type* /*dummy*/ = 0)
: base_type(begin(seq), detail::map_impl_from_iterator())
{}
template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
map(Sequence&& seq
, typename enable_if<traits::is_sequence<Sequence>>::type* /*dummy*/ = 0)
: base_type(begin(seq), detail::map_impl_from_iterator())
@@ -93,7 +93,7 @@ namespace boost { namespace fusion
{}
template <typename First, typename ...T_>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
map(First&& first, T_&&... rest)
: base_type(BOOST_FUSION_FWD_ELEM(First, first), BOOST_FUSION_FWD_ELEM(T_, rest)...)
{}
diff --git a/boost/fusion/container/set.hpp b/boost/fusion/container/set.hpp
index 6445397464..c9aa6241c2 100644
--- a/boost/fusion/container/set.hpp
+++ b/boost/fusion/container/set.hpp
@@ -8,7 +8,6 @@
#define FUSION_SEQUENCE_CLASS_SET_10022005_0607
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/container/set/limits.hpp>
#include <boost/fusion/container/set/set.hpp>
#include <boost/fusion/container/set/set_fwd.hpp>
#include <boost/fusion/container/set/convert.hpp>
diff --git a/boost/fusion/container/set/detail/as_set.hpp b/boost/fusion/container/set/detail/as_set.hpp
index a41498a333..1eb0d3fe12 100644
--- a/boost/fusion/container/set/detail/as_set.hpp
+++ b/boost/fusion/container/set/detail/as_set.hpp
@@ -1,139 +1,19 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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_PP_IS_ITERATING
-#if !defined(FUSION_AS_SET_0932005_1341)
-#define FUSION_AS_SET_0932005_1341
+#ifndef FUSION_AS_SET_11062014_2121
+#define FUSION_AS_SET_11062014_2121
-#include <boost/preprocessor/iterate.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/repeat.hpp>
-#include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/inc.hpp>
-#include <boost/preprocessor/dec.hpp>
-#include <boost/fusion/container/set/set.hpp>
-#include <boost/fusion/iterator/value_of.hpp>
-#include <boost/fusion/iterator/deref.hpp>
-#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/set/set_fwd.hpp>
-namespace boost { namespace fusion { namespace detail
-{
-BOOST_FUSION_BARRIER_BEGIN
-
- template <int size>
- struct as_set;
-
- template <>
- struct as_set<0>
- {
- template <typename Iterator>
- struct apply
- {
- typedef set<> type;
- };
-
- template <typename Iterator>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- static typename apply<Iterator>::type
- call(Iterator)
- {
- return set<>();
- }
- };
-
-BOOST_FUSION_BARRIER_END
-}}}
-
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/set/detail/preprocessed/as_set.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "preprocessed/as_set" FUSION_MAX_SET_SIZE_STR ".hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion { namespace detail
-{
-BOOST_FUSION_BARRIER_BEGIN
-
-#define BOOST_FUSION_NEXT_ITERATOR(z, n, data) \
- typedef typename fusion::result_of::next<BOOST_PP_CAT(I, n)>::type \
- BOOST_PP_CAT(I, BOOST_PP_INC(n));
-
-#define BOOST_FUSION_NEXT_CALL_ITERATOR(z, n, data) \
- typename gen::BOOST_PP_CAT(I, BOOST_PP_INC(n)) \
- BOOST_PP_CAT(i, BOOST_PP_INC(n)) = fusion::next(BOOST_PP_CAT(i, n));
-
-#define BOOST_FUSION_VALUE_OF_ITERATOR(z, n, data) \
- typedef typename fusion::result_of::value_of<BOOST_PP_CAT(I, n)>::type \
- BOOST_PP_CAT(T, n);
-
-#define BOOST_PP_FILENAME_1 <boost/fusion/container/set/detail/as_set.hpp>
-#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_SET_SIZE)
-#include BOOST_PP_ITERATE()
-
-#undef BOOST_FUSION_NEXT_ITERATOR
-#undef BOOST_FUSION_NEXT_CALL_ITERATOR
-#undef BOOST_FUSION_VALUE_OF_ITERATOR
-
-BOOST_FUSION_BARRIER_END
-}}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
-#endif
-#else // defined(BOOST_PP_IS_ITERATING)
///////////////////////////////////////////////////////////////////////////////
-//
-// Preprocessor vertical repetition code
-//
+// Without variadics, we will use the PP version
///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/container/set/detail/cpp03/as_set.hpp>
-#define N BOOST_PP_ITERATION()
-
- template <>
- struct as_set<N>
- {
- template <typename I0>
- struct apply
- {
- BOOST_PP_REPEAT(N, BOOST_FUSION_NEXT_ITERATOR, _)
- BOOST_PP_REPEAT(N, BOOST_FUSION_VALUE_OF_ITERATOR, _)
- typedef set<BOOST_PP_ENUM_PARAMS(N, T)> type;
- };
-
- template <typename Iterator>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- static typename apply<Iterator>::type
- call(Iterator const& i0)
- {
- typedef apply<Iterator> gen;
- typedef typename gen::type result;
- BOOST_PP_REPEAT(BOOST_PP_DEC(N), BOOST_FUSION_NEXT_CALL_ITERATOR, _)
- return result(BOOST_PP_ENUM_PARAMS(N, *i));
- }
- };
-
-#undef N
-#endif // defined(BOOST_PP_IS_ITERATING)
+#endif
diff --git a/boost/fusion/container/set/detail/cpp03/as_set.hpp b/boost/fusion/container/set/detail/cpp03/as_set.hpp
new file mode 100644
index 0000000000..c9159314b3
--- /dev/null
+++ b/boost/fusion/container/set/detail/cpp03/as_set.hpp
@@ -0,0 +1,139 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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_PP_IS_ITERATING
+#if !defined(FUSION_AS_SET_0932005_1341)
+#define FUSION_AS_SET_0932005_1341
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/inc.hpp>
+#include <boost/preprocessor/dec.hpp>
+#include <boost/fusion/container/set/set.hpp>
+#include <boost/fusion/iterator/value_of.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/iterator/next.hpp>
+
+namespace boost { namespace fusion { namespace detail
+{
+BOOST_FUSION_BARRIER_BEGIN
+
+ template <int size>
+ struct as_set;
+
+ template <>
+ struct as_set<0>
+ {
+ template <typename Iterator>
+ struct apply
+ {
+ typedef set<> type;
+ };
+
+ template <typename Iterator>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ static typename apply<Iterator>::type
+ call(Iterator)
+ {
+ return set<>();
+ }
+ };
+
+BOOST_FUSION_BARRIER_END
+}}}
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/as_set.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/as_set" FUSION_MAX_SET_SIZE_STR ".hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion { namespace detail
+{
+BOOST_FUSION_BARRIER_BEGIN
+
+#define BOOST_FUSION_NEXT_ITERATOR(z, n, data) \
+ typedef typename fusion::result_of::next<BOOST_PP_CAT(I, n)>::type \
+ BOOST_PP_CAT(I, BOOST_PP_INC(n));
+
+#define BOOST_FUSION_NEXT_CALL_ITERATOR(z, n, data) \
+ typename gen::BOOST_PP_CAT(I, BOOST_PP_INC(n)) \
+ BOOST_PP_CAT(i, BOOST_PP_INC(n)) = fusion::next(BOOST_PP_CAT(i, n));
+
+#define BOOST_FUSION_VALUE_OF_ITERATOR(z, n, data) \
+ typedef typename fusion::result_of::value_of<BOOST_PP_CAT(I, n)>::type \
+ BOOST_PP_CAT(T, n);
+
+#define BOOST_PP_FILENAME_1 <boost/fusion/container/set/detail/cpp03/as_set.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_SET_SIZE)
+#include BOOST_PP_ITERATE()
+
+#undef BOOST_FUSION_NEXT_ITERATOR
+#undef BOOST_FUSION_NEXT_CALL_ITERATOR
+#undef BOOST_FUSION_VALUE_OF_ITERATOR
+
+BOOST_FUSION_BARRIER_END
+}}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+#else // defined(BOOST_PP_IS_ITERATING)
+///////////////////////////////////////////////////////////////////////////////
+//
+// Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define N BOOST_PP_ITERATION()
+
+ template <>
+ struct as_set<N>
+ {
+ template <typename I0>
+ struct apply
+ {
+ BOOST_PP_REPEAT(N, BOOST_FUSION_NEXT_ITERATOR, _)
+ BOOST_PP_REPEAT(N, BOOST_FUSION_VALUE_OF_ITERATOR, _)
+ typedef set<BOOST_PP_ENUM_PARAMS(N, T)> type;
+ };
+
+ template <typename Iterator>
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ static typename apply<Iterator>::type
+ call(Iterator const& i0)
+ {
+ typedef apply<Iterator> gen;
+ typedef typename gen::type result;
+ BOOST_PP_REPEAT(BOOST_PP_DEC(N), BOOST_FUSION_NEXT_CALL_ITERATOR, _)
+ return result(BOOST_PP_ENUM_PARAMS(N, *i));
+ }
+ };
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
diff --git a/boost/fusion/container/set/limits.hpp b/boost/fusion/container/set/detail/cpp03/limits.hpp
index adfecdbd0a..2b800abfed 100644
--- a/boost/fusion/container/set/limits.hpp
+++ b/boost/fusion/container/set/detail/cpp03/limits.hpp
@@ -8,7 +8,7 @@
#define FUSION_SET_LIMITS_09162005_1103
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/container/vector/limits.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/limits.hpp>
#if !defined(FUSION_MAX_SET_SIZE)
# define FUSION_MAX_SET_SIZE FUSION_MAX_VECTOR_SIZE
diff --git a/boost/fusion/container/set/detail/preprocessed/as_set.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/as_set.hpp
index 4231dcb180..da257ad900 100644
--- a/boost/fusion/container/set/detail/preprocessed/as_set.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/as_set.hpp
@@ -8,15 +8,15 @@
==============================================================================*/
#if FUSION_MAX_SET_SIZE <= 10
-#include <boost/fusion/container/set/detail/preprocessed/as_set10.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/as_set10.hpp>
#elif FUSION_MAX_SET_SIZE <= 20
-#include <boost/fusion/container/set/detail/preprocessed/as_set20.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/as_set20.hpp>
#elif FUSION_MAX_SET_SIZE <= 30
-#include <boost/fusion/container/set/detail/preprocessed/as_set30.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/as_set30.hpp>
#elif FUSION_MAX_SET_SIZE <= 40
-#include <boost/fusion/container/set/detail/preprocessed/as_set40.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/as_set40.hpp>
#elif FUSION_MAX_SET_SIZE <= 50
-#include <boost/fusion/container/set/detail/preprocessed/as_set50.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/as_set50.hpp>
#else
#error "FUSION_MAX_SET_SIZE out of bounds for preprocessed headers"
#endif
diff --git a/boost/fusion/container/set/detail/preprocessed/as_set10.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/as_set10.hpp
index 019b0b7970..019b0b7970 100644
--- a/boost/fusion/container/set/detail/preprocessed/as_set10.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/as_set10.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/as_set20.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/as_set20.hpp
index 8299b60794..8299b60794 100644
--- a/boost/fusion/container/set/detail/preprocessed/as_set20.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/as_set20.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/as_set30.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/as_set30.hpp
index b8f8adb7a2..b8f8adb7a2 100644
--- a/boost/fusion/container/set/detail/preprocessed/as_set30.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/as_set30.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/as_set40.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/as_set40.hpp
index de5091f8c3..de5091f8c3 100644
--- a/boost/fusion/container/set/detail/preprocessed/as_set40.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/as_set40.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/as_set50.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/as_set50.hpp
index d169b04faf..d169b04faf 100644
--- a/boost/fusion/container/set/detail/preprocessed/as_set50.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/as_set50.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/set.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/set.hpp
index a64fab2c8e..715d5744f9 100644
--- a/boost/fusion/container/set/detail/preprocessed/set.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/set.hpp
@@ -8,15 +8,15 @@
==============================================================================*/
#if FUSION_MAX_SET_SIZE <= 10
-#include <boost/fusion/container/set/detail/preprocessed/set10.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/set10.hpp>
#elif FUSION_MAX_SET_SIZE <= 20
-#include <boost/fusion/container/set/detail/preprocessed/set20.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/set20.hpp>
#elif FUSION_MAX_SET_SIZE <= 30
-#include <boost/fusion/container/set/detail/preprocessed/set30.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/set30.hpp>
#elif FUSION_MAX_SET_SIZE <= 40
-#include <boost/fusion/container/set/detail/preprocessed/set40.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/set40.hpp>
#elif FUSION_MAX_SET_SIZE <= 50
-#include <boost/fusion/container/set/detail/preprocessed/set50.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/set50.hpp>
#else
#error "FUSION_MAX_SET_SIZE out of bounds for preprocessed headers"
#endif
diff --git a/boost/fusion/container/set/detail/preprocessed/set10.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/set10.hpp
index d2eba4c8f5..d2eba4c8f5 100644
--- a/boost/fusion/container/set/detail/preprocessed/set10.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/set10.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/set10_fwd.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/set10_fwd.hpp
index 8b6253dc3b..8b6253dc3b 100644
--- a/boost/fusion/container/set/detail/preprocessed/set10_fwd.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/set10_fwd.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/set20.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/set20.hpp
index 500e726e80..500e726e80 100644
--- a/boost/fusion/container/set/detail/preprocessed/set20.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/set20.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/set20_fwd.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/set20_fwd.hpp
index acbb56dee0..acbb56dee0 100644
--- a/boost/fusion/container/set/detail/preprocessed/set20_fwd.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/set20_fwd.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/set30.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/set30.hpp
index 6c92bead0e..6c92bead0e 100644
--- a/boost/fusion/container/set/detail/preprocessed/set30.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/set30.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/set30_fwd.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/set30_fwd.hpp
index 9c774b0dad..9c774b0dad 100644
--- a/boost/fusion/container/set/detail/preprocessed/set30_fwd.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/set30_fwd.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/set40.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/set40.hpp
index d3c3e5eb58..d3c3e5eb58 100644
--- a/boost/fusion/container/set/detail/preprocessed/set40.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/set40.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/set40_fwd.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/set40_fwd.hpp
index 2f251c108c..2f251c108c 100644
--- a/boost/fusion/container/set/detail/preprocessed/set40_fwd.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/set40_fwd.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/set50.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/set50.hpp
index 1d2dfd446d..1d2dfd446d 100644
--- a/boost/fusion/container/set/detail/preprocessed/set50.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/set50.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/set50_fwd.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/set50_fwd.hpp
index 478b98b578..478b98b578 100644
--- a/boost/fusion/container/set/detail/preprocessed/set50_fwd.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/set50_fwd.hpp
diff --git a/boost/fusion/container/set/detail/preprocessed/set_fwd.hpp b/boost/fusion/container/set/detail/cpp03/preprocessed/set_fwd.hpp
index 28a3e814d2..31e8e411bf 100644
--- a/boost/fusion/container/set/detail/preprocessed/set_fwd.hpp
+++ b/boost/fusion/container/set/detail/cpp03/preprocessed/set_fwd.hpp
@@ -8,15 +8,15 @@
==============================================================================*/
#if FUSION_MAX_SET_SIZE <= 10
-#include <boost/fusion/container/set/detail/preprocessed/set10_fwd.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/set10_fwd.hpp>
#elif FUSION_MAX_SET_SIZE <= 20
-#include <boost/fusion/container/set/detail/preprocessed/set20_fwd.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/set20_fwd.hpp>
#elif FUSION_MAX_SET_SIZE <= 30
-#include <boost/fusion/container/set/detail/preprocessed/set30_fwd.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/set30_fwd.hpp>
#elif FUSION_MAX_SET_SIZE <= 40
-#include <boost/fusion/container/set/detail/preprocessed/set40_fwd.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/set40_fwd.hpp>
#elif FUSION_MAX_SET_SIZE <= 50
-#include <boost/fusion/container/set/detail/preprocessed/set50_fwd.hpp>
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/set50_fwd.hpp>
#else
#error "FUSION_MAX_SET_SIZE out of bounds for preprocessed headers"
#endif
diff --git a/boost/fusion/container/set/detail/cpp03/set.hpp b/boost/fusion/container/set/detail/cpp03/set.hpp
new file mode 100644
index 0000000000..46191c5c63
--- /dev/null
+++ b/boost/fusion/container/set/detail/cpp03/set.hpp
@@ -0,0 +1,106 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_SET_09162005_1104)
+#define FUSION_SET_09162005_1104
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/support/is_sequence.hpp>
+#include <boost/fusion/support/sequence_base.hpp>
+#include <boost/fusion/support/category_of.hpp>
+#include <boost/fusion/support/detail/access.hpp>
+#include <boost/fusion/container/set/set_fwd.hpp>
+#include <boost/fusion/container/set/detail/begin_impl.hpp>
+#include <boost/fusion/container/set/detail/end_impl.hpp>
+#include <boost/fusion/container/set/detail/value_of_impl.hpp>
+#include <boost/fusion/container/set/detail/deref_data_impl.hpp>
+#include <boost/fusion/container/set/detail/deref_impl.hpp>
+#include <boost/fusion/container/set/detail/key_of_impl.hpp>
+#include <boost/fusion/container/set/detail/value_of_data_impl.hpp>
+#include <boost/fusion/container/vector/vector.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/core/enable_if.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/set.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/set" FUSION_MAX_SET_SIZE_STR ".hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct void_;
+ struct fusion_sequence_tag;
+
+ template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_SET_SIZE, typename T)>
+ struct set : sequence_base<set<BOOST_PP_ENUM_PARAMS(FUSION_MAX_SET_SIZE, T)> >
+ {
+ struct category : forward_traversal_tag, associative_tag {};
+
+ typedef set_tag fusion_tag;
+ typedef fusion_sequence_tag tag; // this gets picked up by MPL
+ typedef mpl::false_ is_view;
+
+ typedef vector<
+ BOOST_PP_ENUM_PARAMS(FUSION_MAX_SET_SIZE, T)>
+ storage_type;
+
+ typedef typename storage_type::size size;
+
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ set()
+ : data() {}
+
+ template <typename Sequence>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ set(Sequence const& rhs
+ , typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
+ : data(rhs) {}
+
+ #include <boost/fusion/container/set/detail/cpp03/set_forward_ctor.hpp>
+
+ template <typename T>
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ set&
+ operator=(T const& rhs)
+ {
+ data = rhs;
+ return *this;
+ }
+
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ storage_type& get_data() { return data; }
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ storage_type const& get_data() const { return data; }
+
+ private:
+
+ storage_type data;
+ };
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
diff --git a/boost/fusion/container/set/detail/set_forward_ctor.hpp b/boost/fusion/container/set/detail/cpp03/set_forward_ctor.hpp
index 5d3961048c..aa90b60111 100644
--- a/boost/fusion/container/set/detail/set_forward_ctor.hpp
+++ b/boost/fusion/container/set/detail/cpp03/set_forward_ctor.hpp
@@ -13,7 +13,7 @@
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#define BOOST_PP_FILENAME_1 \
- <boost/fusion/container/set/detail/set_forward_ctor.hpp>
+ <boost/fusion/container/set/detail/cpp03/set_forward_ctor.hpp>
#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_SET_SIZE)
#include BOOST_PP_ITERATE()
diff --git a/boost/fusion/container/set/detail/cpp03/set_fwd.hpp b/boost/fusion/container/set/detail/cpp03/set_fwd.hpp
new file mode 100644
index 0000000000..f50f6083ea
--- /dev/null
+++ b/boost/fusion/container/set/detail/cpp03/set_fwd.hpp
@@ -0,0 +1,53 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_SET_FORWARD_09162005_1102)
+#define FUSION_SET_FORWARD_09162005_1102
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/set/detail/cpp03/limits.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/set/detail/cpp03/preprocessed/set_fwd.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/set" FUSION_MAX_SET_SIZE_STR "_fwd.hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct void_;
+ struct set_tag;
+ struct set_iterator_tag;
+
+ template <
+ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ FUSION_MAX_SET_SIZE, typename T, void_)
+ >
+ struct set;
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
diff --git a/boost/fusion/container/set/set.hpp b/boost/fusion/container/set/set.hpp
index 65a080b0ab..59f4eafc02 100644
--- a/boost/fusion/container/set/set.hpp
+++ b/boost/fusion/container/set/set.hpp
@@ -1,106 +1,20 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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(FUSION_SET_09162005_1104)
-#define FUSION_SET_09162005_1104
+#ifndef FUSION_SET_11062014_1726
+#define FUSION_SET_11062014_1726
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/support/is_sequence.hpp>
-#include <boost/fusion/support/sequence_base.hpp>
-#include <boost/fusion/support/category_of.hpp>
-#include <boost/fusion/support/detail/access.hpp>
#include <boost/fusion/container/set/set_fwd.hpp>
-#include <boost/fusion/container/set/detail/begin_impl.hpp>
-#include <boost/fusion/container/set/detail/end_impl.hpp>
-#include <boost/fusion/container/set/detail/value_of_impl.hpp>
-#include <boost/fusion/container/set/detail/deref_data_impl.hpp>
-#include <boost/fusion/container/set/detail/deref_impl.hpp>
-#include <boost/fusion/container/set/detail/key_of_impl.hpp>
-#include <boost/fusion/container/set/detail/value_of_data_impl.hpp>
-#include <boost/fusion/container/vector/vector.hpp>
-#include <boost/mpl/identity.hpp>
-#include <boost/mpl/bool.hpp>
-#include <boost/core/enable_if.hpp>
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/set/detail/preprocessed/set.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/set" FUSION_MAX_SET_SIZE_STR ".hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+///////////////////////////////////////////////////////////////////////////////
+// Without variadics, we will use the PP version
+///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/container/set/detail/cpp03/set.hpp>
- This is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
#endif
-namespace boost { namespace fusion
-{
- struct void_;
- struct fusion_sequence_tag;
-
- template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_SET_SIZE, typename T)>
- struct set : sequence_base<set<BOOST_PP_ENUM_PARAMS(FUSION_MAX_SET_SIZE, T)> >
- {
- struct category : forward_traversal_tag, associative_tag {};
-
- typedef set_tag fusion_tag;
- typedef fusion_sequence_tag tag; // this gets picked up by MPL
- typedef mpl::false_ is_view;
-
- typedef vector<
- BOOST_PP_ENUM_PARAMS(FUSION_MAX_SET_SIZE, T)>
- storage_type;
-
- typedef typename storage_type::size size;
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- set()
- : data() {}
-
- template <typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- set(Sequence const& rhs
- , typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
- : data(rhs) {}
-
- #include <boost/fusion/container/set/detail/set_forward_ctor.hpp>
-
- template <typename T>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- set&
- operator=(T const& rhs)
- {
- data = rhs;
- return *this;
- }
-
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- storage_type& get_data() { return data; }
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- storage_type const& get_data() const { return data; }
-
- private:
-
- storage_type data;
- };
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
-#endif
diff --git a/boost/fusion/container/set/set_fwd.hpp b/boost/fusion/container/set/set_fwd.hpp
index 2de3db6d5b..50d8d1c8bd 100644
--- a/boost/fusion/container/set/set_fwd.hpp
+++ b/boost/fusion/container/set/set_fwd.hpp
@@ -1,53 +1,19 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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(FUSION_SET_FORWARD_09162005_1102)
-#define FUSION_SET_FORWARD_09162005_1102
+#ifndef FUSION_SET_FORWARD_11062014_1720
+#define FUSION_SET_FORWARD_11062014_1720
+#include <boost/config.hpp>
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/container/set/limits.hpp>
-#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/set/detail/preprocessed/set_fwd.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/set" FUSION_MAX_SET_SIZE_STR "_fwd.hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+// With no variadics, we will use the C++03 version
+///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/container/set/detail/cpp03/set_fwd.hpp>
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
#endif
-namespace boost { namespace fusion
-{
- struct void_;
- struct set_tag;
- struct set_iterator_tag;
-
- template <
- BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
- FUSION_MAX_SET_SIZE, typename T, void_)
- >
- struct set;
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
-#endif
diff --git a/boost/fusion/container/vector.hpp b/boost/fusion/container/vector.hpp
index 06fa5a04bb..a999c8b023 100644
--- a/boost/fusion/container/vector.hpp
+++ b/boost/fusion/container/vector.hpp
@@ -8,7 +8,7 @@
#define FUSION_SEQUENCE_CLASS_VECTOR_10022005_0602
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/container/vector/limits.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/limits.hpp>
#include <boost/fusion/container/vector/vector10.hpp>
#if (FUSION_MAX_VECTOR_SIZE > 10)
diff --git a/boost/fusion/container/vector/detail/as_vector.hpp b/boost/fusion/container/vector/detail/as_vector.hpp
index b5f5e2d05f..eaaac89638 100644
--- a/boost/fusion/container/vector/detail/as_vector.hpp
+++ b/boost/fusion/container/vector/detail/as_vector.hpp
@@ -1,139 +1,19 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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_PP_IS_ITERATING
-#if !defined(FUSION_AS_VECTOR_09222005_0950)
-#define FUSION_AS_VECTOR_09222005_0950
+#ifndef FUSION_AS_VECTOR_11052014_1801
+#define FUSION_AS_VECTOR_11052014_1801
-#include <boost/preprocessor/iterate.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/repeat.hpp>
-#include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/inc.hpp>
-#include <boost/preprocessor/dec.hpp>
-#include <boost/fusion/container/vector/vector.hpp>
-#include <boost/fusion/iterator/value_of.hpp>
-#include <boost/fusion/iterator/deref.hpp>
-#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/support/config.hpp>
-namespace boost { namespace fusion { namespace detail
-{
-BOOST_FUSION_BARRIER_BEGIN
-
- template <int size>
- struct as_vector;
-
- template <>
- struct as_vector<0>
- {
- template <typename Iterator>
- struct apply
- {
- typedef vector0<> type;
- };
-
- template <typename Iterator>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- static typename apply<Iterator>::type
- call(Iterator)
- {
- return vector0<>();
- }
- };
-
-BOOST_FUSION_BARRIER_END
-}}}
-
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/vector/detail/preprocessed/as_vector.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "preprocessed/as_vector" FUSION_MAX_VECTOR_SIZE_STR ".hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion { namespace detail
-{
-BOOST_FUSION_BARRIER_BEGIN
-
-#define BOOST_FUSION_NEXT_ITERATOR(z, n, data) \
- typedef typename fusion::result_of::next<BOOST_PP_CAT(I, n)>::type \
- BOOST_PP_CAT(I, BOOST_PP_INC(n));
-
-#define BOOST_FUSION_NEXT_CALL_ITERATOR(z, n, data) \
- typename gen::BOOST_PP_CAT(I, BOOST_PP_INC(n)) \
- BOOST_PP_CAT(i, BOOST_PP_INC(n)) = fusion::next(BOOST_PP_CAT(i, n));
-
-#define BOOST_FUSION_VALUE_OF_ITERATOR(z, n, data) \
- typedef typename fusion::result_of::value_of<BOOST_PP_CAT(I, n)>::type \
- BOOST_PP_CAT(T, n);
-
-#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/as_vector.hpp>
-#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
-#include BOOST_PP_ITERATE()
-
-#undef BOOST_FUSION_NEXT_ITERATOR
-#undef BOOST_FUSION_NEXT_CALL_ITERATOR
-#undef BOOST_FUSION_VALUE_OF_ITERATOR
-
-BOOST_FUSION_BARRIER_END
-}}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
-#endif
-#else // defined(BOOST_PP_IS_ITERATING)
///////////////////////////////////////////////////////////////////////////////
-//
-// Preprocessor vertical repetition code
-//
+// Without variadics, we will use the PP version
///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/container/vector/detail/cpp03/as_vector.hpp>
-#define N BOOST_PP_ITERATION()
-
- template <>
- struct as_vector<N>
- {
- template <typename I0>
- struct apply
- {
- BOOST_PP_REPEAT(N, BOOST_FUSION_NEXT_ITERATOR, _)
- BOOST_PP_REPEAT(N, BOOST_FUSION_VALUE_OF_ITERATOR, _)
- typedef BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM_PARAMS(N, T)> type;
- };
-
- template <typename Iterator>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- static typename apply<Iterator>::type
- call(Iterator const& i0)
- {
- typedef apply<Iterator> gen;
- typedef typename gen::type result;
- BOOST_PP_REPEAT(BOOST_PP_DEC(N), BOOST_FUSION_NEXT_CALL_ITERATOR, _)
- return result(BOOST_PP_ENUM_PARAMS(N, *i));
- }
- };
+#endif
-#undef N
-#endif // defined(BOOST_PP_IS_ITERATING)
diff --git a/boost/fusion/container/vector/detail/cpp03/as_vector.hpp b/boost/fusion/container/vector/detail/cpp03/as_vector.hpp
new file mode 100644
index 0000000000..bd7fa76be6
--- /dev/null
+++ b/boost/fusion/container/vector/detail/cpp03/as_vector.hpp
@@ -0,0 +1,139 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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_PP_IS_ITERATING
+#if !defined(FUSION_AS_VECTOR_09222005_0950)
+#define FUSION_AS_VECTOR_09222005_0950
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/inc.hpp>
+#include <boost/preprocessor/dec.hpp>
+#include <boost/fusion/container/vector/vector.hpp>
+#include <boost/fusion/iterator/value_of.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/iterator/next.hpp>
+
+namespace boost { namespace fusion { namespace detail
+{
+BOOST_FUSION_BARRIER_BEGIN
+
+ template <int size>
+ struct as_vector;
+
+ template <>
+ struct as_vector<0>
+ {
+ template <typename Iterator>
+ struct apply
+ {
+ typedef vector0<> type;
+ };
+
+ template <typename Iterator>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ static typename apply<Iterator>::type
+ call(Iterator)
+ {
+ return vector0<>();
+ }
+ };
+
+BOOST_FUSION_BARRIER_END
+}}}
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/as_vector" FUSION_MAX_VECTOR_SIZE_STR ".hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion { namespace detail
+{
+BOOST_FUSION_BARRIER_BEGIN
+
+#define BOOST_FUSION_NEXT_ITERATOR(z, n, data) \
+ typedef typename fusion::result_of::next<BOOST_PP_CAT(I, n)>::type \
+ BOOST_PP_CAT(I, BOOST_PP_INC(n));
+
+#define BOOST_FUSION_NEXT_CALL_ITERATOR(z, n, data) \
+ typename gen::BOOST_PP_CAT(I, BOOST_PP_INC(n)) \
+ BOOST_PP_CAT(i, BOOST_PP_INC(n)) = fusion::next(BOOST_PP_CAT(i, n));
+
+#define BOOST_FUSION_VALUE_OF_ITERATOR(z, n, data) \
+ typedef typename fusion::result_of::value_of<BOOST_PP_CAT(I, n)>::type \
+ BOOST_PP_CAT(T, n);
+
+#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/cpp03/as_vector.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
+#include BOOST_PP_ITERATE()
+
+#undef BOOST_FUSION_NEXT_ITERATOR
+#undef BOOST_FUSION_NEXT_CALL_ITERATOR
+#undef BOOST_FUSION_VALUE_OF_ITERATOR
+
+BOOST_FUSION_BARRIER_END
+}}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+#else // defined(BOOST_PP_IS_ITERATING)
+///////////////////////////////////////////////////////////////////////////////
+//
+// Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define N BOOST_PP_ITERATION()
+
+ template <>
+ struct as_vector<N>
+ {
+ template <typename I0>
+ struct apply
+ {
+ BOOST_PP_REPEAT(N, BOOST_FUSION_NEXT_ITERATOR, _)
+ BOOST_PP_REPEAT(N, BOOST_FUSION_VALUE_OF_ITERATOR, _)
+ typedef BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM_PARAMS(N, T)> type;
+ };
+
+ template <typename Iterator>
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ static typename apply<Iterator>::type
+ call(Iterator const& i0)
+ {
+ typedef apply<Iterator> gen;
+ typedef typename gen::type result;
+ BOOST_PP_REPEAT(BOOST_PP_DEC(N), BOOST_FUSION_NEXT_CALL_ITERATOR, _)
+ return result(BOOST_PP_ENUM_PARAMS(N, *i));
+ }
+ };
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
diff --git a/boost/fusion/container/vector/limits.hpp b/boost/fusion/container/vector/detail/cpp03/limits.hpp
index 6e106144bb..6e106144bb 100644
--- a/boost/fusion/container/vector/limits.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/limits.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/as_vector.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector.hpp
index c70f8a7c42..521443ef8e 100644
--- a/boost/fusion/container/vector/detail/preprocessed/as_vector.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector.hpp
@@ -8,15 +8,15 @@
==============================================================================*/
#if FUSION_MAX_VECTOR_SIZE <= 10
-#include <boost/fusion/container/vector/detail/preprocessed/as_vector10.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector10.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 20
-#include <boost/fusion/container/vector/detail/preprocessed/as_vector20.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector20.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 30
-#include <boost/fusion/container/vector/detail/preprocessed/as_vector30.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector30.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 40
-#include <boost/fusion/container/vector/detail/preprocessed/as_vector40.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector40.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 50
-#include <boost/fusion/container/vector/detail/preprocessed/as_vector50.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector50.hpp>
#else
#error "FUSION_MAX_VECTOR_SIZE out of bounds for preprocessed headers"
#endif
diff --git a/boost/fusion/container/vector/detail/preprocessed/as_vector10.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector10.hpp
index 92fdbc07b4..92fdbc07b4 100644
--- a/boost/fusion/container/vector/detail/preprocessed/as_vector10.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector10.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/as_vector20.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector20.hpp
index fa99a4a58b..fa99a4a58b 100644
--- a/boost/fusion/container/vector/detail/preprocessed/as_vector20.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector20.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/as_vector30.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector30.hpp
index 578524a642..578524a642 100644
--- a/boost/fusion/container/vector/detail/preprocessed/as_vector30.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector30.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/as_vector40.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector40.hpp
index 93d63ee2f9..93d63ee2f9 100644
--- a/boost/fusion/container/vector/detail/preprocessed/as_vector40.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector40.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/as_vector50.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector50.hpp
index 6f6cc4802f..6f6cc4802f 100644
--- a/boost/fusion/container/vector/detail/preprocessed/as_vector50.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector50.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector.hpp
index 040fff948b..35b8e64329 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector.hpp
@@ -8,15 +8,15 @@
==============================================================================*/
#if FUSION_MAX_VECTOR_SIZE <= 10
-#include <boost/fusion/container/vector/detail/preprocessed/vvector10.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vvector10.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 20
-#include <boost/fusion/container/vector/detail/preprocessed/vvector20.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vvector20.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 30
-#include <boost/fusion/container/vector/detail/preprocessed/vvector30.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vvector30.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 40
-#include <boost/fusion/container/vector/detail/preprocessed/vvector40.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vvector40.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 50
-#include <boost/fusion/container/vector/detail/preprocessed/vvector50.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vvector50.hpp>
#else
#error "FUSION_MAX_VECTOR_SIZE out of bounds for preprocessed headers"
#endif
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector10.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector10.hpp
index d5e8aad116..d5e8aad116 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector10.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector10.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector10_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector10_fwd.hpp
index 33f817ffaf..33f817ffaf 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector10_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector10_fwd.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector20.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector20.hpp
index 91a9e59c46..91a9e59c46 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector20.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector20.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector20_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector20_fwd.hpp
index b1672857a8..b1672857a8 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector20_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector20_fwd.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector30.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector30.hpp
index c823452038..c823452038 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector30.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector30.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector30_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector30_fwd.hpp
index 39f96aa836..39f96aa836 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector30_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector30_fwd.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector40.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector40.hpp
index ec16fcd94a..ec16fcd94a 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector40.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector40.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector40_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector40_fwd.hpp
index e1d6e0911a..e1d6e0911a 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector40_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector40_fwd.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector50.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector50.hpp
index 2d787edfb6..2d787edfb6 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector50.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector50.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector50_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector50_fwd.hpp
index 6829e9b50f..6829e9b50f 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector50_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector50_fwd.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector_chooser.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser.hpp
index e956bf24e1..fb8f0e2f5b 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector_chooser.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser.hpp
@@ -7,15 +7,15 @@
This is an auto-generated file. Do not edit!
==============================================================================*/
#if FUSION_MAX_VECTOR_SIZE <= 10
-#include <boost/fusion/container/vector/detail/preprocessed/vector_chooser10.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser10.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 20
-#include <boost/fusion/container/vector/detail/preprocessed/vector_chooser20.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser20.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 30
-#include <boost/fusion/container/vector/detail/preprocessed/vector_chooser30.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser30.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 40
-#include <boost/fusion/container/vector/detail/preprocessed/vector_chooser40.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser40.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 50
-#include <boost/fusion/container/vector/detail/preprocessed/vector_chooser50.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser50.hpp>
#else
#error "FUSION_MAX_VECTOR_SIZE out of bounds for preprocessed headers"
#endif
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector_chooser10.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser10.hpp
index d631b53208..d631b53208 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector_chooser10.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser10.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector_chooser20.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser20.hpp
index 9628f483ed..9628f483ed 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector_chooser20.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser20.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector_chooser30.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser30.hpp
index 38edabf45e..38edabf45e 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector_chooser30.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser30.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector_chooser40.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser40.hpp
index a784b75736..a784b75736 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector_chooser40.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser40.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector_chooser50.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser50.hpp
index fc9a260e20..fc9a260e20 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector_chooser50.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser50.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vector_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector_fwd.hpp
index e2576f9004..42c3f5bc6c 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vector_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vector_fwd.hpp
@@ -8,15 +8,15 @@
==============================================================================*/
#if FUSION_MAX_VECTOR_SIZE <= 10
-#include <boost/fusion/container/vector/detail/preprocessed/vvector10_fwd.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vvector10_fwd.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 20
-#include <boost/fusion/container/vector/detail/preprocessed/vvector20_fwd.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vvector20_fwd.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 30
-#include <boost/fusion/container/vector/detail/preprocessed/vvector30_fwd.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vvector30_fwd.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 40
-#include <boost/fusion/container/vector/detail/preprocessed/vvector40_fwd.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vvector40_fwd.hpp>
#elif FUSION_MAX_VECTOR_SIZE <= 50
-#include <boost/fusion/container/vector/detail/preprocessed/vvector50_fwd.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vvector50_fwd.hpp>
#else
#error "FUSION_MAX_VECTOR_SIZE out of bounds for preprocessed headers"
#endif
diff --git a/boost/fusion/container/vector/detail/preprocessed/vvector10.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector10.hpp
index 792809bc9c..cd2bd58b31 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vvector10.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector10.hpp
@@ -38,10 +38,6 @@ namespace boost { namespace fusion
vector(vector const& rhs)
: vec(rhs.vec) {}
template <typename Sequence>
-
-# if !defined(BOOST_CLANG)
- BOOST_CONSTEXPR
-# endif
BOOST_FUSION_GPU_ENABLED
vector(Sequence const& rhs,
typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
diff --git a/boost/fusion/container/vector/detail/preprocessed/vvector10_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector10_fwd.hpp
index 97f64fa359..97f64fa359 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vvector10_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector10_fwd.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vvector20.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector20.hpp
index f1d01617e1..809485fe25 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vvector20.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector20.hpp
@@ -38,10 +38,6 @@ namespace boost { namespace fusion
vector(vector const& rhs)
: vec(rhs.vec) {}
template <typename Sequence>
-
-# if !defined(BOOST_CLANG)
- BOOST_CONSTEXPR
-# endif
BOOST_FUSION_GPU_ENABLED
vector(Sequence const& rhs,
typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
diff --git a/boost/fusion/container/vector/detail/preprocessed/vvector20_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector20_fwd.hpp
index 8d4ea992d1..8d4ea992d1 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vvector20_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector20_fwd.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vvector30.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector30.hpp
index dccc1f0186..3f75a05f35 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vvector30.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector30.hpp
@@ -38,10 +38,6 @@ namespace boost { namespace fusion
vector(vector const& rhs)
: vec(rhs.vec) {}
template <typename Sequence>
-
-# if !defined(BOOST_CLANG)
- BOOST_CONSTEXPR
-# endif
BOOST_FUSION_GPU_ENABLED
vector(Sequence const& rhs,
typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
diff --git a/boost/fusion/container/vector/detail/preprocessed/vvector30_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector30_fwd.hpp
index 03f289e9c9..03f289e9c9 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vvector30_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector30_fwd.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vvector40.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector40.hpp
index 442a4fe995..6c7654ccc5 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vvector40.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector40.hpp
@@ -38,10 +38,6 @@ namespace boost { namespace fusion
vector(vector const& rhs)
: vec(rhs.vec) {}
template <typename Sequence>
-
-# if !defined(BOOST_CLANG)
- BOOST_CONSTEXPR
-# endif
BOOST_FUSION_GPU_ENABLED
vector(Sequence const& rhs,
typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
diff --git a/boost/fusion/container/vector/detail/preprocessed/vvector40_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector40_fwd.hpp
index 55c1097a75..55c1097a75 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vvector40_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector40_fwd.hpp
diff --git a/boost/fusion/container/vector/detail/preprocessed/vvector50.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector50.hpp
index 5237a4f305..47fce0e19d 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vvector50.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector50.hpp
@@ -38,10 +38,6 @@ namespace boost { namespace fusion
vector(vector const& rhs)
: vec(rhs.vec) {}
template <typename Sequence>
-
-# if !defined(BOOST_CLANG)
- BOOST_CONSTEXPR
-# endif
BOOST_FUSION_GPU_ENABLED
vector(Sequence const& rhs,
typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
diff --git a/boost/fusion/container/vector/detail/preprocessed/vvector50_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector50_fwd.hpp
index 621f1606bf..621f1606bf 100644
--- a/boost/fusion/container/vector/detail/preprocessed/vvector50_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/preprocessed/vvector50_fwd.hpp
diff --git a/boost/fusion/container/vector/detail/cpp03/value_at_impl.hpp b/boost/fusion/container/vector/detail/cpp03/value_at_impl.hpp
new file mode 100644
index 0000000000..44feb6002c
--- /dev/null
+++ b/boost/fusion/container/vector/detail/cpp03/value_at_impl.hpp
@@ -0,0 +1,34 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_VALUE_AT_IMPL_05052005_0232)
+#define FUSION_VALUE_AT_IMPL_05052005_0232
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/mpl/at.hpp>
+
+namespace boost { namespace fusion
+{
+ struct vector_tag;
+
+ namespace extension
+ {
+ template <typename Tag>
+ struct value_at_impl;
+
+ template <>
+ struct value_at_impl<vector_tag>
+ {
+ template <typename Sequence, typename N>
+ struct apply
+ {
+ typedef typename mpl::at<typename Sequence::types, N>::type type;
+ };
+ };
+ }
+}}
+
+#endif
diff --git a/boost/fusion/container/vector/detail/cpp03/vector.hpp b/boost/fusion/container/vector/detail/cpp03/vector.hpp
new file mode 100644
index 0000000000..5dcd688650
--- /dev/null
+++ b/boost/fusion/container/vector/detail/cpp03/vector.hpp
@@ -0,0 +1,247 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_VECTOR_07072005_1244)
+#define FUSION_VECTOR_07072005_1244
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/support/is_sequence.hpp>
+#include <boost/fusion/container/vector/vector_fwd.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/vector_n_chooser.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/core/enable_if.hpp>
+
+#define FUSION_HASH #
+
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1600)
+
+#define BOOST_FUSION_VECTOR_COPY_INIT() \
+ ctor_helper(rhs, is_base_of<vector, Sequence>()) \
+
+#define BOOST_FUSION_VECTOR_CTOR_HELPER() \
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
+ static vector_n const& \
+ ctor_helper(vector const& rhs, mpl::true_) \
+ { \
+ return rhs.vec; \
+ } \
+ \
+ template <typename T> \
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
+ static T const& \
+ ctor_helper(T const& rhs, mpl::false_) \
+ { \
+ return rhs; \
+ }
+
+#else
+
+#define BOOST_FUSION_VECTOR_COPY_INIT() \
+ rhs \
+
+#define BOOST_FUSION_VECTOR_CTOR_HELPER()
+
+#endif
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/vvector" FUSION_MAX_VECTOR_SIZE_STR ".hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct void_;
+ struct fusion_sequence_tag;
+
+ template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, typename T)>
+ struct vector
+ : sequence_base<vector<BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, T)> >
+ {
+ private:
+
+ typedef typename detail::vector_n_chooser<
+ BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, T)>::type
+ vector_n;
+
+ template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, typename U)>
+ friend struct vector;
+
+ public:
+
+ typedef typename vector_n::types types;
+ typedef typename vector_n::fusion_tag fusion_tag;
+ typedef typename vector_n::tag tag;
+ typedef typename vector_n::size size;
+ typedef typename vector_n::category category;
+ typedef typename vector_n::is_view is_view;
+
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ vector()
+ : vec() {}
+
+ template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, typename U)>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ vector(vector<BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, U)> const& rhs)
+ : vec(rhs.vec) {}
+
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ vector(vector const& rhs)
+ : vec(rhs.vec) {}
+
+ template <typename Sequence>
+ BOOST_FUSION_GPU_ENABLED
+ vector(Sequence const& rhs,
+ typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
+ : vec(BOOST_FUSION_VECTOR_COPY_INIT()) {}
+
+ // Expand a couple of forwarding constructors for arguments
+ // of type (T0), (T0, T1), (T0, T1, T2) etc. Example:
+ //
+ // vector(
+ // typename detail::call_param<T0>::type arg0
+ // , typename detail::call_param<T1>::type arg1)
+ // : vec(arg0, arg1) {}
+ #include <boost/fusion/container/vector/detail/cpp03/vector_forward_ctor.hpp>
+
+ template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, typename U)>
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ vector&
+ operator=(vector<BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, U)> const& rhs)
+ {
+ vec = rhs.vec;
+ return *this;
+ }
+
+ template <typename T>
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ vector&
+ operator=(T const& rhs)
+ {
+ vec = rhs;
+ return *this;
+ }
+
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ vector&
+ operator=(vector const& rhs)
+ {
+ vec = rhs.vec;
+ return *this;
+ }
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+FUSION_HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#endif
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \
+ (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ vector(vector&& rhs)
+ : vec(std::forward<vector_n>(rhs.vec)) {}
+
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ vector&
+ operator=(vector&& rhs)
+ {
+ vec = std::forward<vector_n>(rhs.vec);
+ return *this;
+ }
+
+ template <typename T>
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ vector&
+ operator=(T&& rhs)
+ {
+ vec = BOOST_FUSION_FWD_ELEM(T, rhs);
+ return *this;
+ }
+#endif
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+FUSION_HASH endif
+#endif
+
+ template <int N>
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ typename add_reference<
+ typename mpl::at_c<types, N>::type
+ >::type
+ at_impl(mpl::int_<N> index)
+ {
+ return vec.at_impl(index);
+ }
+
+ template <int N>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ typename add_reference<
+ typename add_const<
+ typename mpl::at_c<types, N>::type
+ >::type
+ >::type
+ at_impl(mpl::int_<N> index) const
+ {
+ return vec.at_impl(index);
+ }
+
+ template <typename I>
+ BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ typename add_reference<
+ typename mpl::at<types, I>::type
+ >::type
+ at_impl(I /*index*/)
+ {
+ return vec.at_impl(mpl::int_<I::value>());
+ }
+
+ template<typename I>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ typename add_reference<
+ typename add_const<
+ typename mpl::at<types, I>::type
+ >::type
+ >::type
+ at_impl(I /*index*/) const
+ {
+ return vec.at_impl(mpl::int_<I::value>());
+ }
+
+ private:
+
+ BOOST_FUSION_VECTOR_CTOR_HELPER()
+ vector_n vec;
+ };
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#undef FUSION_HASH
+#endif
diff --git a/boost/fusion/container/vector/detail/cpp03/vector10.hpp b/boost/fusion/container/vector/detail/cpp03/vector10.hpp
new file mode 100644
index 0000000000..58a31ddec3
--- /dev/null
+++ b/boost/fusion/container/vector/detail/cpp03/vector10.hpp
@@ -0,0 +1,105 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_VECTOR10_05042005_0257)
+#define FUSION_VECTOR10_05042005_0257
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/vector10_fwd.hpp>
+#include <boost/fusion/support/sequence_base.hpp>
+#include <boost/fusion/support/is_sequence.hpp>
+#include <boost/fusion/support/detail/access.hpp>
+#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/fusion/container/vector/detail/at_impl.hpp>
+#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
+#include <boost/fusion/container/vector/detail/begin_impl.hpp>
+#include <boost/fusion/container/vector/detail/end_impl.hpp>
+
+#include <boost/mpl/void.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/vector/vector10.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/preprocessor/dec.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_shifted.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
+namespace boost { namespace fusion
+{
+ struct vector_tag;
+ struct fusion_sequence_tag;
+ struct random_access_traversal_tag;
+
+ template <typename Dummy>
+ struct vector0 : sequence_base<vector0<Dummy> >
+ {
+ typedef mpl::vector0<> types;
+ typedef vector_tag fusion_tag;
+ typedef fusion_sequence_tag tag; // this gets picked up by MPL
+ typedef mpl::false_ is_view;
+ typedef random_access_traversal_tag category;
+ typedef mpl::int_<0> size;
+
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ vector0() BOOST_NOEXCEPT {}
+
+ template<typename Sequence>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ vector0(Sequence const& /*seq*/) BOOST_NOEXCEPT
+ {}
+ };
+}}
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector10.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/vector10.hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct vector_tag;
+ struct fusion_sequence_tag;
+ struct random_access_traversal_tag;
+
+#define FUSION_HASH #
+// expand vector1 to vector10
+#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/cpp03/vector_n.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, 10)
+#include BOOST_PP_ITERATE()
+#undef FUSION_HASH
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
diff --git a/boost/fusion/container/vector/vector10_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/vector10_fwd.hpp
index ce5cb1e806..d221faece2 100644
--- a/boost/fusion/container/vector/vector10_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/vector10_fwd.hpp
@@ -21,10 +21,10 @@ namespace boost { namespace fusion
}}
#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/vector/detail/preprocessed/vector10_fwd.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector10_fwd.hpp>
#else
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/vector10_fwd.hpp")
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/vector10_fwd.hpp")
#endif
/*=============================================================================
@@ -43,7 +43,7 @@ namespace boost { namespace fusion
namespace boost { namespace fusion
{
// expand vector1 to vector10
- #define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/vector10_fwd.hpp>
+ #define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/cpp03/vector10_fwd.hpp>
#define BOOST_PP_ITERATION_LIMITS (1, 10)
#include BOOST_PP_ITERATE()
}}
diff --git a/boost/fusion/container/vector/detail/cpp03/vector20.hpp b/boost/fusion/container/vector/detail/cpp03/vector20.hpp
new file mode 100644
index 0000000000..89f644c5a4
--- /dev/null
+++ b/boost/fusion/container/vector/detail/cpp03/vector20.hpp
@@ -0,0 +1,81 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_VECTOR20_05052005_0205)
+#define FUSION_VECTOR20_05052005_0205
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/vector20_fwd.hpp>
+#include <boost/fusion/support/sequence_base.hpp>
+#include <boost/fusion/support/is_sequence.hpp>
+#include <boost/fusion/support/detail/access.hpp>
+#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/fusion/container/vector/detail/at_impl.hpp>
+#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
+#include <boost/fusion/container/vector/detail/begin_impl.hpp>
+#include <boost/fusion/container/vector/detail/end_impl.hpp>
+
+#include <boost/mpl/void.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/vector/vector20.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/preprocessor/dec.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_shifted.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector20.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/vector20.hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct vector_tag;
+ struct fusion_sequence_tag;
+ struct random_access_traversal_tag;
+
+#define FUSION_HASH #
+// expand vector11 to vector20
+#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/cpp03/vector_n.hpp>
+#define BOOST_PP_ITERATION_LIMITS (11, 20)
+#include BOOST_PP_ITERATE()
+#undef FUSION_HASH
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+
diff --git a/boost/fusion/container/vector/vector20_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/vector20_fwd.hpp
index bf1b39b454..e69b59f4a6 100644
--- a/boost/fusion/container/vector/vector20_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/vector20_fwd.hpp
@@ -15,10 +15,10 @@
#include <boost/preprocessor/repetition/enum_params.hpp>
#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/vector/detail/preprocessed/vector20_fwd.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector20_fwd.hpp>
#else
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/vector20_fwd.hpp")
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/vector20_fwd.hpp")
#endif
/*=============================================================================
@@ -38,7 +38,7 @@
namespace boost { namespace fusion
{
// expand vector11 to vector20
- #define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/vector20_fwd.hpp>
+ #define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/cpp03/vector20_fwd.hpp>
#define BOOST_PP_ITERATION_LIMITS (11, 20)
#include BOOST_PP_ITERATE()
}}
diff --git a/boost/fusion/container/vector/detail/cpp03/vector30.hpp b/boost/fusion/container/vector/detail/cpp03/vector30.hpp
new file mode 100644
index 0000000000..ad838c9ac6
--- /dev/null
+++ b/boost/fusion/container/vector/detail/cpp03/vector30.hpp
@@ -0,0 +1,80 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_VECTOR30_05052005_0206)
+#define FUSION_VECTOR30_05052005_0206
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/vector30_fwd.hpp>
+#include <boost/fusion/support/sequence_base.hpp>
+#include <boost/fusion/support/is_sequence.hpp>
+#include <boost/fusion/support/detail/access.hpp>
+#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/fusion/container/vector/detail/at_impl.hpp>
+#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
+#include <boost/fusion/container/vector/detail/begin_impl.hpp>
+#include <boost/fusion/container/vector/detail/end_impl.hpp>
+
+#include <boost/mpl/void.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/vector/vector30.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/preprocessor/dec.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_shifted.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector30.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/vector30.hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct vector_tag;
+ struct fusion_sequence_tag;
+ struct random_access_traversal_tag;
+
+#define FUSION_HASH #
+// expand vector21 to vector30
+#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/cpp03/vector_n.hpp>
+#define BOOST_PP_ITERATION_LIMITS (21, 30)
+#include BOOST_PP_ITERATE()
+#undef FUSION_HASH
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+
diff --git a/boost/fusion/container/vector/vector30_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/vector30_fwd.hpp
index 23b38569e5..e799b09657 100644
--- a/boost/fusion/container/vector/vector30_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/vector30_fwd.hpp
@@ -15,10 +15,10 @@
#include <boost/preprocessor/repetition/enum_params.hpp>
#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/vector/detail/preprocessed/vector30_fwd.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector30_fwd.hpp>
#else
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/vector30_fwd.hpp")
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/vector30_fwd.hpp")
#endif
/*=============================================================================
@@ -38,7 +38,7 @@
namespace boost { namespace fusion
{
// expand vector21 to vector30
- #define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/vector30_fwd.hpp>
+ #define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/cpp03/vector30_fwd.hpp>
#define BOOST_PP_ITERATION_LIMITS (21, 30)
#include BOOST_PP_ITERATE()
}}
diff --git a/boost/fusion/container/vector/detail/cpp03/vector40.hpp b/boost/fusion/container/vector/detail/cpp03/vector40.hpp
new file mode 100644
index 0000000000..10770907eb
--- /dev/null
+++ b/boost/fusion/container/vector/detail/cpp03/vector40.hpp
@@ -0,0 +1,81 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_VECTOR40_05052005_0208)
+#define FUSION_VECTOR40_05052005_0208
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/vector40_fwd.hpp>
+#include <boost/fusion/support/sequence_base.hpp>
+#include <boost/fusion/support/is_sequence.hpp>
+#include <boost/fusion/support/detail/access.hpp>
+#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/fusion/container/vector/detail/at_impl.hpp>
+#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
+#include <boost/fusion/container/vector/detail/begin_impl.hpp>
+#include <boost/fusion/container/vector/detail/end_impl.hpp>
+
+#include <boost/mpl/void.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/vector/vector40.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/preprocessor/dec.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_shifted.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector40.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/vector40.hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct vector_tag;
+ struct fusion_sequence_tag;
+ struct random_access_traversal_tag;
+
+#define FUSION_HASH #
+// expand vector31 to vector40
+#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/cpp03/vector_n.hpp>
+#define BOOST_PP_ITERATION_LIMITS (31, 40)
+#include BOOST_PP_ITERATE()
+#undef FUSION_HASH
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+
diff --git a/boost/fusion/container/vector/vector40_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/vector40_fwd.hpp
index fc3d29d195..790dd76135 100644
--- a/boost/fusion/container/vector/vector40_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/vector40_fwd.hpp
@@ -15,10 +15,10 @@
#include <boost/preprocessor/repetition/enum_params.hpp>
#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/vector/detail/preprocessed/vector40_fwd.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector40_fwd.hpp>
#else
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/vector40_fwd.hpp")
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/vector40_fwd.hpp")
#endif
/*=============================================================================
@@ -38,7 +38,7 @@
namespace boost { namespace fusion
{
// expand vector31 to vector40
- #define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/vector40_fwd.hpp>
+ #define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/cpp03/vector40_fwd.hpp>
#define BOOST_PP_ITERATION_LIMITS (31, 40)
#include BOOST_PP_ITERATE()
}}
diff --git a/boost/fusion/container/vector/detail/cpp03/vector50.hpp b/boost/fusion/container/vector/detail/cpp03/vector50.hpp
new file mode 100644
index 0000000000..6c0b48bbc4
--- /dev/null
+++ b/boost/fusion/container/vector/detail/cpp03/vector50.hpp
@@ -0,0 +1,80 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_VECTOR50_05052005_0207)
+#define FUSION_VECTOR50_05052005_0207
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/vector50_fwd.hpp>
+#include <boost/fusion/support/sequence_base.hpp>
+#include <boost/fusion/support/is_sequence.hpp>
+#include <boost/fusion/support/detail/access.hpp>
+#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/fusion/container/vector/detail/at_impl.hpp>
+#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
+#include <boost/fusion/container/vector/detail/begin_impl.hpp>
+#include <boost/fusion/container/vector/detail/end_impl.hpp>
+
+#include <boost/mpl/void.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/vector/vector50.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/preprocessor/dec.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_shifted.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector50.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/vector50.hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct vector_tag;
+ struct fusion_sequence_tag;
+ struct random_access_traversal_tag;
+
+#define FUSION_HASH #
+// expand vector41 to vector50
+#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/cpp03/vector_n.hpp>
+#define BOOST_PP_ITERATION_LIMITS (41, 50)
+#include BOOST_PP_ITERATE()
+#undef FUSION_HASH
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+
diff --git a/boost/fusion/container/vector/vector50_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/vector50_fwd.hpp
index 52083ad47c..4ec5e2812c 100644
--- a/boost/fusion/container/vector/vector50_fwd.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/vector50_fwd.hpp
@@ -15,10 +15,10 @@
#include <boost/preprocessor/repetition/enum_params.hpp>
#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/vector/detail/preprocessed/vector50_fwd.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector50_fwd.hpp>
#else
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/vector50_fwd.hpp")
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/vector50_fwd.hpp")
#endif
/*=============================================================================
@@ -38,7 +38,7 @@
namespace boost { namespace fusion
{
// expand vector41 to vector50
- #define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/vector50_fwd.hpp>
+ #define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/cpp03/vector50_fwd.hpp>
#define BOOST_PP_ITERATION_LIMITS (41, 50)
#include BOOST_PP_ITERATE()
}}
diff --git a/boost/fusion/container/vector/detail/vector_forward_ctor.hpp b/boost/fusion/container/vector/detail/cpp03/vector_forward_ctor.hpp
index 8ec636074e..682f0ce367 100644
--- a/boost/fusion/container/vector/detail/vector_forward_ctor.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/vector_forward_ctor.hpp
@@ -11,7 +11,7 @@
#define FUSION_FORWARD_CTOR_FORWARD(z, n, _) BOOST_FUSION_FWD_ELEM(U##n, _##n)
#define BOOST_PP_FILENAME_1 \
- <boost/fusion/container/vector/detail/vector_forward_ctor.hpp>
+ <boost/fusion/container/vector/detail/cpp03/vector_forward_ctor.hpp>
#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
#include BOOST_PP_ITERATE()
diff --git a/boost/fusion/container/vector/detail/cpp03/vector_fwd.hpp b/boost/fusion/container/vector/detail/cpp03/vector_fwd.hpp
new file mode 100644
index 0000000000..f894b1a699
--- /dev/null
+++ b/boost/fusion/container/vector/detail/cpp03/vector_fwd.hpp
@@ -0,0 +1,66 @@
+/*=============================================================================
+ Copyright (c) 1999-2003 Jaakko Jarvi
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_VECTOR_FORWARD_07072005_0125)
+#define FUSION_VECTOR_FORWARD_07072005_0125
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/limits.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+
+#include <boost/fusion/container/vector/detail/cpp03/vector10.hpp>
+#if (FUSION_MAX_VECTOR_SIZE > 10)
+#include <boost/fusion/container/vector/detail/cpp03/vector20.hpp>
+#endif
+#if (FUSION_MAX_VECTOR_SIZE > 20)
+#include <boost/fusion/container/vector/detail/cpp03/vector30.hpp>
+#endif
+#if (FUSION_MAX_VECTOR_SIZE > 30)
+#include <boost/fusion/container/vector/detail/cpp03/vector40.hpp>
+#endif
+#if (FUSION_MAX_VECTOR_SIZE > 40)
+#include <boost/fusion/container/vector/detail/cpp03/vector50.hpp>
+#endif
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector_fwd.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/vvector" FUSION_MAX_VECTOR_SIZE_STR "_fwd.hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct void_;
+
+ template <
+ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ FUSION_MAX_VECTOR_SIZE, typename T, void_)
+ >
+ struct vector;
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
diff --git a/boost/fusion/container/vector/detail/vector_n.hpp b/boost/fusion/container/vector/detail/cpp03/vector_n.hpp
index 932ce36c7d..932ce36c7d 100644
--- a/boost/fusion/container/vector/detail/vector_n.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/vector_n.hpp
diff --git a/boost/fusion/container/vector/detail/vector_n_chooser.hpp b/boost/fusion/container/vector/detail/cpp03/vector_n_chooser.hpp
index b0e69afc79..002889ceb5 100644
--- a/boost/fusion/container/vector/detail/vector_n_chooser.hpp
+++ b/boost/fusion/container/vector/detail/cpp03/vector_n_chooser.hpp
@@ -8,21 +8,21 @@
#if !defined(FUSION_VECTOR_N_CHOOSER_07072005_1248)
#define FUSION_VECTOR_N_CHOOSER_07072005_1248
-#include <boost/fusion/container/vector/limits.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/limits.hpp>
// include vector0..N where N is FUSION_MAX_VECTOR_SIZE
-#include <boost/fusion/container/vector/vector10.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/vector10.hpp>
#if (FUSION_MAX_VECTOR_SIZE > 10)
-#include <boost/fusion/container/vector/vector20.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/vector20.hpp>
#endif
#if (FUSION_MAX_VECTOR_SIZE > 20)
-#include <boost/fusion/container/vector/vector30.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/vector30.hpp>
#endif
#if (FUSION_MAX_VECTOR_SIZE > 30)
-#include <boost/fusion/container/vector/vector40.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/vector40.hpp>
#endif
#if (FUSION_MAX_VECTOR_SIZE > 40)
-#include <boost/fusion/container/vector/vector50.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/vector50.hpp>
#endif
#include <boost/preprocessor/cat.hpp>
@@ -38,7 +38,7 @@ namespace boost { namespace fusion
}}
#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/vector/detail/preprocessed/vector_chooser.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/preprocessed/vector_chooser.hpp>
#else
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
#pragma wave option(preserve: 2, line: 0, output: "preprocessed/vector_chooser" FUSION_MAX_VECTOR_SIZE_STR ".hpp")
@@ -72,7 +72,7 @@ namespace boost { namespace fusion { namespace detail
};
#define BOOST_PP_FILENAME_1 \
- <boost/fusion/container/vector/detail/vector_n_chooser.hpp>
+ <boost/fusion/container/vector/detail/cpp03/vector_n_chooser.hpp>
#define BOOST_PP_ITERATION_LIMITS (1, BOOST_PP_DEC(FUSION_MAX_VECTOR_SIZE))
#include BOOST_PP_ITERATE()
diff --git a/boost/fusion/container/vector/detail/value_at_impl.hpp b/boost/fusion/container/vector/detail/value_at_impl.hpp
index 06402b43ee..f71ca8486d 100644
--- a/boost/fusion/container/vector/detail/value_at_impl.hpp
+++ b/boost/fusion/container/vector/detail/value_at_impl.hpp
@@ -1,34 +1,19 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
- Distributed under the Boost Software License, Version 1.0. (See accompanying
+ Distributed under the 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(FUSION_VALUE_AT_IMPL_05052005_0232)
-#define FUSION_VALUE_AT_IMPL_05052005_0232
+#ifndef FUSION_VALUE_AT_IMPL_16122014_1641
+#define FUSION_VALUE_AT_IMPL_16122014_1641
+#include <boost/config.hpp>
#include <boost/fusion/support/config.hpp>
-#include <boost/mpl/at.hpp>
-namespace boost { namespace fusion
-{
- struct vector_tag;
-
- namespace extension
- {
- template <typename Tag>
- struct value_at_impl;
-
- template <>
- struct value_at_impl<vector_tag>
- {
- template <typename Sequence, typename N>
- struct apply
- {
- typedef typename mpl::at<typename Sequence::types, N>::type type;
- };
- };
- }
-}}
+///////////////////////////////////////////////////////////////////////////////
+// Without variadics, we will use the PP version
+///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/container/vector/detail/cpp03/value_at_impl.hpp>
#endif
+
diff --git a/boost/fusion/container/vector/vector.hpp b/boost/fusion/container/vector/vector.hpp
index c1cea9159e..2b9f0ce5ca 100644
--- a/boost/fusion/container/vector/vector.hpp
+++ b/boost/fusion/container/vector/vector.hpp
@@ -1,257 +1,20 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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(FUSION_VECTOR_07072005_1244)
-#define FUSION_VECTOR_07072005_1244
+#ifndef FUSION_VECTOR_11052014_1625
+#define FUSION_VECTOR_11052014_1625
-#include <boost/preprocessor/iterate.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/config.hpp>
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/support/is_sequence.hpp>
#include <boost/fusion/container/vector/vector_fwd.hpp>
-#include <boost/fusion/container/vector/detail/vector_n_chooser.hpp>
-#include <boost/fusion/sequence/intrinsic/begin.hpp>
-#include <boost/mpl/at.hpp>
-#include <boost/mpl/bool.hpp>
-#include <boost/type_traits/add_reference.hpp>
-#include <boost/type_traits/add_const.hpp>
-#include <boost/type_traits/is_base_of.hpp>
-#include <boost/detail/workaround.hpp>
-#include <boost/core/enable_if.hpp>
-#define FUSION_HASH #
-
-#if BOOST_WORKAROUND(BOOST_MSVC, <= 1600)
-
-#define BOOST_FUSION_VECTOR_COPY_INIT() \
- ctor_helper(rhs, is_base_of<vector, Sequence>()) \
-
-#define BOOST_FUSION_VECTOR_CTOR_HELPER() \
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
- static vector_n const& \
- ctor_helper(vector const& rhs, mpl::true_) \
- { \
- return rhs.vec; \
- } \
- \
- template <typename T> \
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
- static T const& \
- ctor_helper(T const& rhs, mpl::false_) \
- { \
- return rhs; \
- }
-
-#else
-
-#define BOOST_FUSION_VECTOR_COPY_INIT() \
- rhs \
-
-#define BOOST_FUSION_VECTOR_CTOR_HELPER()
+///////////////////////////////////////////////////////////////////////////////
+// Without variadics, we will use the PP version
+///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/container/vector/detail/cpp03/vector.hpp>
#endif
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/vector/detail/preprocessed/vector.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/vvector" FUSION_MAX_VECTOR_SIZE_STR ".hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion
-{
- struct void_;
- struct fusion_sequence_tag;
-
- template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, typename T)>
- struct vector
- : sequence_base<vector<BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, T)> >
- {
- private:
-
- typedef typename detail::vector_n_chooser<
- BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, T)>::type
- vector_n;
-
- template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, typename U)>
- friend struct vector;
-
- public:
-
- typedef typename vector_n::types types;
- typedef typename vector_n::fusion_tag fusion_tag;
- typedef typename vector_n::tag tag;
- typedef typename vector_n::size size;
- typedef typename vector_n::category category;
- typedef typename vector_n::is_view is_view;
-
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- vector()
- : vec() {}
-
- template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, typename U)>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- vector(vector<BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, U)> const& rhs)
- : vec(rhs.vec) {}
-
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- vector(vector const& rhs)
- : vec(rhs.vec) {}
-
- template <typename Sequence>
- // XXX:
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-FUSION_HASH if !defined(BOOST_CLANG)
- BOOST_CONSTEXPR
-FUSION_HASH endif
-#else
-#if !defined(BOOST_CLANG)
- BOOST_CONSTEXPR
-#endif
-#endif
- BOOST_FUSION_GPU_ENABLED
- vector(Sequence const& rhs,
- typename boost::enable_if<traits::is_sequence<Sequence> >::type* = 0)
- : vec(BOOST_FUSION_VECTOR_COPY_INIT()) {}
-
- // Expand a couple of forwarding constructors for arguments
- // of type (T0), (T0, T1), (T0, T1, T2) etc. Example:
- //
- // vector(
- // typename detail::call_param<T0>::type arg0
- // , typename detail::call_param<T1>::type arg1)
- // : vec(arg0, arg1) {}
- #include <boost/fusion/container/vector/detail/vector_forward_ctor.hpp>
-
- template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, typename U)>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- vector&
- operator=(vector<BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, U)> const& rhs)
- {
- vec = rhs.vec;
- return *this;
- }
-
- template <typename T>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- vector&
- operator=(T const& rhs)
- {
- vec = rhs;
- return *this;
- }
-
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- vector&
- operator=(vector const& rhs)
- {
- vec = rhs.vec;
- return *this;
- }
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-FUSION_HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
-#endif
-#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \
- (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- vector(vector&& rhs)
- : vec(std::forward<vector_n>(rhs.vec)) {}
-
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- vector&
- operator=(vector&& rhs)
- {
- vec = std::forward<vector_n>(rhs.vec);
- return *this;
- }
-
- template <typename T>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- vector&
- operator=(T&& rhs)
- {
- vec = BOOST_FUSION_FWD_ELEM(T, rhs);
- return *this;
- }
-#endif
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-FUSION_HASH endif
-#endif
-
- template <int N>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- typename add_reference<
- typename mpl::at_c<types, N>::type
- >::type
- at_impl(mpl::int_<N> index)
- {
- return vec.at_impl(index);
- }
-
- template <int N>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- typename add_reference<
- typename add_const<
- typename mpl::at_c<types, N>::type
- >::type
- >::type
- at_impl(mpl::int_<N> index) const
- {
- return vec.at_impl(index);
- }
-
- template <typename I>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- typename add_reference<
- typename mpl::at<types, I>::type
- >::type
- at_impl(I /*index*/)
- {
- return vec.at_impl(mpl::int_<I::value>());
- }
-
- template<typename I>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- typename add_reference<
- typename add_const<
- typename mpl::at<types, I>::type
- >::type
- >::type
- at_impl(I /*index*/) const
- {
- return vec.at_impl(mpl::int_<I::value>());
- }
-
- private:
-
- BOOST_FUSION_VECTOR_CTOR_HELPER()
- vector_n vec;
- };
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
-#undef FUSION_HASH
-#endif
diff --git a/boost/fusion/container/vector/vector10.hpp b/boost/fusion/container/vector/vector10.hpp
index a5ef47542d..f152bfe161 100644
--- a/boost/fusion/container/vector/vector10.hpp
+++ b/boost/fusion/container/vector/vector10.hpp
@@ -1,105 +1,19 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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(FUSION_VECTOR10_05042005_0257)
-#define FUSION_VECTOR10_05042005_0257
+#ifndef FUSION_VECTOR10_11052014_2316
+#define FUSION_VECTOR10_11052014_2316
+#include <boost/config.hpp>
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/container/vector/vector10_fwd.hpp>
-#include <boost/fusion/support/sequence_base.hpp>
-#include <boost/fusion/support/is_sequence.hpp>
-#include <boost/fusion/support/detail/access.hpp>
-#include <boost/fusion/iterator/next.hpp>
-#include <boost/fusion/iterator/deref.hpp>
-#include <boost/fusion/sequence/intrinsic/begin.hpp>
-#include <boost/fusion/container/vector/detail/at_impl.hpp>
-#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
-#include <boost/fusion/container/vector/detail/begin_impl.hpp>
-#include <boost/fusion/container/vector/detail/end_impl.hpp>
-#include <boost/mpl/void.hpp>
-#include <boost/mpl/int.hpp>
-#include <boost/mpl/bool.hpp>
-#include <boost/mpl/at.hpp>
-#include <boost/mpl/vector/vector10.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-#include <boost/utility/enable_if.hpp>
+///////////////////////////////////////////////////////////////////////////////
+// Without variadics, we will use the PP version
+///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/container/vector/detail/cpp03/vector10.hpp>
-#include <boost/preprocessor/dec.hpp>
-#include <boost/preprocessor/iteration/iterate.hpp>
-#include <boost/preprocessor/repetition/enum.hpp>
-#include <boost/preprocessor/repetition/enum_shifted.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/repeat_from_to.hpp>
-
-namespace boost { namespace fusion
-{
- struct vector_tag;
- struct fusion_sequence_tag;
- struct random_access_traversal_tag;
-
- template <typename Dummy>
- struct vector0 : sequence_base<vector0<Dummy> >
- {
- typedef mpl::vector0<> types;
- typedef vector_tag fusion_tag;
- typedef fusion_sequence_tag tag; // this gets picked up by MPL
- typedef mpl::false_ is_view;
- typedef random_access_traversal_tag category;
- typedef mpl::int_<0> size;
-
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- vector0() BOOST_NOEXCEPT {}
-
- template<typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- vector0(Sequence const& /*seq*/) BOOST_NOEXCEPT
- {}
- };
-}}
-
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/vector/detail/preprocessed/vector10.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/vector10.hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion
-{
- struct vector_tag;
- struct fusion_sequence_tag;
- struct random_access_traversal_tag;
-
-#define FUSION_HASH #
-// expand vector1 to vector10
-#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/vector_n.hpp>
-#define BOOST_PP_ITERATION_LIMITS (1, 10)
-#include BOOST_PP_ITERATE()
-#undef FUSION_HASH
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
#endif
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
-#endif
diff --git a/boost/fusion/container/vector/vector20.hpp b/boost/fusion/container/vector/vector20.hpp
index 61978dcb48..c5be355df6 100644
--- a/boost/fusion/container/vector/vector20.hpp
+++ b/boost/fusion/container/vector/vector20.hpp
@@ -1,81 +1,19 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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(FUSION_VECTOR20_05052005_0205)
-#define FUSION_VECTOR20_05052005_0205
+#ifndef FUSION_VECTOR20_11052014_2316
+#define FUSION_VECTOR20_11052014_2316
+#include <boost/config.hpp>
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/container/vector/vector20_fwd.hpp>
-#include <boost/fusion/support/sequence_base.hpp>
-#include <boost/fusion/support/is_sequence.hpp>
-#include <boost/fusion/support/detail/access.hpp>
-#include <boost/fusion/iterator/next.hpp>
-#include <boost/fusion/iterator/deref.hpp>
-#include <boost/fusion/sequence/intrinsic/begin.hpp>
-#include <boost/fusion/container/vector/detail/at_impl.hpp>
-#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
-#include <boost/fusion/container/vector/detail/begin_impl.hpp>
-#include <boost/fusion/container/vector/detail/end_impl.hpp>
-#include <boost/mpl/void.hpp>
-#include <boost/mpl/int.hpp>
-#include <boost/mpl/at.hpp>
-#include <boost/mpl/bool.hpp>
-#include <boost/mpl/vector/vector20.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-#include <boost/utility/enable_if.hpp>
-
-#include <boost/preprocessor/dec.hpp>
-#include <boost/preprocessor/iteration/iterate.hpp>
-#include <boost/preprocessor/repetition/enum.hpp>
-#include <boost/preprocessor/repetition/enum_shifted.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/repeat_from_to.hpp>
-
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/vector/detail/preprocessed/vector20.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/vector20.hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion
-{
- struct vector_tag;
- struct fusion_sequence_tag;
- struct random_access_traversal_tag;
-
-#define FUSION_HASH #
-// expand vector11 to vector20
-#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/vector_n.hpp>
-#define BOOST_PP_ITERATION_LIMITS (11, 20)
-#include BOOST_PP_ITERATE()
-#undef FUSION_HASH
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+///////////////////////////////////////////////////////////////////////////////
+// Without variadics, we will use the PP version
+///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/container/vector/detail/cpp03/vector20.hpp>
#endif
diff --git a/boost/fusion/container/vector/vector30.hpp b/boost/fusion/container/vector/vector30.hpp
index f034abd5e5..1a528cb578 100644
--- a/boost/fusion/container/vector/vector30.hpp
+++ b/boost/fusion/container/vector/vector30.hpp
@@ -1,80 +1,19 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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(FUSION_VECTOR30_05052005_0206)
-#define FUSION_VECTOR30_05052005_0206
+#ifndef FUSION_VECTOR30_11052014_2316
+#define FUSION_VECTOR30_11052014_2316
+#include <boost/config.hpp>
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/container/vector/vector30_fwd.hpp>
-#include <boost/fusion/support/sequence_base.hpp>
-#include <boost/fusion/support/is_sequence.hpp>
-#include <boost/fusion/support/detail/access.hpp>
-#include <boost/fusion/iterator/next.hpp>
-#include <boost/fusion/iterator/deref.hpp>
-#include <boost/fusion/sequence/intrinsic/begin.hpp>
-#include <boost/fusion/container/vector/detail/at_impl.hpp>
-#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
-#include <boost/fusion/container/vector/detail/begin_impl.hpp>
-#include <boost/fusion/container/vector/detail/end_impl.hpp>
-#include <boost/mpl/void.hpp>
-#include <boost/mpl/int.hpp>
-#include <boost/mpl/at.hpp>
-#include <boost/mpl/bool.hpp>
-#include <boost/mpl/vector/vector30.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-#include <boost/utility/enable_if.hpp>
-
-#include <boost/preprocessor/dec.hpp>
-#include <boost/preprocessor/iteration/iterate.hpp>
-#include <boost/preprocessor/repetition/enum.hpp>
-#include <boost/preprocessor/repetition/enum_shifted.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/repeat_from_to.hpp>
-
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/vector/detail/preprocessed/vector30.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/vector30.hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion
-{
- struct vector_tag;
- struct fusion_sequence_tag;
- struct random_access_traversal_tag;
-
-#define FUSION_HASH #
-// expand vector21 to vector30
-#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/vector_n.hpp>
-#define BOOST_PP_ITERATION_LIMITS (21, 30)
-#include BOOST_PP_ITERATE()
-#undef FUSION_HASH
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+///////////////////////////////////////////////////////////////////////////////
+// Without variadics, we will use the PP version
+///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/container/vector/detail/cpp03/vector30.hpp>
#endif
diff --git a/boost/fusion/container/vector/vector40.hpp b/boost/fusion/container/vector/vector40.hpp
index 5a7bb44cf7..5faa7d595b 100644
--- a/boost/fusion/container/vector/vector40.hpp
+++ b/boost/fusion/container/vector/vector40.hpp
@@ -1,81 +1,19 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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(FUSION_VECTOR40_05052005_0208)
-#define FUSION_VECTOR40_05052005_0208
+#ifndef FUSION_VECTOR40_11052014_2316
+#define FUSION_VECTOR40_11052014_2316
+#include <boost/config.hpp>
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/container/vector/vector40_fwd.hpp>
-#include <boost/fusion/support/sequence_base.hpp>
-#include <boost/fusion/support/is_sequence.hpp>
-#include <boost/fusion/support/detail/access.hpp>
-#include <boost/fusion/iterator/next.hpp>
-#include <boost/fusion/iterator/deref.hpp>
-#include <boost/fusion/sequence/intrinsic/begin.hpp>
-#include <boost/fusion/container/vector/detail/at_impl.hpp>
-#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
-#include <boost/fusion/container/vector/detail/begin_impl.hpp>
-#include <boost/fusion/container/vector/detail/end_impl.hpp>
-#include <boost/mpl/void.hpp>
-#include <boost/mpl/int.hpp>
-#include <boost/mpl/at.hpp>
-#include <boost/mpl/bool.hpp>
-#include <boost/mpl/vector/vector40.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-#include <boost/utility/enable_if.hpp>
-
-#include <boost/preprocessor/dec.hpp>
-#include <boost/preprocessor/iteration/iterate.hpp>
-#include <boost/preprocessor/repetition/enum.hpp>
-#include <boost/preprocessor/repetition/enum_shifted.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/repeat_from_to.hpp>
-
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/vector/detail/preprocessed/vector40.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/vector40.hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion
-{
- struct vector_tag;
- struct fusion_sequence_tag;
- struct random_access_traversal_tag;
-
-#define FUSION_HASH #
-// expand vector31 to vector40
-#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/vector_n.hpp>
-#define BOOST_PP_ITERATION_LIMITS (31, 40)
-#include BOOST_PP_ITERATE()
-#undef FUSION_HASH
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+///////////////////////////////////////////////////////////////////////////////
+// Without variadics, we will use the PP version
+///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/container/vector/detail/cpp03/vector40.hpp>
#endif
diff --git a/boost/fusion/container/vector/vector50.hpp b/boost/fusion/container/vector/vector50.hpp
index 2448d51e11..7b7e7a8a18 100644
--- a/boost/fusion/container/vector/vector50.hpp
+++ b/boost/fusion/container/vector/vector50.hpp
@@ -1,80 +1,19 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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(FUSION_VECTOR50_05052005_0207)
-#define FUSION_VECTOR50_05052005_0207
+#ifndef FUSION_VECTOR50_11052014_2316
+#define FUSION_VECTOR50_11052014_2316
+#include <boost/config.hpp>
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/container/vector/vector50_fwd.hpp>
-#include <boost/fusion/support/sequence_base.hpp>
-#include <boost/fusion/support/is_sequence.hpp>
-#include <boost/fusion/support/detail/access.hpp>
-#include <boost/fusion/iterator/next.hpp>
-#include <boost/fusion/iterator/deref.hpp>
-#include <boost/fusion/sequence/intrinsic/begin.hpp>
-#include <boost/fusion/container/vector/detail/at_impl.hpp>
-#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
-#include <boost/fusion/container/vector/detail/begin_impl.hpp>
-#include <boost/fusion/container/vector/detail/end_impl.hpp>
-#include <boost/mpl/void.hpp>
-#include <boost/mpl/int.hpp>
-#include <boost/mpl/at.hpp>
-#include <boost/mpl/bool.hpp>
-#include <boost/mpl/vector/vector50.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-#include <boost/utility/enable_if.hpp>
-
-#include <boost/preprocessor/dec.hpp>
-#include <boost/preprocessor/iteration/iterate.hpp>
-#include <boost/preprocessor/repetition/enum.hpp>
-#include <boost/preprocessor/repetition/enum_shifted.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/repeat_from_to.hpp>
-
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/vector/detail/preprocessed/vector50.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/vector50.hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion
-{
- struct vector_tag;
- struct fusion_sequence_tag;
- struct random_access_traversal_tag;
-
-#define FUSION_HASH #
-// expand vector41 to vector50
-#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/detail/vector_n.hpp>
-#define BOOST_PP_ITERATION_LIMITS (41, 50)
-#include BOOST_PP_ITERATE()
-#undef FUSION_HASH
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+///////////////////////////////////////////////////////////////////////////////
+// Without variadics, we will use the PP version
+///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/container/vector/detail/cpp03/vector50.hpp>
#endif
diff --git a/boost/fusion/container/vector/vector_fwd.hpp b/boost/fusion/container/vector/vector_fwd.hpp
index d157ea81f8..b63099ce9d 100644
--- a/boost/fusion/container/vector/vector_fwd.hpp
+++ b/boost/fusion/container/vector/vector_fwd.hpp
@@ -1,66 +1,19 @@
/*=============================================================================
- Copyright (c) 1999-2003 Jaakko Jarvi
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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(FUSION_VECTOR_FORWARD_07072005_0125)
-#define FUSION_VECTOR_FORWARD_07072005_0125
+#ifndef FUSION_VECTOR_FORWARD_11052014_1626
+#define FUSION_VECTOR_FORWARD_11052014_1626
+#include <boost/config.hpp>
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/container/vector/limits.hpp>
-#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
-#include <boost/fusion/container/vector/vector10.hpp>
-#if (FUSION_MAX_VECTOR_SIZE > 10)
-#include <boost/fusion/container/vector/vector20.hpp>
-#endif
-#if (FUSION_MAX_VECTOR_SIZE > 20)
-#include <boost/fusion/container/vector/vector30.hpp>
-#endif
-#if (FUSION_MAX_VECTOR_SIZE > 30)
-#include <boost/fusion/container/vector/vector40.hpp>
-#endif
-#if (FUSION_MAX_VECTOR_SIZE > 40)
-#include <boost/fusion/container/vector/vector50.hpp>
-#endif
+///////////////////////////////////////////////////////////////////////////////
+// With no variadics, we will use the C++03 version
+///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/container/vector/detail/cpp03/vector_fwd.hpp>
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/container/vector/detail/preprocessed/vector_fwd.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/vvector" FUSION_MAX_VECTOR_SIZE_STR "_fwd.hpp")
#endif
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion
-{
- struct void_;
-
- template <
- BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
- FUSION_MAX_VECTOR_SIZE, typename T, void_)
- >
- struct vector;
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
-#endif
diff --git a/boost/fusion/functional/adapter/limits.hpp b/boost/fusion/functional/adapter/limits.hpp
index 783bc63275..cdcdf8210e 100644
--- a/boost/fusion/functional/adapter/limits.hpp
+++ b/boost/fusion/functional/adapter/limits.hpp
@@ -9,7 +9,7 @@
#if !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_LIMITS_HPP_INCLUDED)
# define BOOST_FUSION_FUNCTIONAL_ADAPTER_LIMITS_HPP_INCLUDED
-# include <boost/fusion/container/vector/limits.hpp>
+# include <boost/fusion/container/vector/detail/cpp03/limits.hpp>
# if !defined(BOOST_FUSION_UNFUSED_MAX_ARITY)
# define BOOST_FUSION_UNFUSED_MAX_ARITY 6
diff --git a/boost/fusion/functional/invocation/detail/that_ptr.hpp b/boost/fusion/functional/invocation/detail/that_ptr.hpp
index 7a1a5c5700..33ee93bf38 100644
--- a/boost/fusion/functional/invocation/detail/that_ptr.hpp
+++ b/boost/fusion/functional/invocation/detail/that_ptr.hpp
@@ -12,7 +12,6 @@
#include <boost/fusion/support/config.hpp>
#include <boost/get_pointer.hpp>
#include <boost/utility/addressof.hpp>
-#include <boost/type_traits/config.hpp>
#include <boost/type_traits/remove_reference.hpp>
namespace boost { namespace fusion { namespace detail
@@ -61,10 +60,16 @@ namespace boost { namespace fusion { namespace detail
template <typename PtrOrSmartPtr> struct non_const_pointee;
- namespace adl_barrier
+#if defined(BOOST_MSVC) || (defined(__BORLANDC__) && !defined(BOOST_DISABLE_WIN32))
+# define BOOST_FUSION_TRAIT_DECL __cdecl
+#else
+# define BOOST_FUSION_TRAIT_DECL /**/
+#endif
+
+namespace adl_barrier
{
using boost::get_pointer;
- void const * BOOST_TT_DECL get_pointer(...); // fallback
+ void const * BOOST_FUSION_TRAIT_DECL get_pointer(...); // fallback
template< typename T> char const_tester(T *);
template< typename T> long const_tester(T const *);
diff --git a/boost/fusion/sequence/comparison/less_equal.hpp b/boost/fusion/sequence/comparison/less_equal.hpp
index 53159926c8..c5dfa8d5c7 100644
--- a/boost/fusion/sequence/comparison/less_equal.hpp
+++ b/boost/fusion/sequence/comparison/less_equal.hpp
@@ -13,7 +13,6 @@
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/sequence/comparison/enable_comparison.hpp>
-#include <boost/fusion/support/is_sequence.hpp>
#if defined(FUSION_DIRECT_OPERATOR_USAGE)
#include <boost/fusion/sequence/comparison/detail/less_equal.hpp>
@@ -38,36 +37,6 @@ namespace boost { namespace fusion
namespace operators
{
-#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1400)
-// Workaround for VC8.0 and VC7.1
- template <typename Seq1, typename Seq2>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- inline bool
- operator<=(sequence_base<Seq1> const& a, sequence_base<Seq2> const& b)
- {
- return less_equal(a.derived(), b.derived());
- }
-
- template <typename Seq1, typename Seq2>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- inline typename disable_if<traits::is_native_fusion_sequence<Seq2>, bool>::type
- operator<=(sequence_base<Seq1> const& a, Seq2 const& b)
- {
- return less_equal(a.derived(), b);
- }
-
- template <typename Seq1, typename Seq2>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- inline typename disable_if<traits::is_native_fusion_sequence<Seq1>, bool>::type
- operator<=(Seq1 const& a, sequence_base<Seq2> const& b)
- {
- return less_equal(a, b.derived());
- }
-
-#else
-// Somehow VC8.0 and VC7.1 does not like this code
-// but barfs somewhere else.
-
template <typename Seq1, typename Seq2>
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
inline typename
@@ -79,7 +48,6 @@ namespace boost { namespace fusion
{
return fusion::less_equal(a, b);
}
-#endif
}
using operators::operator<=;
}}
diff --git a/boost/fusion/sequence/intrinsic/at.hpp b/boost/fusion/sequence/intrinsic/at.hpp
index fdfa72a60a..a103e078a2 100644
--- a/boost/fusion/sequence/intrinsic/at.hpp
+++ b/boost/fusion/sequence/intrinsic/at.hpp
@@ -10,12 +10,13 @@
#include <boost/fusion/support/config.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
#include <boost/mpl/less.hpp>
#include <boost/mpl/empty_base.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/support/tag_of.hpp>
-#include <boost/fusion/support/detail/access.hpp>
+#include <boost/fusion/support/category_of.hpp>
namespace boost { namespace fusion
{
@@ -64,7 +65,10 @@ namespace boost { namespace fusion
template <typename Sequence, typename N, typename Tag>
struct at_impl
: mpl::if_<
- mpl::less<N, typename extension::size_impl<Tag>::template apply<Sequence>::type>
+ mpl::or_<
+ mpl::less<N, typename extension::size_impl<Tag>::template apply<Sequence>::type>
+ , traits::is_unbounded<Sequence>
+ >
, typename extension::at_impl<Tag>::template apply<Sequence, N>
, mpl::empty_base
>::type
diff --git a/boost/fusion/sequence/intrinsic/at_key.hpp b/boost/fusion/sequence/intrinsic/at_key.hpp
index 4693a90553..9454cb56f7 100644
--- a/boost/fusion/sequence/intrinsic/at_key.hpp
+++ b/boost/fusion/sequence/intrinsic/at_key.hpp
@@ -11,10 +11,15 @@
#include <boost/fusion/support/config.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
+#include <boost/fusion/sequence/intrinsic/has_key.hpp>
#include <boost/fusion/algorithm/query/find.hpp>
#include <boost/fusion/iterator/deref_data.hpp>
#include <boost/fusion/support/tag_of.hpp>
+#include <boost/fusion/support/category_of.hpp>
#include <boost/fusion/support/detail/access.hpp>
+#include <boost/mpl/empty_base.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
namespace boost { namespace fusion
{
@@ -64,12 +69,26 @@ namespace boost { namespace fusion
struct at_key_impl<std_pair_tag>;
}
+ namespace detail
+ {
+ template <typename Sequence, typename Key, typename Tag>
+ struct at_key_impl
+ : mpl::if_<
+ mpl::or_<
+ typename extension::has_key_impl<Tag>::template apply<Sequence, Key>
+ , traits::is_unbounded<Sequence>
+ >
+ , typename extension::at_key_impl<Tag>::template apply<Sequence, Key>
+ , mpl::empty_base
+ >::type
+ {};
+ }
+
namespace result_of
{
template <typename Sequence, typename Key>
struct at_key
- : extension::at_key_impl<typename detail::tag_of<Sequence>::type>::
- template apply<Sequence, Key>
+ : detail::at_key_impl<Sequence, Key, typename detail::tag_of<Sequence>::type>
{};
}
diff --git a/boost/fusion/sequence/intrinsic/value_at.hpp b/boost/fusion/sequence/intrinsic/value_at.hpp
index 362669b521..152f0c9455 100644
--- a/boost/fusion/sequence/intrinsic/value_at.hpp
+++ b/boost/fusion/sequence/intrinsic/value_at.hpp
@@ -9,8 +9,13 @@
#include <boost/fusion/support/config.hpp>
#include <boost/mpl/int.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/less.hpp>
+#include <boost/mpl/empty_base.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/support/tag_of.hpp>
+#include <boost/fusion/support/category_of.hpp>
namespace boost { namespace fusion
{
@@ -50,12 +55,26 @@ namespace boost { namespace fusion
struct value_at_impl<std_pair_tag>;
}
+ namespace detail
+ {
+ template <typename Sequence, typename N, typename Tag>
+ struct value_at_impl
+ : mpl::if_<
+ mpl::or_<
+ mpl::less<N, typename extension::size_impl<Tag>::template apply<Sequence>::type>
+ , traits::is_unbounded<Sequence>
+ >
+ , typename extension::value_at_impl<Tag>::template apply<Sequence, N>
+ , mpl::empty_base
+ >::type
+ {};
+ }
+
namespace result_of
{
template <typename Sequence, typename N>
struct value_at
- : extension::value_at_impl<typename detail::tag_of<Sequence>::type>::
- template apply<Sequence, N>
+ : detail::value_at_impl<Sequence, N, typename detail::tag_of<Sequence>::type>
{};
template <typename Sequence, int N>
diff --git a/boost/fusion/sequence/intrinsic/value_at_key.hpp b/boost/fusion/sequence/intrinsic/value_at_key.hpp
index 6d8be3fbcd..76baf1b8ac 100644
--- a/boost/fusion/sequence/intrinsic/value_at_key.hpp
+++ b/boost/fusion/sequence/intrinsic/value_at_key.hpp
@@ -10,10 +10,15 @@
#include <boost/fusion/support/config.hpp>
#include <boost/mpl/int.hpp>
+#include <boost/mpl/empty_base.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
+#include <boost/fusion/sequence/intrinsic/has_key.hpp>
#include <boost/fusion/iterator/value_of_data.hpp>
#include <boost/fusion/algorithm/query/find.hpp>
#include <boost/fusion/support/tag_of.hpp>
+#include <boost/fusion/support/category_of.hpp>
namespace boost { namespace fusion
{
@@ -52,13 +57,27 @@ namespace boost { namespace fusion
template <>
struct value_at_key_impl<std_pair_tag>;
}
-
+
+ namespace detail
+ {
+ template <typename Sequence, typename N, typename Tag>
+ struct value_at_key_impl
+ : mpl::if_<
+ mpl::or_<
+ typename extension::has_key_impl<Tag>::template apply<Sequence, N>
+ , traits::is_unbounded<Sequence>
+ >
+ , typename extension::value_at_key_impl<Tag>::template apply<Sequence, N>
+ , mpl::empty_base
+ >::type
+ {};
+ }
+
namespace result_of
{
template <typename Sequence, typename N>
struct value_at_key
- : extension::value_at_key_impl<typename detail::tag_of<Sequence>::type>::
- template apply<Sequence, N>
+ : detail::value_at_key_impl<Sequence, N, typename detail::tag_of<Sequence>::type>
{};
}
}}
diff --git a/boost/fusion/support/category_of.hpp b/boost/fusion/support/category_of.hpp
index 6bdf6d0291..92b0ea1b60 100644
--- a/boost/fusion/support/category_of.hpp
+++ b/boost/fusion/support/category_of.hpp
@@ -36,6 +36,8 @@ namespace boost { namespace fusion
struct associative_tag {};
+ struct unbounded_tag {};
+
namespace extension
{
template<typename Tag>
@@ -107,6 +109,13 @@ namespace boost { namespace fusion
random_access_traversal_tag
, typename category_of<T>::type>
{};
+
+ template <typename T>
+ struct is_unbounded
+ : is_base_of<
+ unbounded_tag
+ , typename category_of<T>::type>
+ {};
}
}}
diff --git a/boost/fusion/support/config.hpp b/boost/fusion/support/config.hpp
index 10dc29df54..23554531b5 100644
--- a/boost/fusion/support/config.hpp
+++ b/boost/fusion/support/config.hpp
@@ -2,7 +2,7 @@
Copyright (c) 2014 Eric Niebler
Copyright (c) 2014 Kohei Takahashi
- Distributed under the Boost Software License, Version 1.0. (See accompanying
+ Distributed under the 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(FUSION_SUPPORT_CONFIG_01092014_1718)
@@ -10,6 +10,7 @@
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
+#include <utility>
#ifndef BOOST_FUSION_GPU_ENABLED
#define BOOST_FUSION_GPU_ENABLED BOOST_GPU_ENABLED
@@ -78,7 +79,7 @@ namespace boost { namespace fusion { namespace detail
// - MSVC 10.0 implements iterator intrinsics; MSVC 13.0 implements LWG2408.
#if (defined(BOOST_LIBSTDCXX_VERSION) && (BOOST_LIBSTDCXX_VERSION < 40500) && \
defined(BOOST_LIBSTDCXX11)) || \
- (defined(BOOST_MSVC) && (1600 <= BOOST_MSVC || BOOST_MSVC < 1900))
+ (defined(BOOST_MSVC) && (1600 <= BOOST_MSVC && BOOST_MSVC < 1900))
# define BOOST_FUSION_WORKAROUND_FOR_LWG_2408
namespace std
{
@@ -87,4 +88,12 @@ namespace std
}
#endif
+
+// Workaround for older GCC that doesn't accept `this` in constexpr.
+#if BOOST_WORKAROUND(BOOST_GCC, < 40700)
+#define BOOST_FUSION_CONSTEXPR_THIS
+#else
+#define BOOST_FUSION_CONSTEXPR_THIS BOOST_CONSTEXPR
+#endif
+
#endif
diff --git a/boost/fusion/support/detail/index_sequence.hpp b/boost/fusion/support/detail/index_sequence.hpp
new file mode 100644
index 0000000000..1b596e7239
--- /dev/null
+++ b/boost/fusion/support/detail/index_sequence.hpp
@@ -0,0 +1,59 @@
+/*=============================================================================
+ Copyright (c) 2015 Agustin K-ballo Berge
+ Copyright (c) 2015 Kohei Takahashi
+
+ Distributed under the 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_FUSION_SUPPORT_DETAIL_INDEX_SEQUENCE_06232015_1038
+#define BOOST_FUSION_SUPPORT_DETAIL_INDEX_SEQUENCE_06232015_1038
+
+#include <boost/fusion/support/config.hpp>
+#include <cstddef>
+
+namespace boost { namespace fusion { namespace detail
+{
+ template <std::size_t ...Ints>
+ struct index_sequence
+ {
+ typedef std::size_t value_type;
+
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ static std::size_t size() BOOST_NOEXCEPT
+ { return sizeof...(Ints); }
+
+ // non standard extension
+ typedef index_sequence type;
+ };
+
+ template <typename Left, typename Right>
+ struct _make_index_sequence_join;
+
+ template <std::size_t... Left, std::size_t... Right>
+ struct _make_index_sequence_join<
+ index_sequence<Left...>, index_sequence<Right...>
+ > : index_sequence<Left..., (sizeof...(Left) + Right)...>
+ {};
+
+ template <std::size_t N>
+ struct make_index_sequence
+ : _make_index_sequence_join<
+ typename make_index_sequence<N / 2>::type
+ , typename make_index_sequence<N - N / 2>::type
+ >
+ {};
+
+ template <>
+ struct make_index_sequence<1>
+ : index_sequence<0>
+ {};
+
+ template <>
+ struct make_index_sequence<0>
+ : index_sequence<>
+ {};
+}}}
+
+#endif
+
diff --git a/boost/fusion/support/pair.hpp b/boost/fusion/support/pair.hpp
index fd5d57e687..a4cd1ff092 100644
--- a/boost/fusion/support/pair.hpp
+++ b/boost/fusion/support/pair.hpp
@@ -49,7 +49,7 @@ namespace boost { namespace fusion
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename Second2>
- BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_GPU_ENABLED
pair(Second2&& val
, typename boost::disable_if<is_lvalue_reference<Second2> >::type* /* dummy */ = 0
, typename boost::enable_if<is_convertible<Second2, Second> >::type* /*dummy*/ = 0
diff --git a/boost/fusion/support/unused.hpp b/boost/fusion/support/unused.hpp
index 4bbe24e88b..964839ab25 100644
--- a/boost/fusion/support/unused.hpp
+++ b/boost/fusion/support/unused.hpp
@@ -34,7 +34,7 @@ namespace boost { namespace fusion
}
template <typename T>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_CONSTEXPR_THIS BOOST_FUSION_GPU_ENABLED
unused_type const&
operator=(T const&) const BOOST_NOEXCEPT
{
@@ -49,7 +49,7 @@ namespace boost { namespace fusion
return *this;
}
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ BOOST_FUSION_CONSTEXPR_THIS BOOST_FUSION_GPU_ENABLED
unused_type const&
operator=(unused_type const&) const BOOST_NOEXCEPT
{
@@ -64,7 +64,7 @@ namespace boost { namespace fusion
}
};
- BOOST_CONSTEXPR unused_type const unused = unused_type();
+ BOOST_CONSTEXPR_OR_CONST unused_type unused = unused_type();
namespace detail
{
diff --git a/boost/fusion/tuple/detail/make_tuple.hpp b/boost/fusion/tuple/detail/make_tuple.hpp
new file mode 100644
index 0000000000..f87ea5a231
--- /dev/null
+++ b/boost/fusion/tuple/detail/make_tuple.hpp
@@ -0,0 +1,86 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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_PP_IS_ITERATING
+#if !defined(FUSION_MAKE_TUPLE_10032005_0843)
+#define FUSION_MAKE_TUPLE_10032005_0843
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/fusion/tuple/detail/tuple.hpp>
+#include <boost/fusion/support/detail/as_fusion_element.hpp>
+
+namespace boost { namespace fusion
+{
+ BOOST_FUSION_GPU_ENABLED inline tuple<>
+ make_tuple()
+ {
+ return tuple<>();
+ }
+}}
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/tuple/detail/preprocessed/make_tuple.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/make_tuple" FUSION_MAX_VECTOR_SIZE_STR ".hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \
+ typename detail::as_fusion_element<BOOST_PP_CAT(T, n)>::type
+
+#define BOOST_PP_FILENAME_1 <boost/fusion/tuple/detail/make_tuple.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
+#include BOOST_PP_ITERATE()
+
+#undef BOOST_FUSION_AS_FUSION_ELEMENT
+
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+#else // defined(BOOST_PP_IS_ITERATING)
+///////////////////////////////////////////////////////////////////////////////
+//
+// Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define N BOOST_PP_ITERATION()
+
+ template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+ BOOST_FUSION_GPU_ENABLED
+ inline tuple<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>
+ make_tuple(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& arg))
+ {
+ return tuple<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>(
+ BOOST_PP_ENUM_PARAMS(N, arg));
+ }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
diff --git a/boost/fusion/tuple/detail/preprocessed/tuple10.hpp b/boost/fusion/tuple/detail/preprocessed/tuple10.hpp
index 893054caaa..a24a29a12e 100644
--- a/boost/fusion/tuple/detail/preprocessed/tuple10.hpp
+++ b/boost/fusion/tuple/detail/preprocessed/tuple10.hpp
@@ -17,7 +17,7 @@ namespace boost { namespace fusion
BOOST_FUSION_GPU_ENABLED tuple()
: base_type() {}
BOOST_FUSION_GPU_ENABLED tuple(tuple const& rhs)
- : base_type(rhs) {}
+ : base_type(static_cast<base_type const&>(rhs)) {}
template <typename U1, typename U2>
BOOST_FUSION_GPU_ENABLED
tuple(std::pair<U1, U2> const& rhs)
@@ -173,7 +173,7 @@ namespace boost { namespace fusion
BOOST_FUSION_GPU_ENABLED
tuple& operator=(tuple const& rhs)
{
- base_type::operator=(rhs);
+ base_type::operator=(static_cast<base_type const&>(rhs));
return *this;
}
template <typename U1, typename U2>
diff --git a/boost/fusion/tuple/detail/preprocessed/tuple20.hpp b/boost/fusion/tuple/detail/preprocessed/tuple20.hpp
index c526fb7e31..73de49ffb8 100644
--- a/boost/fusion/tuple/detail/preprocessed/tuple20.hpp
+++ b/boost/fusion/tuple/detail/preprocessed/tuple20.hpp
@@ -17,7 +17,7 @@ namespace boost { namespace fusion
BOOST_FUSION_GPU_ENABLED tuple()
: base_type() {}
BOOST_FUSION_GPU_ENABLED tuple(tuple const& rhs)
- : base_type(rhs) {}
+ : base_type(static_cast<base_type const&>(rhs)) {}
template <typename U1, typename U2>
BOOST_FUSION_GPU_ENABLED
tuple(std::pair<U1, U2> const& rhs)
@@ -313,7 +313,7 @@ namespace boost { namespace fusion
BOOST_FUSION_GPU_ENABLED
tuple& operator=(tuple const& rhs)
{
- base_type::operator=(rhs);
+ base_type::operator=(static_cast<base_type const&>(rhs));
return *this;
}
template <typename U1, typename U2>
diff --git a/boost/fusion/tuple/detail/preprocessed/tuple30.hpp b/boost/fusion/tuple/detail/preprocessed/tuple30.hpp
index d99b726d02..9db26a0c9a 100644
--- a/boost/fusion/tuple/detail/preprocessed/tuple30.hpp
+++ b/boost/fusion/tuple/detail/preprocessed/tuple30.hpp
@@ -17,7 +17,7 @@ namespace boost { namespace fusion
BOOST_FUSION_GPU_ENABLED tuple()
: base_type() {}
BOOST_FUSION_GPU_ENABLED tuple(tuple const& rhs)
- : base_type(rhs) {}
+ : base_type(static_cast<base_type const&>(rhs)) {}
template <typename U1, typename U2>
BOOST_FUSION_GPU_ENABLED
tuple(std::pair<U1, U2> const& rhs)
@@ -453,7 +453,7 @@ namespace boost { namespace fusion
BOOST_FUSION_GPU_ENABLED
tuple& operator=(tuple const& rhs)
{
- base_type::operator=(rhs);
+ base_type::operator=(static_cast<base_type const&>(rhs));
return *this;
}
template <typename U1, typename U2>
diff --git a/boost/fusion/tuple/detail/preprocessed/tuple40.hpp b/boost/fusion/tuple/detail/preprocessed/tuple40.hpp
index c8ecbb9690..44e0d2c1d5 100644
--- a/boost/fusion/tuple/detail/preprocessed/tuple40.hpp
+++ b/boost/fusion/tuple/detail/preprocessed/tuple40.hpp
@@ -17,7 +17,7 @@ namespace boost { namespace fusion
BOOST_FUSION_GPU_ENABLED tuple()
: base_type() {}
BOOST_FUSION_GPU_ENABLED tuple(tuple const& rhs)
- : base_type(rhs) {}
+ : base_type(static_cast<base_type const&>(rhs)) {}
template <typename U1, typename U2>
BOOST_FUSION_GPU_ENABLED
tuple(std::pair<U1, U2> const& rhs)
@@ -593,7 +593,7 @@ namespace boost { namespace fusion
BOOST_FUSION_GPU_ENABLED
tuple& operator=(tuple const& rhs)
{
- base_type::operator=(rhs);
+ base_type::operator=(static_cast<base_type const&>(rhs));
return *this;
}
template <typename U1, typename U2>
diff --git a/boost/fusion/tuple/detail/preprocessed/tuple50.hpp b/boost/fusion/tuple/detail/preprocessed/tuple50.hpp
index 94f87e3588..db157b6549 100644
--- a/boost/fusion/tuple/detail/preprocessed/tuple50.hpp
+++ b/boost/fusion/tuple/detail/preprocessed/tuple50.hpp
@@ -17,7 +17,7 @@ namespace boost { namespace fusion
BOOST_FUSION_GPU_ENABLED tuple()
: base_type() {}
BOOST_FUSION_GPU_ENABLED tuple(tuple const& rhs)
- : base_type(rhs) {}
+ : base_type(static_cast<base_type const&>(rhs)) {}
template <typename U1, typename U2>
BOOST_FUSION_GPU_ENABLED
tuple(std::pair<U1, U2> const& rhs)
@@ -733,7 +733,7 @@ namespace boost { namespace fusion
BOOST_FUSION_GPU_ENABLED
tuple& operator=(tuple const& rhs)
{
- base_type::operator=(rhs);
+ base_type::operator=(static_cast<base_type const&>(rhs));
return *this;
}
template <typename U1, typename U2>
diff --git a/boost/fusion/tuple/detail/tuple.hpp b/boost/fusion/tuple/detail/tuple.hpp
new file mode 100644
index 0000000000..45408f0652
--- /dev/null
+++ b/boost/fusion/tuple/detail/tuple.hpp
@@ -0,0 +1,122 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_TUPLE_10032005_0810)
+#define FUSION_TUPLE_10032005_0810
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/tuple/detail/tuple_fwd.hpp>
+#include <boost/fusion/container/vector/vector.hpp>
+#include <boost/fusion/sequence/intrinsic/size.hpp>
+#include <boost/fusion/sequence/intrinsic/value_at.hpp>
+#include <boost/fusion/sequence/intrinsic/at.hpp>
+#include <boost/fusion/sequence/comparison.hpp>
+#include <boost/fusion/sequence/io.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/config/no_tr1/utility.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/tuple/detail/preprocessed/tuple.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/tuple" FUSION_MAX_VECTOR_SIZE_STR ".hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, typename T)>
+ struct tuple : vector<BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, T)>
+ {
+ typedef vector<
+ BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, T)>
+ base_type;
+
+ BOOST_FUSION_GPU_ENABLED tuple()
+ : base_type() {}
+
+ BOOST_FUSION_GPU_ENABLED tuple(tuple const& rhs)
+ : base_type(static_cast<base_type const&>(rhs)) {}
+
+ template <typename U1, typename U2>
+ BOOST_FUSION_GPU_ENABLED
+ tuple(std::pair<U1, U2> const& rhs)
+ : base_type(rhs) {}
+
+ #include <boost/fusion/tuple/detail/tuple_expand.hpp>
+
+ template <typename T>
+ BOOST_FUSION_GPU_ENABLED
+ tuple& operator=(T const& rhs)
+ {
+ base_type::operator=(rhs);
+ return *this;
+ }
+
+ BOOST_FUSION_GPU_ENABLED
+ tuple& operator=(tuple const& rhs)
+ {
+ base_type::operator=(static_cast<base_type const&>(rhs));
+ return *this;
+ }
+
+ template <typename U1, typename U2>
+ BOOST_FUSION_GPU_ENABLED
+ tuple& operator=(std::pair<U1, U2> const& rhs)
+ {
+ base_type::operator=(rhs);
+ return *this;
+ }
+ };
+
+ template <typename Tuple>
+ struct tuple_size : result_of::size<Tuple> {};
+
+ template <int N, typename Tuple>
+ struct tuple_element : result_of::value_at_c<Tuple, N> {};
+
+ template <int N, typename Tuple>
+ BOOST_FUSION_GPU_ENABLED
+ inline typename
+ lazy_disable_if<
+ is_const<Tuple>
+ , result_of::at_c<Tuple, N>
+ >::type
+ get(Tuple& tup)
+ {
+ return at_c<N>(tup);
+ }
+
+ template <int N, typename Tuple>
+ BOOST_FUSION_GPU_ENABLED
+ inline typename result_of::at_c<Tuple const, N>::type
+ get(Tuple const& tup)
+ {
+ return at_c<N>(tup);
+ }
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+
diff --git a/boost/fusion/tuple/detail/tuple_fwd.hpp b/boost/fusion/tuple/detail/tuple_fwd.hpp
new file mode 100644
index 0000000000..ef6bdfe8b6
--- /dev/null
+++ b/boost/fusion/tuple/detail/tuple_fwd.hpp
@@ -0,0 +1,52 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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(FUSION_TUPLE_FORWARD_10032005_0956)
+#define FUSION_TUPLE_FORWARD_10032005_0956
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/limits.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/tuple/detail/preprocessed/tuple_fwd.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/tuple" FUSION_MAX_VECTOR_SIZE_STR "_fwd.hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+ struct void_;
+
+ template <
+ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ FUSION_MAX_VECTOR_SIZE, typename T, void_)
+ >
+ struct tuple;
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+
diff --git a/boost/fusion/tuple/detail/tuple_tie.hpp b/boost/fusion/tuple/detail/tuple_tie.hpp
new file mode 100644
index 0000000000..b650d1cc16
--- /dev/null
+++ b/boost/fusion/tuple/detail/tuple_tie.hpp
@@ -0,0 +1,76 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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_PP_IS_ITERATING
+#if !defined(FUSION_TUPLE_TIE_10032005_0846)
+#define FUSION_TUPLE_TIE_10032005_0846
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/fusion/tuple/detail/tuple.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/tuple/detail/preprocessed/tuple_tie.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/tuple_tie" FUSION_MAX_VECTOR_SIZE_STR ".hpp")
+#endif
+
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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 is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+#define BOOST_FUSION_REF(z, n, data) BOOST_PP_CAT(T, n)&
+
+#define BOOST_PP_FILENAME_1 <boost/fusion/tuple/detail/tuple_tie.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
+#include BOOST_PP_ITERATE()
+
+#undef BOOST_FUSION_REF
+
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+#else // defined(BOOST_PP_IS_ITERATING)
+///////////////////////////////////////////////////////////////////////////////
+//
+// Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define N BOOST_PP_ITERATION()
+
+ template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+ BOOST_FUSION_GPU_ENABLED
+ inline tuple<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)>
+ tie(BOOST_PP_ENUM_BINARY_PARAMS(N, T, & arg))
+ {
+ return tuple<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)>(
+ BOOST_PP_ENUM_PARAMS(N, arg));
+ }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
diff --git a/boost/fusion/tuple/make_tuple.hpp b/boost/fusion/tuple/make_tuple.hpp
index 93034834d9..0d1277366a 100644
--- a/boost/fusion/tuple/make_tuple.hpp
+++ b/boost/fusion/tuple/make_tuple.hpp
@@ -1,86 +1,19 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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_PP_IS_ITERATING
-#if !defined(FUSION_MAKE_TUPLE_10032005_0843)
-#define FUSION_MAKE_TUPLE_10032005_0843
+#ifndef FUSION_MAKE_TUPLE_14122014_0048
+#define FUSION_MAKE_TUPLE_14122014_0048
-#include <boost/preprocessor/iterate.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/fusion/tuple/tuple.hpp>
-#include <boost/fusion/support/detail/as_fusion_element.hpp>
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/tuple/tuple_fwd.hpp>
-namespace boost { namespace fusion
-{
- BOOST_FUSION_GPU_ENABLED inline tuple<>
- make_tuple()
- {
- return tuple<>();
- }
-}}
-
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/tuple/detail/preprocessed/make_tuple.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/make_tuple" FUSION_MAX_VECTOR_SIZE_STR ".hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion
-{
-#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \
- typename detail::as_fusion_element<BOOST_PP_CAT(T, n)>::type
-
-#define BOOST_PP_FILENAME_1 <boost/fusion/tuple/make_tuple.hpp>
-#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
-#include BOOST_PP_ITERATE()
-
-#undef BOOST_FUSION_AS_FUSION_ELEMENT
-
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
-#endif
-#else // defined(BOOST_PP_IS_ITERATING)
///////////////////////////////////////////////////////////////////////////////
-//
-// Preprocessor vertical repetition code
-//
+// With no variadics, we will use the C++03 version
///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/tuple/detail/make_tuple.hpp>
-#define N BOOST_PP_ITERATION()
-
- template <BOOST_PP_ENUM_PARAMS(N, typename T)>
- BOOST_FUSION_GPU_ENABLED
- inline tuple<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>
- make_tuple(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& arg))
- {
- return tuple<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>(
- BOOST_PP_ENUM_PARAMS(N, arg));
- }
-
-#undef N
-#endif // defined(BOOST_PP_IS_ITERATING)
+#endif
diff --git a/boost/fusion/tuple/tuple.hpp b/boost/fusion/tuple/tuple.hpp
index 953f2b6664..674c369132 100644
--- a/boost/fusion/tuple/tuple.hpp
+++ b/boost/fusion/tuple/tuple.hpp
@@ -1,122 +1,19 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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(FUSION_TUPLE_10032005_0810)
-#define FUSION_TUPLE_10032005_0810
+#ifndef FUSION_TUPLE_14122014_0102
+#define FUSION_TUPLE_14122014_0102
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/tuple/tuple_fwd.hpp>
-#include <boost/fusion/container/vector/vector.hpp>
-#include <boost/fusion/sequence/intrinsic/size.hpp>
-#include <boost/fusion/sequence/intrinsic/value_at.hpp>
-#include <boost/fusion/sequence/intrinsic/at.hpp>
-#include <boost/fusion/sequence/comparison.hpp>
-#include <boost/fusion/sequence/io.hpp>
-#include <boost/utility/enable_if.hpp>
-#include <boost/type_traits/is_const.hpp>
-#include <boost/config/no_tr1/utility.hpp>
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/tuple/detail/preprocessed/tuple.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/tuple" FUSION_MAX_VECTOR_SIZE_STR ".hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion
-{
- template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, typename T)>
- struct tuple : vector<BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, T)>
- {
- typedef vector<
- BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, T)>
- base_type;
-
- BOOST_FUSION_GPU_ENABLED tuple()
- : base_type() {}
-
- BOOST_FUSION_GPU_ENABLED tuple(tuple const& rhs)
- : base_type(rhs) {}
-
- template <typename U1, typename U2>
- BOOST_FUSION_GPU_ENABLED
- tuple(std::pair<U1, U2> const& rhs)
- : base_type(rhs) {}
-
- #include <boost/fusion/tuple/detail/tuple_expand.hpp>
-
- template <typename T>
- BOOST_FUSION_GPU_ENABLED
- tuple& operator=(T const& rhs)
- {
- base_type::operator=(rhs);
- return *this;
- }
-
- BOOST_FUSION_GPU_ENABLED
- tuple& operator=(tuple const& rhs)
- {
- base_type::operator=(rhs);
- return *this;
- }
-
- template <typename U1, typename U2>
- BOOST_FUSION_GPU_ENABLED
- tuple& operator=(std::pair<U1, U2> const& rhs)
- {
- base_type::operator=(rhs);
- return *this;
- }
- };
-
- template <typename Tuple>
- struct tuple_size : result_of::size<Tuple> {};
-
- template <int N, typename Tuple>
- struct tuple_element : result_of::value_at_c<Tuple, N> {};
-
- template <int N, typename Tuple>
- BOOST_FUSION_GPU_ENABLED
- inline typename
- lazy_disable_if<
- is_const<Tuple>
- , result_of::at_c<Tuple, N>
- >::type
- get(Tuple& tup)
- {
- return at_c<N>(tup);
- }
-
- template <int N, typename Tuple>
- BOOST_FUSION_GPU_ENABLED
- inline typename result_of::at_c<Tuple const, N>::type
- get(Tuple const& tup)
- {
- return at_c<N>(tup);
- }
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+///////////////////////////////////////////////////////////////////////////////
+// With no variadics, we will use the C++03 version
+///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/tuple/detail/tuple.hpp>
#endif
diff --git a/boost/fusion/tuple/tuple_fwd.hpp b/boost/fusion/tuple/tuple_fwd.hpp
index 68969183d1..0742023403 100644
--- a/boost/fusion/tuple/tuple_fwd.hpp
+++ b/boost/fusion/tuple/tuple_fwd.hpp
@@ -1,52 +1,19 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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(FUSION_TUPLE_FORWARD_10032005_0956)
-#define FUSION_TUPLE_FORWARD_10032005_0956
+#ifndef FUSION_TUPLE_FORWARD_14122014_0051
+#define FUSION_TUPLE_FORWARD_14122014_0051
+#include <boost/config.hpp>
#include <boost/fusion/support/config.hpp>
-#include <boost/fusion/container/vector/limits.hpp>
-#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/tuple/detail/preprocessed/tuple_fwd.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/tuple" FUSION_MAX_VECTOR_SIZE_STR "_fwd.hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion
-{
- struct void_;
-
- template <
- BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
- FUSION_MAX_VECTOR_SIZE, typename T, void_)
- >
- struct tuple;
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+///////////////////////////////////////////////////////////////////////////////
+// With no variadics, we will use the C++03 version
+///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/tuple/detail/tuple_fwd.hpp>
#endif
diff --git a/boost/fusion/tuple/tuple_tie.hpp b/boost/fusion/tuple/tuple_tie.hpp
index 1905028766..9202807048 100644
--- a/boost/fusion/tuple/tuple_tie.hpp
+++ b/boost/fusion/tuple/tuple_tie.hpp
@@ -1,76 +1,19 @@
/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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_PP_IS_ITERATING
-#if !defined(FUSION_TUPLE_TIE_10032005_0846)
-#define FUSION_TUPLE_TIE_10032005_0846
+#ifndef FUSION_TUPLE_TIE_14122014_0115
+#define FUSION_TUPLE_TIE_14122014_0115
-#include <boost/preprocessor/iterate.hpp>
-#include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/fusion/tuple/tuple.hpp>
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/tuple/tuple_fwd.hpp>
-#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
-#include <boost/fusion/tuple/detail/preprocessed/tuple_tie.hpp>
-#else
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 2, line: 0, output: "detail/preprocessed/tuple_tie" FUSION_MAX_VECTOR_SIZE_STR ".hpp")
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
-
- Distributed under the 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 is an auto-generated file. Do not edit!
-==============================================================================*/
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(preserve: 1)
-#endif
-
-namespace boost { namespace fusion
-{
-#define BOOST_FUSION_REF(z, n, data) BOOST_PP_CAT(T, n)&
-
-#define BOOST_PP_FILENAME_1 <boost/fusion/tuple/tuple_tie.hpp>
-#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
-#include BOOST_PP_ITERATE()
-
-#undef BOOST_FUSION_REF
-
-}}
-
-#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
-#pragma wave option(output: null)
-#endif
-
-#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
-
-#endif
-#else // defined(BOOST_PP_IS_ITERATING)
///////////////////////////////////////////////////////////////////////////////
-//
-// Preprocessor vertical repetition code
-//
+// With no variadics, we will use the C++03 version
///////////////////////////////////////////////////////////////////////////////
+# include <boost/fusion/tuple/detail/tuple_tie.hpp>
-#define N BOOST_PP_ITERATION()
-
- template <BOOST_PP_ENUM_PARAMS(N, typename T)>
- BOOST_FUSION_GPU_ENABLED
- inline tuple<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)>
- tie(BOOST_PP_ENUM_BINARY_PARAMS(N, T, & arg))
- {
- return tuple<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)>(
- BOOST_PP_ENUM_PARAMS(N, arg));
- }
-
-#undef N
-#endif // defined(BOOST_PP_IS_ITERATING)
+#endif
diff --git a/boost/fusion/view/nview/detail/cpp03/nview_impl.hpp b/boost/fusion/view/nview/detail/cpp03/nview_impl.hpp
new file mode 100644
index 0000000000..08c6c9d738
--- /dev/null
+++ b/boost/fusion/view/nview/detail/cpp03/nview_impl.hpp
@@ -0,0 +1,78 @@
+/*=============================================================================
+ Copyright (c) 2009 Hartmut Kaiser
+
+ Distributed under the 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_PP_IS_ITERATING
+
+#if !defined(BOOST_FUSION_NVIEW_IMPL_SEP_23_2009_1017PM)
+#define BOOST_FUSION_NVIEW_IMPL_SEP_23_2009_1017PM
+
+#include <climits>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repeat.hpp>
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+
+#define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (1, FUSION_MAX_VECTOR_SIZE, \
+ "boost/fusion/view/nview/detail/cpp03/nview_impl.hpp")) \
+ /**/
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace fusion { namespace result_of
+{
+ template <typename Sequence
+ , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(FUSION_MAX_VECTOR_SIZE, int I, INT_MAX)>
+ struct as_nview
+ {
+ typedef mpl::vector_c<
+ int, BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, I)
+ > index_type;
+ typedef nview<Sequence, index_type> type;
+ };
+}}}
+
+#include BOOST_PP_ITERATE()
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// Preprocessor vertical repetition code
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+#if N < FUSION_MAX_VECTOR_SIZE
+namespace boost { namespace fusion { namespace result_of
+{
+ template <typename Sequence, BOOST_PP_ENUM_PARAMS(N, int I)>
+ struct as_nview<Sequence, BOOST_PP_ENUM_PARAMS(N, I)>
+ {
+ typedef mpl::vector_c<int, BOOST_PP_ENUM_PARAMS(N, I)> index_type;
+ typedef nview<Sequence, index_type> type;
+ };
+}}}
+#endif
+
+namespace boost { namespace fusion
+{
+ template<BOOST_PP_ENUM_PARAMS(N, int I), typename Sequence>
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ inline nview<Sequence, mpl::vector_c<int, BOOST_PP_ENUM_PARAMS(N, I)> >
+ as_nview(Sequence& s)
+ {
+ typedef mpl::vector_c<int, BOOST_PP_ENUM_PARAMS(N, I)> index_type;
+ return nview<Sequence, index_type>(s);
+ }
+
+}}
+
+#undef N
+
+#endif
diff --git a/boost/fusion/view/nview/detail/nview_impl.hpp b/boost/fusion/view/nview/detail/nview_impl.hpp
index e0d9335638..40674e3551 100644
--- a/boost/fusion/view/nview/detail/nview_impl.hpp
+++ b/boost/fusion/view/nview/detail/nview_impl.hpp
@@ -1,78 +1,18 @@
/*=============================================================================
- Copyright (c) 2009 Hartmut Kaiser
+ Copyright (c) 2014 Kohei Takahashi
Distributed under the 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_FUSION_NVIEW_IMPL_17122014_1948
+#define BOOST_FUSION_NVIEW_IMPL_17122014_1948
-#ifndef BOOST_PP_IS_ITERATING
-
-#if !defined(BOOST_FUSION_NVIEW_IMPL_SEP_23_2009_1017PM)
-#define BOOST_FUSION_NVIEW_IMPL_SEP_23_2009_1017PM
-
-#include <climits>
-#include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/repeat.hpp>
-#include <boost/preprocessor/iterate.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
-
-#define BOOST_PP_ITERATION_PARAMS_1 \
- (3, (1, FUSION_MAX_VECTOR_SIZE, \
- "boost/fusion/view/nview/detail/nview_impl.hpp")) \
- /**/
+#include <boost/fusion/support/config.hpp>
///////////////////////////////////////////////////////////////////////////////
-namespace boost { namespace fusion { namespace result_of
-{
- template <typename Sequence
- , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(FUSION_MAX_VECTOR_SIZE, int I, INT_MAX)>
- struct as_nview
- {
- typedef mpl::vector_c<
- int, BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, I)
- > index_type;
- typedef nview<Sequence, index_type> type;
- };
-}}}
-
-#include BOOST_PP_ITERATE()
-
-#endif
-
+// Without variadics, we will use the PP version
///////////////////////////////////////////////////////////////////////////////
-// Preprocessor vertical repetition code
-///////////////////////////////////////////////////////////////////////////////
-#else // defined(BOOST_PP_IS_ITERATING)
-
-#define N BOOST_PP_ITERATION()
+# include <boost/fusion/view/nview/detail/cpp03/nview_impl.hpp>
-#if N < FUSION_MAX_VECTOR_SIZE
-namespace boost { namespace fusion { namespace result_of
-{
- template <typename Sequence, BOOST_PP_ENUM_PARAMS(N, int I)>
- struct as_nview<Sequence, BOOST_PP_ENUM_PARAMS(N, I)>
- {
- typedef mpl::vector_c<int, BOOST_PP_ENUM_PARAMS(N, I)> index_type;
- typedef nview<Sequence, index_type> type;
- };
-}}}
#endif
-namespace boost { namespace fusion
-{
- template<BOOST_PP_ENUM_PARAMS(N, int I), typename Sequence>
- BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
- inline nview<Sequence, mpl::vector_c<int, BOOST_PP_ENUM_PARAMS(N, I)> >
- as_nview(Sequence& s)
- {
- typedef mpl::vector_c<int, BOOST_PP_ENUM_PARAMS(N, I)> index_type;
- return nview<Sequence, index_type>(s);
- }
-
-}}
-
-#undef N
-
-#endif
diff --git a/boost/geometry/algorithms/append.hpp b/boost/geometry/algorithms/append.hpp
index 6ffb5f9587..894f52c68b 100644
--- a/boost/geometry/algorithms/append.hpp
+++ b/boost/geometry/algorithms/append.hpp
@@ -327,7 +327,7 @@ struct append<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
int ring_index,
int multi_index)
{
- apply_visitor(
+ boost::apply_visitor(
visitor<RangeOrPoint>(
range_or_point,
ring_index,
diff --git a/boost/geometry/algorithms/assign.hpp b/boost/geometry/algorithms/assign.hpp
index 2f325448ad..b17e305f2a 100644
--- a/boost/geometry/algorithms/assign.hpp
+++ b/boost/geometry/algorithms/assign.hpp
@@ -281,7 +281,7 @@ struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry1,
Geometry2 const& geometry2)
{
- return apply_visitor(visitor(geometry2), geometry1);
+ return boost::apply_visitor(visitor(geometry2), geometry1);
}
};
@@ -313,7 +313,7 @@ struct assign<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
apply(Geometry1& geometry1,
variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
{
- return apply_visitor(visitor(geometry1), geometry2);
+ return boost::apply_visitor(visitor(geometry1), geometry2);
}
};
@@ -341,7 +341,7 @@ struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM
apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
{
- return apply_visitor(visitor(), geometry1, geometry2);
+ return boost::apply_visitor(visitor(), geometry1, geometry2);
}
};
diff --git a/boost/geometry/algorithms/buffer.hpp b/boost/geometry/algorithms/buffer.hpp
index d85d32a0c6..e776072a2f 100644
--- a/boost/geometry/algorithms/buffer.hpp
+++ b/boost/geometry/algorithms/buffer.hpp
@@ -18,12 +18,15 @@
#include <boost/numeric/conversion/cast.hpp>
+#include <boost/range.hpp>
+
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/clear.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
@@ -261,9 +264,15 @@ inline void buffer(GeometryIn const& geometry_in,
geometry_out.clear();
+ if (geometry::is_empty(geometry_in))
+ {
+ // Then output geometry is kept empty as well
+ return;
+ }
+
model::box<point_type> box;
- envelope(geometry_in, box);
- buffer(box, box, distance_strategy.max_distance(join_strategy, end_strategy));
+ geometry::envelope(geometry_in, box);
+ geometry::buffer(box, box, distance_strategy.max_distance(join_strategy, end_strategy));
rescale_policy_type rescale_policy
= boost::geometry::get_rescale_policy<rescale_policy_type>(box);
diff --git a/boost/geometry/algorithms/centroid.hpp b/boost/geometry/algorithms/centroid.hpp
index 67ed68ac03..1b99ab2ef3 100644
--- a/boost/geometry/algorithms/centroid.hpp
+++ b/boost/geometry/algorithms/centroid.hpp
@@ -1,14 +1,15 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2014, 2015.
// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -55,8 +56,7 @@
#include <boost/geometry/util/for_each_coordinate.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
-#include <boost/geometry/multi/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/detail/centroid/translating_transformer.hpp>
@@ -361,7 +361,7 @@ struct centroid_multi
#if ! defined(BOOST_GEOMETRY_CENTROID_NO_THROW)
// If there is nothing in any of the ranges, it is not possible
// to calculate the centroid
- if (geometry::num_points(multi) == 0)
+ if (geometry::is_empty(multi))
{
throw centroid_exception();
}
@@ -624,7 +624,7 @@ inline void centroid(Geometry const& geometry, Point& c,
template<typename Geometry, typename Point>
inline void centroid(Geometry const& geometry, Point& c)
{
- centroid(geometry, c, default_strategy());
+ geometry::centroid(geometry, c, default_strategy());
}
@@ -643,7 +643,7 @@ template<typename Point, typename Geometry>
inline Point return_centroid(Geometry const& geometry)
{
Point c;
- centroid(geometry, c);
+ geometry::centroid(geometry, c);
return c;
}
@@ -666,7 +666,7 @@ template<typename Point, typename Geometry, typename Strategy>
inline Point return_centroid(Geometry const& geometry, Strategy const& strategy)
{
Point c;
- centroid(geometry, c, strategy);
+ geometry::centroid(geometry, c, strategy);
return c;
}
diff --git a/boost/geometry/algorithms/clear.hpp b/boost/geometry/algorithms/clear.hpp
index 22b61e7c30..54b2162767 100644
--- a/boost/geometry/algorithms/clear.hpp
+++ b/boost/geometry/algorithms/clear.hpp
@@ -162,7 +162,7 @@ struct clear<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
static inline void apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry)
{
- apply_visitor(visitor(), geometry);
+ boost::apply_visitor(visitor(), geometry);
}
};
diff --git a/boost/geometry/algorithms/convert.hpp b/boost/geometry/algorithms/convert.hpp
index 5d68854a45..78618aed2d 100644
--- a/boost/geometry/algorithms/convert.hpp
+++ b/boost/geometry/algorithms/convert.hpp
@@ -522,7 +522,7 @@ struct convert<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Geometry2& geometry2
)
{
- apply_visitor(visitor(geometry2), geometry1);
+ boost::apply_visitor(visitor(geometry2), geometry1);
}
};
diff --git a/boost/geometry/algorithms/convex_hull.hpp b/boost/geometry/algorithms/convex_hull.hpp
index c6db004f3d..71c18bb5f3 100644
--- a/boost/geometry/algorithms/convex_hull.hpp
+++ b/boost/geometry/algorithms/convex_hull.hpp
@@ -1,13 +1,14 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014, 2015.
// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -40,7 +41,7 @@
#include <boost/geometry/views/detail/range_type.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/detail/as_range.hpp>
#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
@@ -301,7 +302,7 @@ template<typename Geometry, typename OutputGeometry, typename Strategy>
inline void convex_hull(Geometry const& geometry,
OutputGeometry& out, Strategy const& strategy)
{
- if (geometry::num_points(geometry) == 0)
+ if (geometry::is_empty(geometry))
{
// Leave output empty
return;
@@ -326,7 +327,7 @@ template<typename Geometry, typename OutputGeometry>
inline void convex_hull(Geometry const& geometry,
OutputGeometry& hull)
{
- convex_hull(geometry, hull, default_strategy());
+ geometry::convex_hull(geometry, hull, default_strategy());
}
#ifndef DOXYGEN_NO_DETAIL
diff --git a/boost/geometry/algorithms/crosses.hpp b/boost/geometry/algorithms/crosses.hpp
index cec4931a64..9546a5335b 100644
--- a/boost/geometry/algorithms/crosses.hpp
+++ b/boost/geometry/algorithms/crosses.hpp
@@ -30,7 +30,8 @@
#include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
namespace boost { namespace geometry
{
@@ -48,9 +49,9 @@ template
typename Tag2 = typename tag<Geometry2>::type
>
struct crosses
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_crosses_type,
+ detail::de9im::static_mask_crosses_type,
Geometry1,
Geometry2
>
@@ -87,18 +88,17 @@ namespace resolve_variant
Geometry2 const& m_geometry2;
visitor(Geometry2 const& geometry2)
- : m_geometry2(geometry2)
+ : m_geometry2(geometry2)
{}
template <typename Geometry1>
result_type operator()(Geometry1 const& geometry1) const
{
return crosses
- <
- Geometry1,
- Geometry2
- >::apply
- (geometry1, m_geometry2);
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, m_geometry2);
}
};
@@ -106,7 +106,7 @@ namespace resolve_variant
apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Geometry2 const& geometry2)
{
- return apply_visitor(visitor(geometry2), geometry1);
+ return boost::apply_visitor(visitor(geometry2), geometry1);
}
};
@@ -119,27 +119,25 @@ namespace resolve_variant
Geometry1 const& m_geometry1;
visitor(Geometry1 const& geometry1)
- : m_geometry1(geometry1)
+ : m_geometry1(geometry1)
{}
template <typename Geometry2>
result_type operator()(Geometry2 const& geometry2) const
{
return crosses
- <
- Geometry1,
- Geometry2
- >::apply
- (m_geometry1, geometry2);
+ <
+ Geometry1,
+ Geometry2
+ >::apply(m_geometry1, geometry2);
}
};
static inline bool
- apply(
- Geometry1 const& geometry1,
+ apply(Geometry1 const& geometry1,
const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2)
{
- return apply_visitor(visitor(geometry1), geometry2);
+ return boost::apply_visitor(visitor(geometry1), geometry2);
}
};
@@ -150,25 +148,22 @@ namespace resolve_variant
struct visitor: static_visitor<bool>
{
template <typename Geometry1, typename Geometry2>
- result_type operator()(
- Geometry1 const& geometry1,
+ result_type operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
{
return crosses
- <
- Geometry1,
- Geometry2
- >::apply
- (geometry1, geometry2);
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2);
}
};
static inline bool
- apply(
- const variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
+ apply(const variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
const variant<BOOST_VARIANT_ENUM_PARAMS(T2)>& geometry2)
{
- return apply_visitor(visitor(), geometry1, geometry2);
+ return boost::apply_visitor(visitor(), geometry1, geometry2);
}
};
diff --git a/boost/geometry/algorithms/detail/andoyer_inverse.hpp b/boost/geometry/algorithms/detail/andoyer_inverse.hpp
new file mode 100644
index 0000000000..eb8485b8e1
--- /dev/null
+++ b/boost/geometry/algorithms/detail/andoyer_inverse.hpp
@@ -0,0 +1,163 @@
+// Boost.Geometry
+
+// Copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_ALGORITHMS_DETAIL_ANDOYER_INVERSE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ANDOYER_INVERSE_HPP
+
+
+#include <boost/math/constants/constants.hpp>
+
+#include <boost/geometry/core/radius.hpp>
+#include <boost/geometry/core/srs.hpp>
+
+#include <boost/geometry/util/condition.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/flattening.hpp>
+#include <boost/geometry/algorithms/detail/result_inverse.hpp>
+
+
+namespace boost { namespace geometry { namespace detail
+{
+
+/*!
+\brief The solution of the inverse problem of geodesics on latlong coordinates,
+ Forsyth-Andoyer-Lambert type approximation with first order terms.
+\author See
+ - Technical Report: PAUL D. THOMAS, MATHEMATICAL MODELS FOR NAVIGATION SYSTEMS, 1965
+ http://www.dtic.mil/docs/citations/AD0627893
+ - Technical Report: PAUL D. THOMAS, SPHEROIDAL GEODESICS, REFERENCE SYSTEMS, AND LOCAL GEOMETRY, 1970
+ http://www.dtic.mil/docs/citations/AD703541
+*/
+
+template <typename CT, bool EnableDistance, bool EnableAzimuth>
+struct andoyer_inverse
+{
+ typedef result_inverse<CT> result_type;
+
+ template <typename T1, typename T2, typename Spheroid>
+ static inline result_type apply(T1 const& lon1,
+ T1 const& lat1,
+ T2 const& lon2,
+ T2 const& lat2,
+ Spheroid const& spheroid)
+ {
+ result_type result;
+
+ // coordinates in radians
+
+ if ( math::equals(lon1, lon2)
+ && math::equals(lat1, lat2) )
+ {
+ result.set(CT(0), CT(0));
+ return result;
+ }
+
+ CT const pi_half = math::pi<CT>() / CT(2);
+
+ if ( math::equals(math::abs(lat1), pi_half)
+ && math::equals(math::abs(lat2), pi_half) )
+ {
+ result.set(CT(0), CT(0));
+ return result;
+ }
+
+ CT const dlon = lon2 - lon1;
+ CT const sin_dlon = sin(dlon);
+ CT const cos_dlon = cos(dlon);
+ CT const sin_lat1 = sin(lat1);
+ CT const cos_lat1 = cos(lat1);
+ CT const sin_lat2 = sin(lat2);
+ CT const cos_lat2 = cos(lat2);
+
+ // H,G,T = infinity if cos_d = 1 or cos_d = -1
+ // lat1 == +-90 && lat2 == +-90
+ // lat1 == lat2 && lon1 == lon2
+ CT const cos_d = sin_lat1*sin_lat2 + cos_lat1*cos_lat2*cos_dlon;
+ CT const d = acos(cos_d);
+ CT const sin_d = sin(d);
+
+ // just in case since above lat1 and lat2 is checked
+ // the check below is equal to cos_d == 1 || cos_d == -1 || d == 0
+ if ( math::equals(sin_d, CT(0)) )
+ {
+ result.set(CT(0), CT(0));
+ return result;
+ }
+
+ // if the function returned before this place
+ // and endpoints were on the poles +-90 deg
+ // in this case the azimuth could either be 0 or +-pi
+
+ CT const f = detail::flattening<CT>(spheroid);
+
+ if ( BOOST_GEOMETRY_CONDITION(EnableDistance) )
+ {
+ CT const K = math::sqr(sin_lat1-sin_lat2);
+ CT const L = math::sqr(sin_lat1+sin_lat2);
+ CT const three_sin_d = CT(3) * sin_d;
+ // H or G = infinity if cos_d = 1 or cos_d = -1
+ CT const H = (d+three_sin_d)/(CT(1)-cos_d);
+ CT const G = (d-three_sin_d)/(CT(1)+cos_d);
+
+ // for e.g. lat1=-90 && lat2=90 here we have G*L=INF*0
+ CT const dd = -(f/CT(4))*(H*K+G*L);
+
+ CT const a = get_radius<0>(spheroid);
+
+ result.distance = a * (d + dd);
+ }
+ else
+ {
+ result.distance = CT(0);
+ }
+
+ if ( BOOST_GEOMETRY_CONDITION(EnableAzimuth) )
+ {
+ CT A = CT(0);
+ CT U = CT(0);
+ if ( ! math::equals(cos_lat2, CT(0)) )
+ {
+ CT const tan_lat2 = sin_lat2/cos_lat2;
+ CT const M = cos_lat1*tan_lat2-sin_lat1*cos_dlon;
+ A = atan2(sin_dlon, M);
+ CT const sin_2A = sin(CT(2)*A);
+ U = (f/CT(2))*math::sqr(cos_lat1)*sin_2A;
+ }
+
+ CT V = CT(0);
+ if ( ! math::equals(cos_lat1, CT(0)) )
+ {
+ CT const tan_lat1 = sin_lat1/cos_lat1;
+ CT const N = cos_lat2*tan_lat1-sin_lat2*cos_dlon;
+ CT const B = atan2(sin_dlon, N);
+ CT const sin_2B = sin(CT(2)*B);
+ V = (f/CT(2))*math::sqr(cos_lat2)*sin_2B;
+ }
+
+ // infinity if sin_d = 0, so cos_d = 1 or cos_d = -1
+ CT const T = d / sin_d;
+ CT const dA = V*T-U;
+
+ result.azimuth = A - dA;
+ }
+ else
+ {
+ result.azimuth = CT(0);
+ }
+
+ return result;
+ }
+};
+
+}}} // namespace boost::geometry::detail
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ANDOYER_INVERSE_HPP
diff --git a/boost/geometry/algorithms/detail/azimuth.hpp b/boost/geometry/algorithms/detail/azimuth.hpp
index 7810b4814e..f0a8d65c86 100644
--- a/boost/geometry/algorithms/detail/azimuth.hpp
+++ b/boost/geometry/algorithms/detail/azimuth.hpp
@@ -49,10 +49,10 @@ struct azimuth<ReturnType, geographic_tag>
template <typename P1, typename P2, typename Spheroid>
static inline ReturnType apply(P1 const& p1, P2 const& p2, Spheroid const& spheroid)
{
- return geometry::detail::vincenty_inverse<ReturnType>
+ return geometry::detail::vincenty_inverse<ReturnType, false, true>
( get_as_radian<0>(p1), get_as_radian<1>(p1),
get_as_radian<0>(p2), get_as_radian<1>(p2),
- spheroid ).azimuth12();
+ spheroid ).azimuth;
}
template <typename P1, typename P2>
diff --git a/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp b/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
index 127e4c3fb2..b25bcc7fb5 100644
--- a/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
+++ b/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
@@ -12,11 +12,12 @@
#include <cstddef>
#include <iterator>
+
#include <boost/core/ignore_unused.hpp>
#include <boost/numeric/conversion/cast.hpp>
-
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
@@ -227,7 +228,7 @@ struct buffer_range
typename EndStrategy,
typename RobustPolicy
>
- static inline bool iterate(Collection& collection,
+ static inline strategy::buffer::result_code iterate(Collection& collection,
Iterator begin, Iterator end,
strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance_strategy,
@@ -266,7 +267,7 @@ struct buffer_range
* pup: penultimate_point
*/
- bool result = false;
+ strategy::buffer::result_code result = strategy::buffer::result_no_output;
bool first = true;
Iterator it = begin;
@@ -277,18 +278,25 @@ struct buffer_range
for (Iterator prev = it++; it != end; ++it)
{
generated_side.clear();
- side_strategy.apply(*prev, *it, side,
+ strategy::buffer::result_code error_code
+ = side_strategy.apply(*prev, *it, side,
distance_strategy, generated_side);
- if (generated_side.empty())
+ if (error_code == strategy::buffer::result_no_output)
{
// Because input is simplified, this is improbable,
// but it can happen for degenerate geometries
// Further handling of this side is skipped
continue;
}
+ else if (error_code == strategy::buffer::result_error_numerical)
+ {
+ return error_code;
+ }
+
+ BOOST_GEOMETRY_ASSERT(! generated_side.empty());
- result = true;
+ result = strategy::buffer::result_normal;
if (! first)
{
@@ -383,6 +391,7 @@ inline void buffer_point(Point const& point, Collection& collection,
std::vector<OutputPointType> range_out;
point_strategy.apply(point, distance_strategy, range_out);
collection.add_piece(strategy::buffer::buffered_point, range_out, false);
+ collection.set_piece_center(point);
collection.finish_ring();
}
@@ -458,7 +467,7 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
typename EndStrategy,
typename RobustPolicy
>
- static inline bool iterate(Collection& collection,
+ static inline strategy::buffer::result_code iterate(Collection& collection,
Iterator begin, Iterator end,
strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance_strategy,
@@ -471,13 +480,14 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
typedef detail::buffer::buffer_range<RingOutput> buffer_range;
- bool result = buffer_range::iterate(collection, begin, end,
+ strategy::buffer::result_code result
+ = buffer_range::iterate(collection, begin, end,
side,
distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1, first_p2, last_p1, last_p2);
// Generate closing join
- if (result)
+ if (result == strategy::buffer::result_normal)
{
buffer_range::add_join(collection,
*(end - 2),
@@ -502,7 +512,7 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
typename PointStrategy,
typename RobustPolicy
>
- static inline void apply(RingInput const& ring,
+ static inline strategy::buffer::result_code apply(RingInput const& ring,
Collection& collection,
DistanceStrategy const& distance,
SideStrategy const& side_strategy,
@@ -514,7 +524,7 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
RingInput simplified;
detail::buffer::simplify_input(ring, distance, simplified);
- bool has_output = false;
+ strategy::buffer::result_code code = strategy::buffer::result_no_output;
std::size_t n = boost::size(simplified);
std::size_t const min_points = core_detail::closure::minimum_ring_size
@@ -528,21 +538,19 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
if (distance.negative())
{
// Walk backwards (rings will be reversed afterwards)
- // It might be that this will be changed later.
- // TODO: decide this.
- has_output = iterate(collection, boost::rbegin(view), boost::rend(view),
+ code = iterate(collection, boost::rbegin(view), boost::rend(view),
strategy::buffer::buffer_side_right,
distance, side_strategy, join_strategy, end_strategy, robust_policy);
}
else
{
- has_output = iterate(collection, boost::begin(view), boost::end(view),
+ code = iterate(collection, boost::begin(view), boost::end(view),
strategy::buffer::buffer_side_left,
distance, side_strategy, join_strategy, end_strategy, robust_policy);
}
}
- if (! has_output && n >= 1)
+ if (code == strategy::buffer::result_no_output && n >= 1)
{
// Use point_strategy to buffer degenerated ring
detail::buffer::buffer_point<output_point_type>
@@ -551,6 +559,7 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
collection, distance, point_strategy
);
}
+ return code;
}
};
@@ -576,7 +585,7 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
typename EndStrategy,
typename RobustPolicy
>
- static inline bool iterate(Collection& collection,
+ static inline strategy::buffer::result_code iterate(Collection& collection,
Iterator begin, Iterator end,
strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance_strategy,
@@ -601,27 +610,33 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
else
{
std::vector<output_point_type> generated_side;
- side_strategy.apply(ultimate_point, penultimate_point,
+ strategy::buffer::result_code code
+ = side_strategy.apply(ultimate_point, penultimate_point,
strategy::buffer::buffer_side_right,
distance_strategy, generated_side);
- if (generated_side.empty())
+ if (code != strategy::buffer::result_normal)
{
- return false;
+ // No output or numerical error
+ return code;
}
reverse_p1 = generated_side.front();
}
output_point_type first_p2, last_p1, last_p2;
- detail::buffer::buffer_range<output_ring_type>::iterate(collection,
+ strategy::buffer::result_code result
+ = detail::buffer::buffer_range<output_ring_type>::iterate(collection,
begin, end, side,
distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1, first_p2, last_p1, last_p2);
- std::vector<output_point_type> range_out;
- end_strategy.apply(penultimate_point, last_p2, ultimate_point, reverse_p1, side, distance_strategy, range_out);
- collection.add_endcap(end_strategy, range_out, ultimate_point);
- return true;
+ if (result == strategy::buffer::result_normal)
+ {
+ std::vector<output_point_type> range_out;
+ end_strategy.apply(penultimate_point, last_p2, ultimate_point, reverse_p1, side, distance_strategy, range_out);
+ collection.add_endcap(end_strategy, range_out, ultimate_point);
+ }
+ return result;
}
template
@@ -634,7 +649,7 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
typename PointStrategy,
typename RobustPolicy
>
- static inline void apply(Linestring const& linestring, Collection& collection,
+ static inline strategy::buffer::result_code apply(Linestring const& linestring, Collection& collection,
DistanceStrategy const& distance,
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
@@ -645,28 +660,29 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
Linestring simplified;
detail::buffer::simplify_input(linestring, distance, simplified);
- bool has_output = false;
+ strategy::buffer::result_code code = strategy::buffer::result_no_output;
std::size_t n = boost::size(simplified);
if (n > 1)
{
collection.start_new_ring();
output_point_type first_p1;
- has_output = iterate(collection,
+ code = iterate(collection,
boost::begin(simplified), boost::end(simplified),
strategy::buffer::buffer_side_left,
distance, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1);
- if (has_output)
+ if (code == strategy::buffer::result_normal)
{
- iterate(collection, boost::rbegin(simplified), boost::rend(simplified),
+ code = iterate(collection,
+ boost::rbegin(simplified), boost::rend(simplified),
strategy::buffer::buffer_side_right,
distance, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1);
}
collection.finish_ring();
}
- if (! has_output && n >= 1)
+ if (code == strategy::buffer::result_no_output && n >= 1)
{
// Use point_strategy to buffer degenerated linestring
detail::buffer::buffer_point<output_point_type>
@@ -675,6 +691,7 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
collection, distance, point_strategy
);
}
+ return code;
}
};
@@ -718,9 +735,16 @@ private:
for (Iterator it = begin; it != end; ++it)
{
collection.start_new_ring();
- policy::apply(*it, collection, distance, side_strategy,
+ strategy::buffer::result_code const code
+ = policy::apply(*it, collection, distance, side_strategy,
join_strategy, end_strategy, point_strategy,
robust_policy);
+
+ if (code == strategy::buffer::result_error_numerical)
+ {
+ collection.abort_ring();
+ return;
+ }
collection.finish_ring(is_interior);
}
}
@@ -774,11 +798,21 @@ public:
{
{
collection.start_new_ring();
- policy::apply(exterior_ring(polygon), collection,
+
+ strategy::buffer::result_code const code
+ = policy::apply(exterior_ring(polygon), collection,
distance, side_strategy,
join_strategy, end_strategy, point_strategy,
robust_policy);
- collection.finish_ring(false, geometry::num_interior_rings(polygon) > 0u);
+
+ if (code == strategy::buffer::result_error_numerical)
+ {
+ collection.abort_ring();
+ }
+ else
+ {
+ collection.finish_ring(false, geometry::num_interior_rings(polygon) > 0u);
+ }
}
apply_interior_rings(interior_rings(polygon),
@@ -910,7 +944,7 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
collection.reverse();
}
- if (distance_strategy.negative() && areal)
+ if (BOOST_GEOMETRY_CONDITION(distance_strategy.negative() && areal))
{
collection.discard_nonintersecting_deflated_rings();
}
diff --git a/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp b/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
index c5bb8acc05..255ac797dc 100644
--- a/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
+++ b/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
@@ -9,6 +9,9 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFER_POLICIES_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFER_POLICIES_HPP
+#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
+# define BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION
+#endif
#include <cstddef>
@@ -81,8 +84,8 @@ template <typename Point, typename SegmentRatio>
struct buffer_turn_operation
: public detail::overlay::traversal_turn_operation<Point, SegmentRatio>
{
- int piece_index;
- int index_in_robust_ring;
+ signed_size_type piece_index;
+ signed_size_type index_in_robust_ring;
inline buffer_turn_operation()
: piece_index(-1)
@@ -103,7 +106,7 @@ struct buffer_turn_info
typedef Point point_type;
typedef RobustPoint robust_point_type;
- int turn_index; // TODO: this might go if partition can operate on non-const input
+ std::size_t turn_index; // TODO: this might go if partition can operate on non-const input
RobustPoint robust_point;
#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
@@ -122,24 +125,30 @@ struct buffer_turn_info
intersection_location_type location;
- int count_within;
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ robust_point_type rob_pi, rob_pj, rob_qi, rob_qj;
+#endif
+
+ std::size_t count_within;
bool within_original;
- int count_on_original_boundary;
- int count_in_original; // increased by +1 for in ext.ring, -1 for int.ring
+ std::size_t count_on_original_boundary;
+ signed_size_type count_in_original; // increased by +1 for in ext.ring, -1 for int.ring
- int count_on_offsetted;
- int count_on_helper;
- int count_within_near_offsetted;
+ std::size_t count_on_offsetted;
+ std::size_t count_on_helper;
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ std::size_t count_within_near_offsetted;
+#endif
bool remove_on_multi;
// Obsolete:
- int count_on_occupied;
- int count_on_multi;
+ std::size_t count_on_occupied;
+ std::size_t count_on_multi;
inline buffer_turn_info()
- : turn_index(-1)
+ : turn_index(0)
, location(location_ok)
, count_within(0)
, within_original(false)
@@ -147,7 +156,9 @@ struct buffer_turn_info
, count_in_original(0)
, count_on_offsetted(0)
, count_on_helper(0)
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
, count_within_near_offsetted(0)
+#endif
, remove_on_multi(false)
, count_on_occupied(0)
, count_on_multi(0)
diff --git a/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp b/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
index a501e3f197..545d89cb9b 100644
--- a/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
+++ b/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
@@ -16,11 +16,14 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/algorithms/comparable_distance.hpp>
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/is_convex.hpp>
#include <boost/geometry/strategies/buffer.hpp>
@@ -126,6 +129,11 @@ struct buffered_piece_collection
typedef geometry::model::ring<robust_point_type> robust_ring_type;
typedef geometry::model::box<robust_point_type> robust_box_type;
+ typedef typename default_comparable_distance_result
+ <
+ robust_point_type
+ >::type robust_comparable_radius_type;
+
typedef typename strategy::side::services::default_strategy
<
typename cs_tag<point_type>::type
@@ -159,7 +167,7 @@ struct buffered_piece_collection
struct robust_turn
{
- int turn_index;
+ std::size_t turn_index;
int operation_index;
robust_point_type point;
segment_identifier seg_id;
@@ -172,10 +180,10 @@ struct buffered_piece_collection
typedef geometry::section<robust_box_type, 1> section_type;
strategy::buffer::piece_type type;
- int index;
+ signed_size_type index;
- int left_index; // points to previous piece of same ring
- int right_index; // points to next piece of same ring
+ signed_size_type left_index; // points to previous piece of same ring
+ signed_size_type right_index; // points to next piece of same ring
// The next two members (1, 2) form together a complete clockwise ring
// for each piece (with one dupped point)
@@ -183,21 +191,21 @@ struct buffered_piece_collection
// 1: half, part of offsetted_rings
segment_identifier first_seg_id;
- int last_segment_index; // no segment-identifier - it is the same as first_seg_id
- int offsetted_count; // part in robust_ring which is part of offsetted ring
+ signed_size_type last_segment_index; // no segment-identifier - it is the same as first_seg_id
+ signed_size_type offsetted_count; // part in robust_ring which is part of offsetted ring
#if defined(BOOST_GEOMETRY_BUFFER_USE_HELPER_POINTS)
// 2: half, not part of offsetted rings - part of robust ring
std::vector<point_type> helper_points; // 4 points for side, 3 points for join - 0 points for flat-end
#endif
+ bool is_convex;
bool is_monotonic_increasing[2]; // 0=x, 1=y
bool is_monotonic_decreasing[2]; // 0=x, 1=y
// Monotonic sections of pieces around points
std::vector<section_type> sections;
-
// Robust representations
// 3: complete ring
robust_ring_type robust_ring;
@@ -206,6 +214,27 @@ struct buffered_piece_collection
robust_box_type robust_offsetted_envelope;
std::vector<robust_turn> robust_turns; // Used only in insert_rescaled_piece_turns - we might use a map instead
+
+ robust_point_type robust_center;
+ robust_comparable_radius_type robust_min_comparable_radius;
+ robust_comparable_radius_type robust_max_comparable_radius;
+
+ piece()
+ : type(strategy::buffer::piece_type_unknown)
+ , index(-1)
+ , left_index(-1)
+ , right_index(-1)
+ , last_segment_index(-1)
+ , offsetted_count(-1)
+ , is_convex(false)
+ , robust_min_comparable_radius(0)
+ , robust_max_comparable_radius(0)
+ {
+ is_monotonic_increasing[0] = false;
+ is_monotonic_increasing[1] = false;
+ is_monotonic_decreasing[0] = false;
+ is_monotonic_decreasing[1] = false;
+ }
};
struct robust_original
@@ -244,7 +273,7 @@ struct buffered_piece_collection
piece_vector_type m_pieces;
turn_vector_type m_turns;
- int m_first_piece_index;
+ signed_size_type m_first_piece_index;
buffered_ring_collection<buffered_ring<Ring> > offsetted_rings; // indexed by multi_index
std::vector<robust_original> robust_originals; // robust representation of the original(s)
@@ -444,6 +473,7 @@ struct buffered_piece_collection
{
it->location = inside_buffer;
}
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
if (it->count_within_near_offsetted > 0)
{
// Within can have in rare cases a rounding issue. We don't discard this
@@ -451,6 +481,7 @@ struct buffered_piece_collection
// will never start a new ring from this type of points.
it->selectable_start = false;
}
+#endif
}
}
@@ -515,7 +546,7 @@ struct buffered_piece_collection
{
// Add rescaled turn points to corresponding pieces
// (after this, each turn occurs twice)
- int index = 0;
+ std::size_t index = 0;
for (typename boost::range_iterator<turn_vector_type>::type it =
boost::begin(m_turns); it != boost::end(m_turns); ++it, ++index)
{
@@ -544,16 +575,16 @@ struct buffered_piece_collection
}
}
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
// Insert all rescaled turn-points into these rings, to form a
// reliable integer-based ring. All turns can be compared (inside) to this
// rings to see if they are inside.
- for (typename piece_vector_type::iterator it = boost::begin(m_pieces);
- it != boost::end(m_pieces);
- ++it)
+ for (typename boost::range_iterator<piece_vector_type>::type
+ it = boost::begin(m_pieces); it != boost::end(m_pieces); ++it)
{
piece& pc = *it;
- int piece_segment_index = pc.first_seg_id.segment_index;
+ signed_size_type piece_segment_index = pc.first_seg_id.segment_index;
if (! pc.robust_turns.empty())
{
if (pc.robust_turns.size() > 1u)
@@ -561,14 +592,14 @@ struct buffered_piece_collection
std::sort(pc.robust_turns.begin(), pc.robust_turns.end(), buffer_operation_less());
}
// Walk through them, in reverse to insert at right index
- int index_offset = pc.robust_turns.size() - 1;
- for (typename std::vector<robust_turn>::const_reverse_iterator
- rit = pc.robust_turns.rbegin();
- rit != pc.robust_turns.rend();
+ signed_size_type index_offset = static_cast<signed_size_type>(pc.robust_turns.size()) - 1;
+ for (typename boost::range_reverse_iterator<const std::vector<robust_turn> >::type
+ rit = boost::const_rbegin(pc.robust_turns);
+ rit != boost::const_rend(pc.robust_turns);
++rit, --index_offset)
{
- int const index_in_vector = 1 + rit->seg_id.segment_index - piece_segment_index;
- BOOST_ASSERT
+ signed_size_type const index_in_vector = 1 + rit->seg_id.segment_index - piece_segment_index;
+ BOOST_GEOMETRY_ASSERT
(
index_in_vector > 0
&& index_in_vector < pc.offsetted_count
@@ -582,7 +613,8 @@ struct buffered_piece_collection
}
}
- BOOST_ASSERT(assert_indices_in_robust_rings());
+ BOOST_GEOMETRY_ASSERT(assert_indices_in_robust_rings());
+#endif
}
template <std::size_t Dimension>
@@ -607,6 +639,8 @@ struct buffered_piece_collection
pc.is_monotonic_decreasing[0] = true;
pc.is_monotonic_decreasing[1] = true;
+ pc.is_convex = geometry::is_convex(pc.robust_ring);
+
if (pc.offsetted_count < 2)
{
return;
@@ -615,14 +649,13 @@ struct buffered_piece_collection
typename robust_ring_type::const_iterator current = pc.robust_ring.begin();
typename robust_ring_type::const_iterator next = current + 1;
- for (int i = 1; i < pc.offsetted_count; i++)
+ for (signed_size_type i = 1; i < pc.offsetted_count; i++)
{
determine_monotonicity<0>(pc, *current, *next);
determine_monotonicity<1>(pc, *current, *next);
current = next;
++next;
}
-
}
void determine_properties()
@@ -659,7 +692,31 @@ struct buffered_piece_collection
geometry::sectionalize<false, dimensions>(pc.robust_ring,
detail::no_rescale_policy(), pc.sections);
- // TODO (next phase) determine min/max radius
+ // Determine min/max radius
+ typedef geometry::model::referring_segment<robust_point_type const>
+ robust_segment_type;
+
+ typename robust_ring_type::const_iterator current = pc.robust_ring.begin();
+ typename robust_ring_type::const_iterator next = current + 1;
+
+ for (signed_size_type i = 1; i < pc.offsetted_count; i++)
+ {
+ robust_segment_type s(*current, *next);
+ robust_comparable_radius_type const d
+ = geometry::comparable_distance(pc.robust_center, s);
+
+ if (i == 1 || d < pc.robust_min_comparable_radius)
+ {
+ pc.robust_min_comparable_radius = d;
+ }
+ if (i == 1 || d > pc.robust_max_comparable_radius)
+ {
+ pc.robust_max_comparable_radius = d;
+ }
+
+ current = next;
+ ++next;
+ }
}
inline void prepare_buffered_point_pieces()
@@ -730,7 +787,7 @@ struct buffered_piece_collection
inline void start_new_ring()
{
- int const n = offsetted_rings.size();
+ signed_size_type const n = static_cast<signed_size_type>(offsetted_rings.size());
current_segment_id.source_index = 0;
current_segment_id.multi_index = n;
current_segment_id.ring_index = -1;
@@ -739,12 +796,35 @@ struct buffered_piece_collection
offsetted_rings.resize(n + 1);
current_robust_ring.clear();
- m_first_piece_index = boost::size(m_pieces);
+ m_first_piece_index = static_cast<signed_size_type>(boost::size(m_pieces));
+ }
+
+ inline void abort_ring()
+ {
+ // Remove all created pieces for this ring, sections, last offsetted
+ while (! m_pieces.empty()
+ && m_pieces.back().first_seg_id.multi_index
+ == current_segment_id.multi_index)
+ {
+ m_pieces.erase(m_pieces.end() - 1);
+ }
+
+ while (! monotonic_sections.empty()
+ && monotonic_sections.back().ring_id.multi_index
+ == current_segment_id.multi_index)
+ {
+ monotonic_sections.erase(monotonic_sections.end() - 1);
+ }
+
+ offsetted_rings.erase(offsetted_rings.end() - 1);
+ current_robust_ring.clear();
+
+ m_first_piece_index = -1;
}
inline void update_closing_point()
{
- BOOST_ASSERT(! offsetted_rings.empty());
+ BOOST_GEOMETRY_ASSERT(! offsetted_rings.empty());
buffered_ring<Ring>& added = offsetted_rings.back();
if (! boost::empty(added))
{
@@ -764,7 +844,7 @@ struct buffered_piece_collection
// For now, it is made equal because due to numerical instability,
// it can be a tiny bit off, possibly causing a self-intersection
- BOOST_ASSERT(boost::size(m_pieces) > 0);
+ BOOST_GEOMETRY_ASSERT(boost::size(m_pieces) > 0);
if (! ring.empty()
&& current_segment_id.segment_index
== m_pieces.back().first_seg_id.segment_index)
@@ -773,6 +853,13 @@ struct buffered_piece_collection
}
}
+ inline void set_piece_center(point_type const& center)
+ {
+ BOOST_GEOMETRY_ASSERT(! m_pieces.empty());
+ geometry::recalculate(m_pieces.back().robust_center, center,
+ m_robust_policy);
+ }
+
inline void finish_ring(bool is_interior = false, bool has_interiors = false)
{
if (m_first_piece_index == -1)
@@ -780,12 +867,12 @@ struct buffered_piece_collection
return;
}
- if (m_first_piece_index < static_cast<int>(boost::size(m_pieces)))
+ if (m_first_piece_index < static_cast<signed_size_type>(boost::size(m_pieces)))
{
// If piece was added
// Reassign left-of-first and right-of-last
geometry::range::at(m_pieces, m_first_piece_index).left_index
- = boost::size(m_pieces) - 1;
+ = static_cast<signed_size_type>(boost::size(m_pieces)) - 1;
geometry::range::back(m_pieces).right_index = m_first_piece_index;
}
m_first_piece_index = -1;
@@ -794,7 +881,7 @@ struct buffered_piece_collection
if (! current_robust_ring.empty())
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
geometry::equals(current_robust_ring.front(),
current_robust_ring.back())
@@ -808,20 +895,20 @@ struct buffered_piece_collection
inline void set_current_ring_concave()
{
- BOOST_ASSERT(boost::size(offsetted_rings) > 0);
+ BOOST_GEOMETRY_ASSERT(boost::size(offsetted_rings) > 0);
offsetted_rings.back().has_concave = true;
}
- inline int add_point(point_type const& p)
+ inline signed_size_type add_point(point_type const& p)
{
- BOOST_ASSERT(boost::size(offsetted_rings) > 0);
+ BOOST_GEOMETRY_ASSERT(boost::size(offsetted_rings) > 0);
buffered_ring<Ring>& current_ring = offsetted_rings.back();
update_last_point(p, current_ring);
current_segment_id.segment_index++;
current_ring.push_back(p);
- return current_ring.size();
+ return static_cast<signed_size_type>(current_ring.size());
}
//-------------------------------------------------------------------------
@@ -836,7 +923,7 @@ struct buffered_piece_collection
piece pc;
pc.type = type;
- pc.index = boost::size(m_pieces);
+ pc.index = static_cast<signed_size_type>(boost::size(m_pieces));
pc.first_seg_id = current_segment_id;
// Assign left/right (for first/last piece per ring they will be re-assigned later)
@@ -862,11 +949,11 @@ struct buffered_piece_collection
return;
}
- BOOST_ASSERT(pc.first_seg_id.multi_index >= 0);
- BOOST_ASSERT(pc.last_segment_index >= 0);
+ BOOST_GEOMETRY_ASSERT(pc.first_seg_id.multi_index >= 0);
+ BOOST_GEOMETRY_ASSERT(pc.last_segment_index >= 0);
pc.offsetted_count = pc.last_segment_index - pc.first_seg_id.segment_index;
- BOOST_ASSERT(pc.offsetted_count >= 0);
+ BOOST_GEOMETRY_ASSERT(pc.offsetted_count >= 0);
pc.robust_ring.reserve(pc.offsetted_count + helper_points_size);
@@ -915,11 +1002,10 @@ struct buffered_piece_collection
return;
}
- geometry::detail::envelope::envelope_range::apply(pc.robust_ring,
- pc.robust_envelope);
+ geometry::envelope(pc.robust_ring, pc.robust_envelope);
geometry::assign_inverse(pc.robust_offsetted_envelope);
- for (int i = 0; i < pc.offsetted_count; i++)
+ for (signed_size_type i = 0; i < pc.offsetted_count; i++)
{
geometry::expand(pc.robust_offsetted_envelope, pc.robust_ring[i]);
}
@@ -1010,7 +1096,7 @@ struct buffered_piece_collection
template <typename Range>
inline void add_range_to_piece(piece& pc, Range const& range, bool add_front)
{
- BOOST_ASSERT(boost::size(range) != 0u);
+ BOOST_GEOMETRY_ASSERT(boost::size(range) != 0u);
typename Range::const_iterator it = boost::begin(range);
@@ -1046,7 +1132,7 @@ struct buffered_piece_collection
inline void add_side_piece(point_type const& p1, point_type const& p2,
Range const& range, bool first)
{
- BOOST_ASSERT(boost::size(range) >= 2u);
+ BOOST_GEOMETRY_ASSERT(boost::size(range) >= 2u);
piece& pc = create_piece(strategy::buffer::buffered_segment, ! first);
add_range_to_piece(pc, range, first);
@@ -1133,7 +1219,7 @@ struct buffered_piece_collection
robust_point_type any_point;
geometry::recalculate(any_point, point, m_robust_policy);
- int count_in_original = 0;
+ signed_size_type count_in_original = 0;
// Check of the robust point of this outputted ring is in
// any of the robust original rings
@@ -1279,7 +1365,7 @@ struct buffered_piece_collection
// Inner rings, for deflate, which do not have intersections, and
// which are outside originals, are skipped
// (other ones should be traversed)
- int index = 0;
+ signed_size_type index = 0;
for(typename buffered_ring_collection<buffered_ring<Ring> >::const_iterator it = boost::begin(offsetted_rings);
it != boost::end(offsetted_rings);
++it, ++index)
@@ -1287,8 +1373,12 @@ struct buffered_piece_collection
if (! it->has_intersections()
&& ! it->is_untouched_outside_original)
{
- ring_identifier id(0, index, -1);
- selected[id] = properties(*it);
+ properties p = properties(*it);
+ if (p.valid)
+ {
+ ring_identifier id(0, index, -1);
+ selected[id] = p;
+ }
}
}
@@ -1299,8 +1389,12 @@ struct buffered_piece_collection
it != boost::end(traversed_rings);
++it, ++index)
{
- ring_identifier id(2, index, -1);
- selected[id] = properties(*it);
+ properties p = properties(*it);
+ if (p.valid)
+ {
+ ring_identifier id(2, index, -1);
+ selected[id] = p;
+ }
}
detail::overlay::assign_parents(offsetted_rings, traversed_rings, selected, true);
diff --git a/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp b/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp
index 9ea8bc1e85..19c91544ac 100644
--- a/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp
+++ b/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -14,11 +14,14 @@
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/buffer.hpp>
+#include <boost/geometry/algorithms/within.hpp>
+
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
#include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
@@ -26,8 +29,6 @@
#include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
-#include <boost/geometry/multi/algorithms/within.hpp>
-
namespace boost { namespace geometry
{
@@ -225,7 +226,7 @@ struct get_ring<detail::buffer::buffered_ring_collection_tag>
ring_identifier const& id,
MultiGeometry const& multi_ring)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
id.multi_index >= 0
&& id.multi_index < int(boost::size(multi_ring))
diff --git a/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp b/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
index 6a3daa282e..3425ee6ffd 100644
--- a/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
+++ b/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
@@ -17,6 +17,7 @@
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/algorithms/detail/sections/section_functions.hpp>
+#include <boost/geometry/algorithms/detail/buffer/buffer_policies.hpp>
namespace boost { namespace geometry
@@ -28,6 +29,34 @@ namespace detail { namespace buffer
{
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+struct buffer_assign_turn
+{
+ static bool const include_no_turn = false;
+ static bool const include_degenerate = false;
+ static bool const include_opposite = false;
+
+ template
+ <
+ typename Info,
+ typename Point1,
+ typename Point2,
+ typename IntersectionInfo
+ >
+ static inline void apply(Info& info,
+ Point1 const& /*p1*/,
+ Point2 const& /*p2*/,
+ IntersectionInfo const& iinfo)
+ {
+ info.rob_pi = iinfo.rpi();
+ info.rob_pj = iinfo.rpj();
+ info.rob_qi = iinfo.rqi();
+ info.rob_qj = iinfo.rqj();
+ }
+
+};
+#endif
+
template
<
typename Pieces,
@@ -91,7 +120,7 @@ class piece_turn_visitor
template <std::size_t Dimension, typename Iterator, typename Box>
inline void move_begin_iterator(Iterator& it_begin, Iterator it_beyond,
- int& index, int dir, Box const& other_bounding_box)
+ signed_size_type& index, int dir, Box const& other_bounding_box)
{
for(; it_begin != it_beyond
&& it_begin + 1 != it_beyond
@@ -129,20 +158,20 @@ class piece_turn_visitor
typedef typename boost::range_value<Turns const>::type turn_type;
typedef typename boost::range_iterator<ring_type const>::type iterator;
- int const piece1_first_index = piece1.first_seg_id.segment_index;
- int const piece2_first_index = piece2.first_seg_id.segment_index;
+ signed_size_type const piece1_first_index = piece1.first_seg_id.segment_index;
+ signed_size_type const piece2_first_index = piece2.first_seg_id.segment_index;
if (piece1_first_index < 0 || piece2_first_index < 0)
{
return;
}
// Get indices of part of offsetted_rings for this monotonic section:
- int const sec1_first_index = piece1_first_index + section1.begin_index;
- int const sec2_first_index = piece2_first_index + section2.begin_index;
+ signed_size_type const sec1_first_index = piece1_first_index + section1.begin_index;
+ signed_size_type const sec2_first_index = piece2_first_index + section2.begin_index;
// index of last point in section, beyond-end is one further
- int const sec1_last_index = piece1_first_index + section1.end_index;
- int const sec2_last_index = piece2_first_index + section2.end_index;
+ signed_size_type const sec1_last_index = piece1_first_index + section1.end_index;
+ signed_size_type const sec2_last_index = piece2_first_index + section2.end_index;
// get geometry and iterators over these sections
ring_type const& ring1 = m_rings[piece1.first_seg_id.multi_index];
@@ -154,7 +183,7 @@ class piece_turn_visitor
iterator it2_beyond = boost::begin(ring2) + sec2_last_index + 1;
// Set begin/end of monotonic ranges, in both x/y directions
- int index1 = sec1_first_index;
+ signed_size_type index1 = sec1_first_index;
move_begin_iterator<0>(it1_first, it1_beyond, index1,
section1.directions[0], section2.bounding_box);
move_end_iterator<0>(it1_first, it1_beyond,
@@ -164,7 +193,7 @@ class piece_turn_visitor
move_end_iterator<1>(it1_first, it1_beyond,
section1.directions[1], section2.bounding_box);
- int index2 = sec2_first_index;
+ signed_size_type index2 = sec2_first_index;
move_begin_iterator<0>(it2_first, it2_beyond, index2,
section2.directions[0], section1.bounding_box);
move_end_iterator<0>(it2_first, it2_beyond,
@@ -204,7 +233,11 @@ class piece_turn_visitor
// and iterating in sync with them...
typedef detail::overlay::get_turn_info
<
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ buffer_assign_turn
+#else
detail::overlay::assign_null_policy
+#endif
> turn_policy;
turn_policy::apply(*prev1, *it1, *next1,
diff --git a/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp b/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp
index 8803efdec9..0aca21ce88 100644
--- a/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp
+++ b/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp
@@ -14,6 +14,8 @@
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/arithmetic/dot_product.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/comparable_distance.hpp>
@@ -25,6 +27,11 @@
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/strategies/buffer.hpp>
+#include <boost/geometry/algorithms/detail/buffer/buffer_policies.hpp>
+
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+#include <boost/geometry/strategies/cartesian/side_of_intersection.hpp>
+#endif
namespace boost { namespace geometry
@@ -89,8 +96,10 @@ enum analyse_result
analyse_disjoint,
analyse_within,
analyse_on_original_boundary,
- analyse_on_offsetted,
- analyse_near_offsetted
+ analyse_on_offsetted
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ , analyse_near_offsetted
+#endif
};
template <typename Point>
@@ -112,6 +121,31 @@ inline analyse_result check_segment(Point const& previous,
Point const& current, Turn const& turn,
bool from_monotonic)
{
+
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ typedef geometry::model::referring_segment<Point const> segment_type;
+ segment_type const p(turn.rob_pi, turn.rob_pj);
+ segment_type const q(turn.rob_qi, turn.rob_qj);
+ segment_type const r(previous, current);
+ int const side = strategy::side::side_of_intersection::apply(p, q, r,
+ turn.robust_point);
+
+ if (side == 0)
+ {
+ return analyse_on_offsetted;
+ }
+ if (side == -1 && from_monotonic)
+ {
+ return analyse_within;
+ }
+ if (side == 1 && from_monotonic)
+ {
+ return analyse_disjoint;
+ }
+ return analyse_continue;
+
+#else
+
typedef typename strategy::side::services::default_strategy
<
typename cs_tag<Point>::type
@@ -156,6 +190,7 @@ inline analyse_result check_segment(Point const& previous,
// Not monotonic, on left or right side: continue analysing
return analyse_continue;
+#endif
}
@@ -169,14 +204,22 @@ public :
typedef typename Turn::robust_point_type point_type;
typedef typename geometry::coordinate_type<point_type>::type coordinate_type;
- coordinate_type const point_y = geometry::get<1>(turn.robust_point);
-
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ typedef geometry::model::referring_segment<point_type const> segment_type;
+ segment_type const p(turn.rob_pi, turn.rob_pj);
+ segment_type const q(turn.rob_qi, turn.rob_qj);
+#else
typedef strategy::within::winding<point_type> strategy_type;
typename strategy_type::state_type state;
strategy_type strategy;
boost::ignore_unused(strategy);
-
+#endif
+
+ BOOST_GEOMETRY_ASSERT(! piece.sections.empty());
+
+ coordinate_type const point_y = geometry::get<1>(turn.robust_point);
+
for (std::size_t s = 0; s < piece.sections.size(); s++)
{
section_type const& section = piece.sections[s];
@@ -186,11 +229,43 @@ public :
&& point_y >= geometry::get<min_corner, 1>(section.bounding_box) - 1
&& point_y <= geometry::get<max_corner, 1>(section.bounding_box) + 1)
{
- for (int i = section.begin_index + 1; i <= section.end_index; i++)
+ for (signed_size_type i = section.begin_index + 1; i <= section.end_index; i++)
{
point_type const& previous = piece.robust_ring[i - 1];
point_type const& current = piece.robust_ring[i];
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+
+ // First check if it is in range - if it is not, the
+ // expensive side_of_intersection does not need to be
+ // applied
+ coordinate_type y1 = geometry::get<1>(previous);
+ coordinate_type y2 = geometry::get<1>(current);
+
+ if (y1 > y2)
+ {
+ std::swap(y1, y2);
+ }
+
+ if (point_y >= y1 - 1 && point_y <= y2 + 1)
+ {
+ segment_type const r(previous, current);
+ int const side = strategy::side::side_of_intersection::apply(p, q, r,
+ turn.robust_point);
+
+ // Sections are monotonic in y-dimension
+ if (side == 1)
+ {
+ // Left on segment
+ return analyse_disjoint;
+ }
+ else if (side == 0)
+ {
+ // Collinear - TODO: check if really on segment
+ return analyse_on_offsetted;
+ }
+ }
+#else
analyse_result code = check_segment(previous, current, turn, false);
if (code != analyse_continue)
{
@@ -200,10 +275,15 @@ public :
// Get the state (to determine it is within), we don't have
// to cover the on-segment case (covered above)
strategy.apply(turn.robust_point, previous, current, state);
+#endif
}
}
}
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ // It is nowhere outside, and not on segment, so it is within
+ return analyse_within;
+#else
int const code = strategy.result(state);
if (code == 1)
{
@@ -216,6 +296,7 @@ public :
// Should normally not occur - on-segment is covered
return analyse_unknown;
+#endif
}
};
@@ -228,6 +309,49 @@ class analyse_turn_wrt_piece
bool is_original,
Point const& offsetted)
{
+ boost::ignore_unused(offsetted);
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ typedef geometry::model::referring_segment<Point const> segment_type;
+ segment_type const p(turn.rob_pi, turn.rob_pj);
+ segment_type const q(turn.rob_qi, turn.rob_qj);
+ segment_type const r(s1, s2);
+ int const side = strategy::side::side_of_intersection::apply(p, q, r,
+ turn.robust_point);
+
+ if (side == 1)
+ {
+ // left of segment
+ return analyse_disjoint;
+ }
+ else if (side == 0)
+ {
+ // If is collinear, either on segment or before/after
+ typedef geometry::model::box<Point> box_type;
+
+ box_type box;
+ geometry::assign_inverse(box);
+ geometry::expand(box, s1);
+ geometry::expand(box, s2);
+
+ if (geometry::covered_by(turn.robust_point, box))
+ {
+ // Points on helper-segments are considered as within
+ // Points on original boundary are processed differently
+ return is_original
+ ? analyse_on_original_boundary
+ : analyse_within;
+ }
+
+ // It is collinear but not on the segment. Because these
+ // segments are convex, it is outside
+ // Unless the offsetted ring is collinear or concave w.r.t.
+ // helper-segment but that scenario is not yet supported
+ return analyse_disjoint;
+ }
+
+ // right of segment
+ return analyse_continue;
+#else
typedef typename strategy::side::services::default_strategy
<
typename cs_tag<Point>::type
@@ -276,6 +400,7 @@ class analyse_turn_wrt_piece
// right of segment
return analyse_continue;
+#endif
}
template <typename Turn, typename Piece>
@@ -286,7 +411,8 @@ class analyse_turn_wrt_piece
point_type points[4];
- int helper_count = piece.robust_ring.size() - piece.offsetted_count;
+ signed_size_type helper_count = static_cast<signed_size_type>(piece.robust_ring.size())
+ - piece.offsetted_count;
if (helper_count == 4)
{
for (int i = 0; i < 4; i++)
@@ -436,7 +562,7 @@ public :
// It is small or not monotonic, walk linearly through offset
// TODO: this will be combined with winding strategy
- for (int i = 1; i < piece.offsetted_count; i++)
+ for (signed_size_type i = 1; i < piece.offsetted_count; i++)
{
point_type const& previous = piece.robust_ring[i - 1];
point_type const& current = piece.robust_ring[i];
@@ -492,6 +618,61 @@ class turn_in_piece_visitor
return false;
}
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ // NOTE: this function returns a side value in {-1, 0, 1}
+ template <typename Turn, typename Piece>
+ static inline int turn_in_convex_piece(Turn const& turn,
+ Piece const& piece)
+ {
+ typedef typename Turn::robust_point_type point_type;
+ typedef typename Piece::piece_robust_ring_type ring_type;
+ typedef geometry::model::referring_segment<point_type const> segment;
+
+ segment const p(turn.rob_pi, turn.rob_pj);
+ segment const q(turn.rob_qi, turn.rob_qj);
+
+ typedef typename boost::range_iterator<ring_type const>::type iterator_type;
+ iterator_type it = boost::begin(piece.robust_ring);
+ iterator_type end = boost::end(piece.robust_ring);
+
+ // A robust ring is always closed, and always clockwise
+ for (iterator_type previous = it++; it != end; ++previous, ++it)
+ {
+ geometry::equal_to<point_type> comparator;
+ if (comparator(*previous, *it))
+ {
+ // Points are the same
+ continue;
+ }
+
+ segment r(*previous, *it);
+
+ int const side = strategy::side::side_of_intersection::apply(p, q, r,
+ turn.robust_point);
+
+ if (side == 1)
+ {
+ // IP is left of segment, so it is outside
+ return -1; // outside
+ }
+ else if (side == 0)
+ {
+ // IP is collinear with segment. TODO: we should analyze this further
+ // For now we use the fallback point
+ if (in_box(*previous, *it, turn.robust_point))
+ {
+ return 0;
+ }
+ else
+ {
+ return -1; // outside
+ }
+ }
+ }
+ return 1; // inside
+ }
+#endif
+
public:
@@ -530,12 +711,37 @@ public:
}
// TODO: mutable_piece to make some on-demand preparations in analyse
+ Turn& mutable_turn = m_turns[turn.turn_index];
+
+ if (piece.type == geometry::strategy::buffer::buffered_point)
+ {
+ // Optimization for buffer around points: if distance from center
+ // is not between min/max radius, the result is clear
+ typedef typename default_comparable_distance_result
+ <
+ typename Turn::robust_point_type
+ >::type distance_type;
+
+ distance_type const cd
+ = geometry::comparable_distance(piece.robust_center,
+ turn.robust_point);
+
+ if (cd < piece.robust_min_comparable_radius)
+ {
+ mutable_turn.count_within++;
+ return;
+ }
+ if (cd > piece.robust_max_comparable_radius)
+ {
+ return;
+ }
+ }
+
analyse_result analyse_code =
piece.type == geometry::strategy::buffer::buffered_point
? analyse_turn_wrt_point_piece::apply(turn, piece)
: analyse_turn_wrt_piece::apply(turn, piece);
- Turn& mutable_turn = m_turns[turn.turn_index];
switch(analyse_code)
{
case analyse_disjoint :
@@ -549,16 +755,32 @@ public:
case analyse_within :
mutable_turn.count_within++;
return;
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
case analyse_near_offsetted :
mutable_turn.count_within_near_offsetted++;
return;
+#endif
default :
break;
}
- // TODO: this point_in_geometry is a performance-bottleneck here and
- // will be replaced completely by extending analyse_piece functionality
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ // We don't know (yet)
+ int geometry_code = 0;
+ if (piece.is_convex)
+ {
+ geometry_code = turn_in_convex_piece(turn, piece);
+ }
+ else
+ {
+
+ // TODO: this point_in_geometry is a performance-bottleneck here and
+ // will be replaced completely by extending analyse_piece functionality
+ geometry_code = detail::within::point_in_geometry(turn.robust_point, piece.robust_ring);
+ }
+#else
int geometry_code = detail::within::point_in_geometry(turn.robust_point, piece.robust_ring);
+#endif
if (geometry_code == 1)
{
diff --git a/boost/geometry/algorithms/detail/check_iterator_range.hpp b/boost/geometry/algorithms/detail/check_iterator_range.hpp
index 09ea7f79a0..9bd1d7ae27 100644
--- a/boost/geometry/algorithms/detail/check_iterator_range.hpp
+++ b/boost/geometry/algorithms/detail/check_iterator_range.hpp
@@ -33,7 +33,7 @@ struct check_iterator_range
{
for (InputIterator it = first; it != beyond; ++it)
{
- if ( !Predicate::apply(*it) )
+ if (! Predicate::apply(*it))
{
return false;
}
@@ -54,7 +54,7 @@ struct check_iterator_range
for (InputIterator it = first; it != beyond; ++it)
{
- if ( !predicate.apply(*it) )
+ if (! predicate.apply(*it))
{
return false;
}
diff --git a/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp b/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp
index 04fa9ee86b..4ac5ac6976 100644
--- a/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp
+++ b/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp
@@ -12,8 +12,7 @@
#include <iterator>
-#include <boost/assert.hpp>
-
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/util/math.hpp>
@@ -49,7 +48,7 @@ private:
RangeIterator& it_min,
Distance& dist_min)
{
- BOOST_ASSERT( first != last );
+ BOOST_GEOMETRY_ASSERT( first != last );
Distance const zero = Distance(0);
diff --git a/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp b/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp
index 91be6b0ad0..df67890138 100644
--- a/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp
+++ b/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp
@@ -12,9 +12,9 @@
#include <utility>
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/util/math.hpp>
@@ -51,7 +51,7 @@ protected:
iterator_type& it_min2,
Distance& dist_min)
{
- BOOST_ASSERT( first != last );
+ BOOST_GEOMETRY_ASSERT( first != last );
Distance const zero = Distance(0);
@@ -162,7 +162,7 @@ private:
iterator_type& it_min2,
Distance& dist_min)
{
- BOOST_ASSERT( first != last );
+ BOOST_GEOMETRY_ASSERT( first != last );
base_type::apply(point, first, last, strategy,
it_min1, it_min2, dist_min);
diff --git a/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp b/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp
index ceba59b41a..26b8684828 100644
--- a/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp
+++ b/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp
@@ -15,8 +15,7 @@
#include <iterator>
#include <utility>
-#include <boost/assert.hpp>
-
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
@@ -56,8 +55,8 @@ private:
{
typedef index::rtree<RTreeValueType, index::linear<8> > rtree_type;
- BOOST_ASSERT( rtree_first != rtree_last );
- BOOST_ASSERT( queries_first != queries_last );
+ BOOST_GEOMETRY_ASSERT( rtree_first != rtree_last );
+ BOOST_GEOMETRY_ASSERT( queries_first != queries_last );
Distance const zero = Distance(0);
dist_min = zero;
@@ -73,13 +72,13 @@ private:
{
std::size_t n = rt.query(index::nearest(*qit, 1), &t_v);
- BOOST_ASSERT( n > 0 );
- // n above is unused outside BOOST_ASSERT, hence the call
- // to boost::ignore_unused below
+ BOOST_GEOMETRY_ASSERT( n > 0 );
+ // n above is unused outside BOOST_GEOMETRY_ASSERT,
+ // hence the call to boost::ignore_unused below
//
// however, t_v (initialized by the call to rt.query(...))
// is used below, which is why we cannot put the call to
- // rt.query(...) inside BOOST_ASSERT
+ // rt.query(...) inside BOOST_GEOMETRY_ASSERT
boost::ignore_unused(n);
Distance dist = dispatch::distance
diff --git a/boost/geometry/algorithms/detail/comparable_distance/interface.hpp b/boost/geometry/algorithms/detail/comparable_distance/interface.hpp
index c443a54e58..86eec4c036 100644
--- a/boost/geometry/algorithms/detail/comparable_distance/interface.hpp
+++ b/boost/geometry/algorithms/detail/comparable_distance/interface.hpp
@@ -164,7 +164,7 @@ struct comparable_distance
Geometry2 const& geometry2,
Strategy const& strategy)
{
- return apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
+ return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
}
};
@@ -225,7 +225,7 @@ struct comparable_distance
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
Strategy const& strategy)
{
- return apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
+ return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
}
};
@@ -287,7 +287,7 @@ struct comparable_distance
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
Strategy const& strategy)
{
- return apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
+ return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
}
};
@@ -353,7 +353,7 @@ comparable_distance(Geometry1 const& geometry1, Geometry2 const& geometry2)
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
- return comparable_distance(geometry1, geometry2, default_strategy());
+ return geometry::comparable_distance(geometry1, geometry2, default_strategy());
}
diff --git a/boost/geometry/algorithms/detail/disjoint/interface.hpp b/boost/geometry/algorithms/detail/disjoint/interface.hpp
index 96d6881296..18c010731e 100644
--- a/boost/geometry/algorithms/detail/disjoint/interface.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/interface.hpp
@@ -175,7 +175,7 @@ struct disjoint<
*/
template <typename Geometry1, typename Geometry2>
inline bool disjoint(Geometry1 const& geometry1,
- Geometry2 const& geometry2)
+ Geometry2 const& geometry2)
{
return resolve_variant::disjoint<Geometry1, Geometry2>::apply(geometry1, geometry2);
}
diff --git a/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp b/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp
index 7d1bb05242..29e438e546 100644
--- a/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -13,10 +13,20 @@
#include <algorithm>
#include <vector>
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/box.hpp>
+
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
@@ -33,7 +43,8 @@ namespace boost { namespace geometry
namespace detail { namespace disjoint
{
-template<typename MultiPoint1, typename MultiPoint2>
+
+template <typename MultiPoint1, typename MultiPoint2>
class multipoint_multipoint
{
private:
@@ -66,7 +77,7 @@ public:
static inline bool apply(MultiPoint1 const& multipoint1,
MultiPoint2 const& multipoint2)
{
- BOOST_ASSERT( boost::size(multipoint1) <= boost::size(multipoint2) );
+ BOOST_GEOMETRY_ASSERT( boost::size(multipoint1) <= boost::size(multipoint2) );
typedef typename boost::range_value<MultiPoint1>::type point1_type;
@@ -90,6 +101,98 @@ public:
};
+template <typename MultiPoint, typename Linear>
+class multipoint_linear
+{
+private:
+ // structs for partition -- start
+ struct expand_box
+ {
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& total, Geometry const& geometry)
+ {
+ geometry::expand(total, geometry::return_envelope<Box>(geometry));
+ }
+
+ };
+
+ struct overlaps_box
+ {
+ template <typename Box, typename Geometry>
+ static inline bool apply(Box const& box, Geometry const& geometry)
+ {
+ return ! dispatch::disjoint<Geometry, Box>::apply(geometry, box);
+ }
+ };
+
+ class item_visitor_type
+ {
+ public:
+ item_visitor_type() : m_intersection_found(false) {}
+
+ template <typename Item1, typename Item2>
+ inline void apply(Item1 const& item1, Item2 const& item2)
+ {
+ if (! m_intersection_found
+ && ! dispatch::disjoint<Item1, Item2>::apply(item1, item2))
+ {
+ m_intersection_found = true;
+ }
+ }
+
+ inline bool intersection_found() const { return m_intersection_found; }
+
+ private:
+ bool m_intersection_found;
+ };
+ // structs for partition -- end
+
+ class segment_range
+ {
+ public:
+ typedef geometry::segment_iterator<Linear const> const_iterator;
+ typedef const_iterator iterator;
+
+ segment_range(Linear const& linear)
+ : m_linear(linear)
+ {}
+
+ const_iterator begin() const
+ {
+ return geometry::segments_begin(m_linear);
+ }
+
+ const_iterator end() const
+ {
+ return geometry::segments_end(m_linear);
+ }
+
+ private:
+ Linear const& m_linear;
+ };
+
+public:
+ static inline bool apply(MultiPoint const& multipoint, Linear const& linear)
+ {
+ item_visitor_type visitor;
+
+ geometry::partition
+ <
+ geometry::model::box<typename point_type<MultiPoint>::type>,
+ expand_box,
+ overlaps_box
+ >::apply(multipoint, segment_range(linear), visitor);
+
+ return ! visitor.intersection_found();
+ }
+
+ static inline bool apply(Linear const& linear, MultiPoint const& multipoint)
+ {
+ return apply(multipoint, linear);
+ }
+};
+
+
}} // namespace detail::disjoint
#endif // DOXYGEN_NO_DETAIL
@@ -101,7 +204,7 @@ namespace dispatch
{
-template<typename Point, typename MultiPoint, std::size_t DimensionCount>
+template <typename Point, typename MultiPoint, std::size_t DimensionCount>
struct disjoint
<
Point, MultiPoint, DimensionCount, point_tag, multi_point_tag, false
@@ -109,7 +212,7 @@ struct disjoint
{};
-template<typename MultiPoint, typename Segment, std::size_t DimensionCount>
+template <typename MultiPoint, typename Segment, std::size_t DimensionCount>
struct disjoint
<
MultiPoint, Segment, DimensionCount, multi_point_tag, segment_tag, false
@@ -117,7 +220,7 @@ struct disjoint
{};
-template<typename MultiPoint, typename Box, std::size_t DimensionCount>
+template <typename MultiPoint, typename Box, std::size_t DimensionCount>
struct disjoint
<
MultiPoint, Box, DimensionCount, multi_point_tag, box_tag, false
@@ -125,7 +228,12 @@ struct disjoint
{};
-template<typename MultiPoint1, typename MultiPoint2, std::size_t DimensionCount>
+template
+<
+ typename MultiPoint1,
+ typename MultiPoint2,
+ std::size_t DimensionCount
+>
struct disjoint
<
MultiPoint1, MultiPoint2, DimensionCount,
@@ -151,6 +259,22 @@ struct disjoint
};
+template <typename Linear, typename MultiPoint, std::size_t DimensionCount>
+struct disjoint
+ <
+ Linear, MultiPoint, DimensionCount, linear_tag, multi_point_tag, false
+ > : detail::disjoint::multipoint_linear<MultiPoint, Linear>
+{};
+
+
+template <typename MultiPoint, typename Linear, std::size_t DimensionCount>
+struct disjoint
+ <
+ MultiPoint, Linear, DimensionCount, multi_point_tag, linear_tag, false
+ > : detail::disjoint::multipoint_linear<MultiPoint, Linear>
+{};
+
+
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
diff --git a/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp b/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp
index a58bff41da..9ae43f73d0 100644
--- a/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp
@@ -1,12 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2014.
-// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -21,8 +21,6 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_POINT_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_POINT_GEOMETRY_HPP
-#include <boost/geometry/geometries/segment.hpp>
-
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
@@ -39,24 +37,13 @@ namespace detail { namespace disjoint
{
-template<typename Point, typename Geometry>
-struct disjoint_point_linear
-{
- static inline
- bool apply(Point const& pt, Geometry const& g)
- {
- return !geometry::covered_by(pt, g);
- }
-};
-
-
-template <typename Geometry1, typename Geometry2>
struct reverse_covered_by
{
+ template <typename Geometry1, typename Geometry2>
static inline
bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
- return !geometry::covered_by(geometry1, geometry2);
+ return ! geometry::covered_by(geometry1, geometry2);
}
};
@@ -74,30 +61,20 @@ namespace dispatch
template<typename Point, typename Linear, std::size_t DimensionCount>
struct disjoint<Point, Linear, DimensionCount, point_tag, linear_tag, false>
- : public detail::disjoint::disjoint_point_linear<Point, Linear>
+ : detail::disjoint::reverse_covered_by
{};
template <typename Point, typename Areal, std::size_t DimensionCount>
struct disjoint<Point, Areal, DimensionCount, point_tag, areal_tag, false>
- : detail::disjoint::reverse_covered_by<Point, Areal>
+ : detail::disjoint::reverse_covered_by
{};
template<typename Point, typename Segment, std::size_t DimensionCount>
struct disjoint<Point, Segment, DimensionCount, point_tag, segment_tag, false>
-{
- static inline bool apply(Point const& point, Segment const& segment)
- {
- typedef geometry::model::referring_segment<Point const> other_segment;
-
- other_segment other(point, point);
- return detail::disjoint::disjoint_segment
- <
- Segment, other_segment
- >::apply(segment, other);
- }
-};
+ : detail::disjoint::reverse_covered_by
+{};
} // namespace dispatch
diff --git a/boost/geometry/algorithms/detail/disjoint/point_point.hpp b/boost/geometry/algorithms/detail/disjoint/point_point.hpp
index b1d32bf95e..7580b7287b 100644
--- a/boost/geometry/algorithms/detail/disjoint/point_point.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/point_point.hpp
@@ -1,12 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
-// This file was modified by Oracle on 2013-2014.
-// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -23,11 +23,26 @@
#include <cstddef>
+#include <boost/type_traits/is_same.hpp>
+
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+#include <boost/geometry/strategies/strategy_transform.hpp>
+
+#include <boost/geometry/geometries/helper_geometry.hpp>
+
+#include <boost/geometry/algorithms/transform.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
@@ -40,38 +55,146 @@ namespace boost { namespace geometry
namespace detail { namespace disjoint
{
-template
-<
- typename Point1, typename Point2,
- std::size_t Dimension, std::size_t DimensionCount
->
-struct point_point
+
+template <std::size_t Dimension, std::size_t DimensionCount>
+struct point_point_generic
{
+ template <typename Point1, typename Point2>
static inline bool apply(Point1 const& p1, Point2 const& p2)
{
if (! geometry::math::equals(get<Dimension>(p1), get<Dimension>(p2)))
{
return true;
}
- return point_point
- <
- Point1, Point2,
- Dimension + 1, DimensionCount
- >::apply(p1, p2);
+ return
+ point_point_generic<Dimension + 1, DimensionCount>::apply(p1, p2);
}
};
-
-template <typename Point1, typename Point2, std::size_t DimensionCount>
-struct point_point<Point1, Point2, DimensionCount, DimensionCount>
+template <std::size_t DimensionCount>
+struct point_point_generic<DimensionCount, DimensionCount>
{
- static inline bool apply(Point1 const& , Point2 const& )
+ template <typename Point1, typename Point2>
+ static inline bool apply(Point1 const&, Point2 const&)
{
return false;
}
};
+class point_point_on_spheroid
+{
+private:
+ template <typename Point1, typename Point2, bool SameUnits>
+ struct are_same_points
+ {
+ static inline bool apply(Point1 const& point1, Point2 const& point2)
+ {
+ typedef typename helper_geometry<Point1>::type helper_point_type1;
+ typedef typename helper_geometry<Point2>::type helper_point_type2;
+
+ helper_point_type1 point1_normalized
+ = return_normalized<helper_point_type1>(point1);
+ helper_point_type2 point2_normalized
+ = return_normalized<helper_point_type2>(point2);
+
+ return point_point_generic
+ <
+ 0, dimension<Point1>::value
+ >::apply(point1_normalized, point2_normalized);
+ }
+ };
+
+ template <typename Point1, typename Point2>
+ struct are_same_points<Point1, Point2, false> // points have different units
+ {
+ static inline bool apply(Point1 const& point1, Point2 const& point2)
+ {
+ typedef typename geometry::select_most_precise
+ <
+ typename fp_coordinate_type<Point1>::type,
+ typename fp_coordinate_type<Point2>::type
+ >::type calculation_type;
+
+ typename helper_geometry
+ <
+ Point1, calculation_type, radian
+ >::type helper_point1, helper_point2;
+
+ Point1 point1_normalized = return_normalized<Point1>(point1);
+ Point2 point2_normalized = return_normalized<Point2>(point2);
+
+ geometry::transform(point1_normalized, helper_point1);
+ geometry::transform(point2_normalized, helper_point2);
+
+ return point_point_generic
+ <
+ 0, dimension<Point1>::value
+ >::apply(helper_point1, helper_point2);
+ }
+ };
+
+public:
+ template <typename Point1, typename Point2>
+ static inline bool apply(Point1 const& point1, Point2 const& point2)
+ {
+ return are_same_points
+ <
+ Point1,
+ Point2,
+ boost::is_same
+ <
+ typename coordinate_system<Point1>::type::units,
+ typename coordinate_system<Point2>::type::units
+ >::value
+ >::apply(point1, point2);
+ }
+};
+
+
+template
+<
+ typename Point1, typename Point2,
+ std::size_t Dimension, std::size_t DimensionCount,
+ typename CSTag1 = typename cs_tag<Point1>::type,
+ typename CSTag2 = CSTag1
+>
+struct point_point
+ : point_point<Point1, Point2, Dimension, DimensionCount, cartesian_tag>
+{};
+
+template
+<
+ typename Point1, typename Point2,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_point
+ <
+ Point1, Point2, Dimension, DimensionCount, spherical_equatorial_tag
+ > : point_point_on_spheroid
+{};
+
+template
+<
+ typename Point1, typename Point2,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_point
+ <
+ Point1, Point2, Dimension, DimensionCount, geographic_tag
+ > : point_point_on_spheroid
+{};
+
+template
+<
+ typename Point1, typename Point2,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_point<Point1, Point2, Dimension, DimensionCount, cartesian_tag>
+ : point_point_generic<Dimension, DimensionCount>
+{};
+
+
/*!
\brief Internal utility function to detect of points are disjoint
\note To avoid circular references
diff --git a/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp b/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp
index 57257dbdcc..d6de7cac91 100644
--- a/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp
+++ b/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp
@@ -185,10 +185,10 @@ public:
Geometry const
> segment_iterator_type;
- typedef typename std::vector
+ typedef typename boost::range_const_iterator
<
- segment_or_box_point
- >::const_iterator seg_or_box_iterator_type;
+ std::vector<segment_or_box_point>
+ >::type seg_or_box_const_iterator;
typedef assign_new_min_iterator<SegmentOrBox> assign_new_value;
@@ -219,8 +219,9 @@ public:
// segment or box
comparable_return_type cd_min1(0);
point_iterator_type pit_min;
- seg_or_box_iterator_type it_min1 = seg_or_box_points.begin();
- seg_or_box_iterator_type it_min2 = ++seg_or_box_points.begin();
+ seg_or_box_const_iterator it_min1 = boost::const_begin(seg_or_box_points);
+ seg_or_box_const_iterator it_min2 = it_min1;
+ ++it_min2;
bool first = true;
for (point_iterator_type pit = points_begin(geometry);
@@ -229,11 +230,11 @@ public:
comparable_return_type cd;
std::pair
<
- seg_or_box_iterator_type, seg_or_box_iterator_type
+ seg_or_box_const_iterator, seg_or_box_const_iterator
> it_pair
= point_to_point_range::apply(*pit,
- seg_or_box_points.begin(),
- seg_or_box_points.end(),
+ boost::const_begin(seg_or_box_points),
+ boost::const_end(seg_or_box_points),
cstrategy,
cd);
@@ -250,12 +251,11 @@ public:
// segments of the geometry
comparable_return_type cd_min2(0);
segment_iterator_type sit_min;
- typename std::vector<segment_or_box_point>::const_iterator it_min;
+ seg_or_box_const_iterator it_min;
first = true;
- for (typename std::vector<segment_or_box_point>::const_iterator it
- = seg_or_box_points.begin();
- it != seg_or_box_points.end(); ++it, first = false)
+ for (seg_or_box_const_iterator it = boost::const_begin(seg_or_box_points);
+ it != boost::const_end(seg_or_box_points); ++it, first = false)
{
comparable_return_type cd;
segment_iterator_type sit
diff --git a/boost/geometry/algorithms/detail/distance/interface.hpp b/boost/geometry/algorithms/detail/distance/interface.hpp
index fa8cbd69ee..1e7cc433ef 100644
--- a/boost/geometry/algorithms/detail/distance/interface.hpp
+++ b/boost/geometry/algorithms/detail/distance/interface.hpp
@@ -198,7 +198,7 @@ struct distance<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Geometry2 const& geometry2,
Strategy const& strategy)
{
- return apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
+ return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
}
};
@@ -253,7 +253,7 @@ struct distance<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2,
Strategy const& strategy)
{
- return apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
+ return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
}
};
@@ -312,7 +312,7 @@ struct distance
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
Strategy const& strategy)
{
- return apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
+ return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
}
};
@@ -395,7 +395,7 @@ distance(Geometry1 const& geometry1,
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
- return distance(geometry1, geometry2, default_strategy());
+ return geometry::distance(geometry1, geometry2, default_strategy());
}
}} // namespace boost::geometry
diff --git a/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp b/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp
index 78189794a1..6e78bee694 100644
--- a/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp
+++ b/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp
@@ -13,8 +13,7 @@
#include <iterator>
#include <utility>
-#include <boost/assert.hpp>
-
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/iterators/has_one_element.hpp>
@@ -70,7 +69,7 @@ public:
{
namespace sds = strategy::distance::services;
- BOOST_ASSERT( first != last );
+ BOOST_GEOMETRY_ASSERT( first != last );
if ( geometry::has_one_element(first, last) )
{
diff --git a/boost/geometry/algorithms/detail/distance/segment_to_box.hpp b/boost/geometry/algorithms/detail/distance/segment_to_box.hpp
index 79d9adb703..783699ee0a 100644
--- a/boost/geometry/algorithms/detail/distance/segment_to_box.hpp
+++ b/boost/geometry/algorithms/detail/distance/segment_to_box.hpp
@@ -15,13 +15,13 @@
#include <functional>
#include <vector>
-#include <boost/assert.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/mpl/if.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/point_type.hpp>
@@ -561,7 +561,7 @@ private:
typedef compare_less_equal<ReturnType, true> less_equal;
// assert that the segment has non-negative slope
- BOOST_ASSERT( ( math::equals(geometry::get<0>(p0), geometry::get<0>(p1))
+ BOOST_GEOMETRY_ASSERT( ( math::equals(geometry::get<0>(p0), geometry::get<0>(p1))
&& geometry::get<1>(p0) < geometry::get<1>(p1))
||
( geometry::get<0>(p0) < geometry::get<0>(p1)
@@ -617,7 +617,7 @@ private:
typedef compare_less_equal<ReturnType, false> greater_equal;
// assert that the segment has negative slope
- BOOST_ASSERT( geometry::get<0>(p0) < geometry::get<0>(p1)
+ BOOST_GEOMETRY_ASSERT( geometry::get<0>(p0) < geometry::get<0>(p1)
&& geometry::get<1>(p0) > geometry::get<1>(p1) );
ReturnType result(0);
@@ -665,7 +665,7 @@ public:
PPStrategy const& pp_strategy,
PSStrategy const& ps_strategy)
{
- BOOST_ASSERT( geometry::less<SegmentPoint>()(p0, p1) );
+ BOOST_GEOMETRY_ASSERT( geometry::less<SegmentPoint>()(p0, p1) );
if (geometry::get<0>(p0) < geometry::get<0>(p1)
&& geometry::get<1>(p0) > geometry::get<1>(p1))
diff --git a/boost/geometry/algorithms/detail/envelope/box.hpp b/boost/geometry/algorithms/detail/envelope/box.hpp
new file mode 100644
index 0000000000..3790262948
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/box.hpp
@@ -0,0 +1,167 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/views/detail/indexed_point_view.hpp>
+
+#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+template
+<
+ std::size_t Index,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct envelope_indexed_box
+{
+ template <typename BoxIn, typename BoxOut>
+ static inline void apply(BoxIn const& box_in, BoxOut& mbr)
+ {
+ detail::indexed_point_view<BoxIn const, Index> box_in_corner(box_in);
+ detail::indexed_point_view<BoxOut, Index> mbr_corner(mbr);
+
+ detail::conversion::point_to_point
+ <
+ detail::indexed_point_view<BoxIn const, Index>,
+ detail::indexed_point_view<BoxOut, Index>,
+ Dimension,
+ DimensionCount
+ >::apply(box_in_corner, mbr_corner);
+ }
+};
+
+template
+<
+ std::size_t Index,
+ std::size_t DimensionCount
+>
+struct envelope_indexed_box_on_spheroid
+{
+ template <typename BoxIn, typename BoxOut>
+ static inline void apply(BoxIn const& box_in, BoxOut& mbr)
+ {
+ // transform() does not work with boxes of dimension higher
+ // than 2; to account for such boxes we transform the min/max
+ // points of the boxes using the indexed_point_view
+ detail::indexed_point_view<BoxIn const, Index> box_in_corner(box_in);
+ detail::indexed_point_view<BoxOut, Index> mbr_corner(mbr);
+
+ // first transform the units
+ transform_units(box_in_corner, mbr_corner);
+
+ // now transform the remaining coordinates
+ detail::conversion::point_to_point
+ <
+ detail::indexed_point_view<BoxIn const, Index>,
+ detail::indexed_point_view<BoxOut, Index>,
+ 2,
+ DimensionCount
+ >::apply(box_in_corner, mbr_corner);
+ }
+};
+
+
+struct envelope_box
+{
+ template<typename BoxIn, typename BoxOut>
+ static inline void apply(BoxIn const& box_in, BoxOut& mbr)
+ {
+ envelope_indexed_box
+ <
+ min_corner, 0, dimension<BoxIn>::value
+ >::apply(box_in, mbr);
+
+ envelope_indexed_box
+ <
+ max_corner, 0, dimension<BoxIn>::value
+ >::apply(box_in, mbr);
+ }
+};
+
+
+struct envelope_box_on_spheroid
+{
+ template <typename BoxIn, typename BoxOut>
+ static inline void apply(BoxIn const& box_in, BoxOut& mbr)
+ {
+ BoxIn box_in_normalized = detail::return_normalized<BoxIn>(box_in);
+
+ envelope_indexed_box_on_spheroid
+ <
+ min_corner, dimension<BoxIn>::value
+ >::apply(box_in_normalized, mbr);
+
+ envelope_indexed_box_on_spheroid
+ <
+ max_corner, dimension<BoxIn>::value
+ >::apply(box_in_normalized, mbr);
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Box, typename CS_Tag>
+struct envelope<Box, box_tag, CS_Tag>
+ : detail::envelope::envelope_box
+{};
+
+
+template <typename Box>
+struct envelope<Box, box_tag, spherical_equatorial_tag>
+ : detail::envelope::envelope_box_on_spheroid
+{};
+
+
+template <typename Box>
+struct envelope<Box, box_tag, geographic_tag>
+ : detail::envelope::envelope_box_on_spheroid
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/implementation.hpp b/boost/geometry/algorithms/detail/envelope/implementation.hpp
new file mode 100644
index 0000000000..c1dbf8e589
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/implementation.hpp
@@ -0,0 +1,106 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_IMPLEMENTATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_IMPLEMENTATION_HPP
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/is_empty.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/box.hpp>
+#include <boost/geometry/algorithms/detail/envelope/linear.hpp>
+#include <boost/geometry/algorithms/detail/envelope/multipoint.hpp>
+#include <boost/geometry/algorithms/detail/envelope/point.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range.hpp>
+#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+struct envelope_polygon
+{
+ template <typename Polygon, typename Box>
+ static inline void apply(Polygon const& polygon, Box& mbr)
+ {
+ typename ring_return_type<Polygon const>::type ext_ring
+ = exterior_ring(polygon);
+
+ if (geometry::is_empty(ext_ring))
+ {
+ // if the exterior ring is empty, consider the interior rings
+ envelope_multi_range
+ <
+ envelope_range
+ >::apply(interior_rings(polygon), mbr);
+ }
+ else
+ {
+ // otherwise, consider only the exterior ring
+ envelope_range::apply(ext_ring, mbr);
+ }
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Ring>
+struct envelope<Ring, ring_tag>
+ : detail::envelope::envelope_range
+{};
+
+
+template <typename Polygon>
+struct envelope<Polygon, polygon_tag>
+ : detail::envelope::envelope_polygon
+{};
+
+
+template <typename MultiPolygon>
+struct envelope<MultiPolygon, multi_polygon_tag>
+ : detail::envelope::envelope_multi_range
+ <
+ detail::envelope::envelope_polygon
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_IMPLEMENTATION_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/initialize.hpp b/boost/geometry/algorithms/detail/envelope/initialize.hpp
new file mode 100644
index 0000000000..d8e252b53a
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/initialize.hpp
@@ -0,0 +1,86 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INITIALIZE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INITIALIZE_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/bounds.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+template <std::size_t Dimension, std::size_t DimensionCount>
+struct initialize_loop
+{
+ template <typename Box, typename CoordinateType>
+ static inline void apply(Box& box,
+ CoordinateType min_value,
+ CoordinateType max_value)
+ {
+ geometry::set<min_corner, Dimension>(box, min_value);
+ geometry::set<max_corner, Dimension>(box, max_value);
+
+ initialize_loop
+ <
+ Dimension + 1, DimensionCount
+ >::apply(box, min_value, max_value);
+ }
+};
+
+template <std::size_t DimensionCount>
+struct initialize_loop<DimensionCount, DimensionCount>
+{
+ template <typename Box, typename CoordinateType>
+ static inline void apply(Box&, CoordinateType, CoordinateType)
+ {
+ }
+};
+
+
+template
+<
+ typename Box,
+ std::size_t Dimension = 0,
+ std::size_t DimensionCount = dimension<Box>::value
+>
+struct initialize
+{
+ typedef typename coordinate_type<Box>::type coordinate_type;
+
+ static inline void apply(Box& box,
+ coordinate_type min_value
+ = boost::numeric::bounds<coordinate_type>::highest(),
+ coordinate_type max_value
+ = boost::numeric::bounds<coordinate_type>::lowest())
+ {
+ initialize_loop
+ <
+ Dimension, DimensionCount
+ >::apply(box, min_value, max_value);
+ }
+};
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INITIALIZE_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/interface.hpp b/boost/geometry/algorithms/detail/envelope/interface.hpp
new file mode 100644
index 0000000000..997ac1b23e
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/interface.hpp
@@ -0,0 +1,126 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP
+
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace resolve_variant
+{
+
+template <typename Geometry>
+struct envelope
+{
+ template <typename Box>
+ static inline void apply(Geometry const& geometry, Box& box)
+ {
+ concept::check<Geometry const>();
+ concept::check<Box>();
+
+ dispatch::envelope<Geometry>::apply(geometry, box);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Box>
+ struct visitor: boost::static_visitor<void>
+ {
+ Box& m_box;
+
+ visitor(Box& box): m_box(box) {}
+
+ template <typename Geometry>
+ void operator()(Geometry const& geometry) const
+ {
+ envelope<Geometry>::apply(geometry, m_box);
+ }
+ };
+
+ template <typename Box>
+ static inline void
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
+ Box& box)
+ {
+ boost::apply_visitor(visitor<Box>(box), geometry);
+ }
+};
+
+} // namespace resolve_variant
+
+
+/*!
+\brief \brief_calc{envelope}
+\ingroup envelope
+\details \details_calc{envelope,\det_envelope}.
+\tparam Geometry \tparam_geometry
+\tparam Box \tparam_box
+\param geometry \param_geometry
+\param mbr \param_box \param_set{envelope}
+
+\qbk{[include reference/algorithms/envelope.qbk]}
+\qbk{
+[heading Example]
+[envelope] [envelope_output]
+}
+*/
+template<typename Geometry, typename Box>
+inline void envelope(Geometry const& geometry, Box& mbr)
+{
+ resolve_variant::envelope<Geometry>::apply(geometry, mbr);
+}
+
+
+/*!
+\brief \brief_calc{envelope}
+\ingroup envelope
+\details \details_calc{return_envelope,\det_envelope}. \details_return{envelope}
+\tparam Box \tparam_box
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\return \return_calc{envelope}
+
+\qbk{[include reference/algorithms/envelope.qbk]}
+\qbk{
+[heading Example]
+[return_envelope] [return_envelope_output]
+}
+*/
+template<typename Box, typename Geometry>
+inline Box return_envelope(Geometry const& geometry)
+{
+ Box mbr;
+ resolve_variant::envelope<Geometry>::apply(geometry, mbr);
+ return mbr;
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/intersects_antimeridian.hpp b/boost/geometry/algorithms/detail/envelope/intersects_antimeridian.hpp
new file mode 100644
index 0000000000..47937bf740
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/intersects_antimeridian.hpp
@@ -0,0 +1,78 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERSECTS_ANTIMERIDIAN_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERSECTS_ANTIMERIDIAN_HPP
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace detail { namespace envelope
+{
+
+
+struct intersects_antimeridian
+{
+ template <typename Units, typename CoordinateType>
+ static inline bool apply(CoordinateType const& lon1,
+ CoordinateType const& lat1,
+ CoordinateType const& lon2,
+ CoordinateType const& lat2)
+ {
+ typedef math::detail::constants_on_spheroid
+ <
+ CoordinateType, Units
+ > constants;
+
+ return
+ math::equals(math::abs(lat1), constants::max_latitude())
+ ||
+ math::equals(math::abs(lat2), constants::max_latitude())
+ ||
+ math::larger(math::abs(lon1 - lon2), constants::half_period());
+ }
+
+ template <typename Segment>
+ static inline bool apply(Segment const& segment)
+ {
+ return apply(detail::indexed_point_view<Segment, 0>(segment),
+ detail::indexed_point_view<Segment, 1>(segment));
+ }
+
+ template <typename Point>
+ static inline bool apply(Point const& p1, Point const& p2)
+ {
+ Point p1_normalized = detail::return_normalized<Point>(p1);
+ Point p2_normalized = detail::return_normalized<Point>(p2);
+
+ return apply
+ <
+ typename coordinate_system<Point>::type::units
+ >(geometry::get<0>(p1_normalized),
+ geometry::get<1>(p1_normalized),
+ geometry::get<0>(p2_normalized),
+ geometry::get<1>(p2_normalized));
+ }
+};
+
+
+}} // namespace detail::envelope
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERSECTS_ANTIMERIDIAN_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/linear.hpp b/boost/geometry/algorithms/detail/envelope/linear.hpp
new file mode 100644
index 0000000000..49c3cf3135
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/linear.hpp
@@ -0,0 +1,96 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINEAR_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINEAR_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/range.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+struct envelope_linestring_on_spheroid
+{
+ template <typename Linestring, typename Box>
+ static inline void apply(Linestring const& linestring, Box& mbr)
+ {
+ envelope_range::apply(geometry::segments_begin(linestring),
+ geometry::segments_end(linestring),
+ mbr);
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Linestring, typename CS_Tag>
+struct envelope<Linestring, linestring_tag, CS_Tag>
+ : detail::envelope::envelope_range
+{};
+
+template <typename Linestring>
+struct envelope<Linestring, linestring_tag, spherical_equatorial_tag>
+ : detail::envelope::envelope_linestring_on_spheroid
+{};
+
+
+template <typename MultiLinestring, typename CS_Tag>
+struct envelope
+ <
+ MultiLinestring, multi_linestring_tag, CS_Tag
+ > : detail::envelope::envelope_multi_range
+ <
+ detail::envelope::envelope_range
+ >
+{};
+
+template <typename MultiLinestring>
+struct envelope
+ <
+ MultiLinestring, multi_linestring_tag, spherical_equatorial_tag
+ > : detail::envelope::envelope_multi_range_on_spheroid
+ <
+ detail::envelope::envelope_linestring_on_spheroid
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINEAR_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/multipoint.hpp b/boost/geometry/algorithms/detail/envelope/multipoint.hpp
new file mode 100644
index 0000000000..210debfdba
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/multipoint.hpp
@@ -0,0 +1,378 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
+
+#include <cstddef>
+#include <algorithm>
+#include <utility>
+#include <vector>
+
+#include <boost/algorithm/minmax_element.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/range.hpp>
+
+#include <boost/geometry/geometries/helper_geometry.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/box.hpp>
+#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range.hpp>
+#include <boost/geometry/algorithms/detail/expand/point.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+class envelope_multipoint_on_spheroid
+{
+private:
+ template <std::size_t Dim>
+ struct coordinate_less
+ {
+ template <typename Point>
+ inline bool operator()(Point const& point1, Point const& point2) const
+ {
+ return math::smaller(geometry::get<Dim>(point1),
+ geometry::get<Dim>(point2));
+ }
+ };
+
+ template <typename Constants, typename MultiPoint, typename OutputIterator>
+ static inline void analyze_point_coordinates(MultiPoint const& multipoint,
+ bool& has_south_pole,
+ bool& has_north_pole,
+ OutputIterator oit)
+ {
+ typedef typename boost::range_value<MultiPoint>::type point_type;
+ typedef typename boost::range_iterator
+ <
+ MultiPoint const
+ >::type iterator_type;
+
+ // analyze point coordinates:
+ // (1) normalize point coordinates
+ // (2) check if any point is the north or the south pole
+ // (3) put all non-pole points in a container
+ //
+ // notice that at this point in the algorithm, we have at
+ // least two points on the spheroid
+ has_south_pole = false;
+ has_north_pole = false;
+
+ for (iterator_type it = boost::begin(multipoint);
+ it != boost::end(multipoint);
+ ++it)
+ {
+ point_type point = detail::return_normalized<point_type>(*it);
+
+ if (math::equals(geometry::get<1>(point),
+ Constants::min_latitude()))
+ {
+ has_south_pole = true;
+ }
+ else if (math::equals(geometry::get<1>(point),
+ Constants::max_latitude()))
+ {
+ has_north_pole = true;
+ }
+ else
+ {
+ *oit++ = point;
+ }
+ }
+ }
+
+ template <typename SortedRange, typename Value>
+ static inline Value maximum_gap(SortedRange const& sorted_range,
+ Value& max_gap_left,
+ Value& max_gap_right)
+ {
+ typedef typename boost::range_iterator
+ <
+ SortedRange const
+ >::type iterator_type;
+
+ iterator_type it1 = boost::begin(sorted_range), it2 = it1;
+ ++it2;
+ max_gap_left = geometry::get<0>(*it1);
+ max_gap_right = geometry::get<0>(*it2);
+
+ Value max_gap = max_gap_right - max_gap_left;
+ for (++it1, ++it2; it2 != boost::end(sorted_range); ++it1, ++it2)
+ {
+ Value gap = geometry::get<0>(*it2) - geometry::get<0>(*it1);
+ if (math::larger(gap, max_gap))
+ {
+ max_gap_left = geometry::get<0>(*it1);
+ max_gap_right = geometry::get<0>(*it2);
+ max_gap = gap;
+ }
+ }
+
+ return max_gap;
+ }
+
+ template
+ <
+ typename Constants,
+ typename PointRange,
+ typename LongitudeLess,
+ typename CoordinateType
+ >
+ static inline void get_min_max_longitudes(PointRange& range,
+ LongitudeLess const& lon_less,
+ CoordinateType& lon_min,
+ CoordinateType& lon_max)
+ {
+ typedef typename boost::range_iterator
+ <
+ PointRange const
+ >::type iterator_type;
+
+ // compute min and max longitude values
+ std::pair<iterator_type, iterator_type> min_max_longitudes
+ = boost::minmax_element(boost::begin(range),
+ boost::end(range),
+ lon_less);
+
+ lon_min = geometry::get<0>(*min_max_longitudes.first);
+ lon_max = geometry::get<0>(*min_max_longitudes.second);
+
+ // if the longitude span is "large" compute the true maximum gap
+ if (math::larger(lon_max - lon_min, Constants::half_period()))
+ {
+ std::sort(boost::begin(range), boost::end(range), lon_less);
+
+ CoordinateType max_gap_left = 0, max_gap_right = 0;
+ CoordinateType max_gap
+ = maximum_gap(range, max_gap_left, max_gap_right);
+
+ CoordinateType complement_gap
+ = Constants::period() + lon_min - lon_max;
+
+ if (math::larger(max_gap, complement_gap))
+ {
+ lon_min = max_gap_right;
+ lon_max = max_gap_left + Constants::period();
+ }
+ }
+ }
+
+ template
+ <
+ typename Constants,
+ typename Iterator,
+ typename LatitudeLess,
+ typename CoordinateType
+ >
+ static inline void get_min_max_latitudes(Iterator const first,
+ Iterator const last,
+ LatitudeLess const& lat_less,
+ bool has_south_pole,
+ bool has_north_pole,
+ CoordinateType& lat_min,
+ CoordinateType& lat_max)
+ {
+ if (has_south_pole && has_north_pole)
+ {
+ lat_min = Constants::min_latitude();
+ lat_max = Constants::max_latitude();
+ }
+ else if (has_south_pole)
+ {
+ lat_min = Constants::min_latitude();
+ lat_max
+ = geometry::get<1>(*std::max_element(first, last, lat_less));
+ }
+ else if (has_north_pole)
+ {
+ lat_min
+ = geometry::get<1>(*std::min_element(first, last, lat_less));
+ lat_max = Constants::max_latitude();
+ }
+ else
+ {
+ std::pair<Iterator, Iterator> min_max_latitudes
+ = boost::minmax_element(first, last, lat_less);
+
+ lat_min = geometry::get<1>(*min_max_latitudes.first);
+ lat_max = geometry::get<1>(*min_max_latitudes.second);
+ }
+ }
+
+public:
+ template <typename MultiPoint, typename Box>
+ static inline void apply(MultiPoint const& multipoint, Box& mbr)
+ {
+ typedef typename point_type<MultiPoint>::type point_type;
+ typedef typename coordinate_type<MultiPoint>::type coordinate_type;
+ typedef typename boost::range_iterator
+ <
+ MultiPoint const
+ >::type iterator_type;
+
+ typedef math::detail::constants_on_spheroid
+ <
+ coordinate_type,
+ typename coordinate_system<MultiPoint>::type::units
+ > constants;
+
+ if (boost::empty(multipoint))
+ {
+ initialize<Box, 0, dimension<Box>::value>::apply(mbr);
+ return;
+ }
+
+ initialize<Box, 0, 2>::apply(mbr);
+
+ if (boost::size(multipoint) == 1)
+ {
+ return dispatch::envelope
+ <
+ typename boost::range_value<MultiPoint>::type
+ >::apply(range::front(multipoint), mbr);
+ }
+
+ // analyze the points and put the non-pole ones in the
+ // points vector
+ std::vector<point_type> points;
+ bool has_north_pole = false, has_south_pole = false;
+
+ analyze_point_coordinates<constants>(multipoint,
+ has_south_pole, has_north_pole,
+ std::back_inserter(points));
+
+ coordinate_type lon_min, lat_min, lon_max, lat_max;
+ if (points.size() == 1)
+ {
+ // we have one non-pole point and at least one pole point
+ lon_min = geometry::get<0>(range::front(points));
+ lon_max = geometry::get<0>(range::front(points));
+ lat_min = has_south_pole
+ ? constants::min_latitude()
+ : constants::max_latitude();
+ lat_max = has_north_pole
+ ? constants::max_latitude()
+ : constants::min_latitude();
+ }
+ else if (points.empty())
+ {
+ // all points are pole points
+ BOOST_GEOMETRY_ASSERT(has_south_pole || has_north_pole);
+ lon_min = coordinate_type(0);
+ lon_max = coordinate_type(0);
+ lat_min = has_south_pole
+ ? constants::min_latitude()
+ : constants::max_latitude();
+ lat_max = (has_north_pole)
+ ? constants::max_latitude()
+ : constants::min_latitude();
+ }
+ else
+ {
+ get_min_max_longitudes<constants>(points,
+ coordinate_less<0>(),
+ lon_min,
+ lon_max);
+
+ get_min_max_latitudes<constants>(points.begin(),
+ points.end(),
+ coordinate_less<1>(),
+ has_south_pole,
+ has_north_pole,
+ lat_min,
+ lat_max);
+ }
+
+ typedef typename helper_geometry
+ <
+ Box,
+ coordinate_type,
+ typename coordinate_system<MultiPoint>::type::units
+ >::type helper_box_type;
+
+ helper_box_type helper_mbr;
+
+ geometry::set<min_corner, 0>(helper_mbr, lon_min);
+ geometry::set<min_corner, 1>(helper_mbr, lat_min);
+ geometry::set<max_corner, 0>(helper_mbr, lon_max);
+ geometry::set<max_corner, 1>(helper_mbr, lat_max);
+
+ // now transform to output MBR (per index)
+ envelope_indexed_box_on_spheroid<min_corner, 2>::apply(helper_mbr, mbr);
+ envelope_indexed_box_on_spheroid<max_corner, 2>::apply(helper_mbr, mbr);
+
+ // compute envelope for higher coordinates
+ iterator_type it = boost::begin(multipoint);
+ envelope_one_point<2, dimension<Box>::value>::apply(*it, mbr);
+
+ for (++it; it != boost::end(multipoint); ++it)
+ {
+ detail::expand::point_loop
+ <
+ strategy::compare::default_strategy,
+ strategy::compare::default_strategy,
+ 2, dimension<Box>::value
+ >::apply(mbr, *it);
+ }
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiPoint, typename CSTag>
+struct envelope<MultiPoint, multi_point_tag, CSTag>
+ : detail::envelope::envelope_range
+{};
+
+template <typename MultiPoint>
+struct envelope<MultiPoint, multi_point_tag, spherical_equatorial_tag>
+ : detail::envelope::envelope_multipoint_on_spheroid
+{};
+
+template <typename MultiPoint>
+struct envelope<MultiPoint, multi_point_tag, geographic_tag>
+ : detail::envelope::envelope_multipoint_on_spheroid
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/point.hpp b/boost/geometry/algorithms/detail/envelope/point.hpp
new file mode 100644
index 0000000000..e914e7e8a0
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/point.hpp
@@ -0,0 +1,127 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_POINT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_POINT_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/views/detail/indexed_point_view.hpp>
+
+#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+template <std::size_t Dimension, std::size_t DimensionCount>
+struct envelope_one_point
+{
+ template <std::size_t Index, typename Point, typename Box>
+ static inline void apply(Point const& point, Box& mbr)
+ {
+ detail::indexed_point_view<Box, Index> box_corner(mbr);
+ detail::conversion::point_to_point
+ <
+ Point,
+ detail::indexed_point_view<Box, Index>,
+ Dimension,
+ DimensionCount
+ >::apply(point, box_corner);
+ }
+
+ template <typename Point, typename Box>
+ static inline void apply(Point const& point, Box& mbr)
+ {
+ apply<min_corner>(point, mbr);
+ apply<max_corner>(point, mbr);
+ }
+};
+
+
+struct envelope_point_on_spheroid
+{
+ template<typename Point, typename Box>
+ static inline void apply(Point const& point, Box& mbr)
+ {
+ Point normalized_point = detail::return_normalized<Point>(point);
+
+ typename point_type<Box>::type box_point;
+
+ // transform units of input point to units of a box point
+ transform_units(normalized_point, box_point);
+
+ geometry::set<min_corner, 0>(mbr, geometry::get<0>(box_point));
+ geometry::set<min_corner, 1>(mbr, geometry::get<1>(box_point));
+
+ geometry::set<max_corner, 0>(mbr, geometry::get<0>(box_point));
+ geometry::set<max_corner, 1>(mbr, geometry::get<1>(box_point));
+
+ envelope_one_point
+ <
+ 2, dimension<Point>::value
+ >::apply(normalized_point, mbr);
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Point, typename CS_Tag>
+struct envelope<Point, point_tag, CS_Tag>
+ : detail::envelope::envelope_one_point<0, dimension<Point>::value>
+{};
+
+
+template <typename Point>
+struct envelope<Point, point_tag, spherical_equatorial_tag>
+ : detail::envelope::envelope_point_on_spheroid
+{};
+
+
+template <typename Point>
+struct envelope<Point, point_tag, geographic_tag>
+ : detail::envelope::envelope_point_on_spheroid
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_POINT_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/range.hpp b/boost/geometry/algorithms/detail/envelope/range.hpp
new file mode 100644
index 0000000000..63b518114b
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/range.hpp
@@ -0,0 +1,179 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_HPP
+
+#include <iterator>
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+
+#include <boost/geometry/util/range.hpp>
+
+#include <boost/geometry/algorithms/is_empty.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
+
+#include <boost/geometry/algorithms/detail/expand/box.hpp>
+#include <boost/geometry/algorithms/detail/expand/point.hpp>
+#include <boost/geometry/algorithms/detail/expand/segment.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+// implementation for simple ranges
+struct envelope_range
+{
+ template <typename Iterator, typename Box>
+ static inline void apply(Iterator first, Iterator last, Box& mbr)
+ {
+ typedef typename std::iterator_traits<Iterator>::value_type value_type;
+
+ // initialize MBR
+ initialize<Box, 0, dimension<Box>::value>::apply(mbr);
+
+ Iterator it = first;
+ if (it != last)
+ {
+ // initialize box with first element in range
+ dispatch::envelope<value_type>::apply(*it, mbr);
+
+ // consider now the remaining elements in the range (if any)
+ for (++it; it != last; ++it)
+ {
+ dispatch::expand<Box, value_type>::apply(mbr, *it);
+ }
+ }
+ }
+
+ template <typename Range, typename Box>
+ static inline void apply(Range const& range, Box& mbr)
+ {
+ return apply(boost::begin(range), boost::end(range), mbr);
+ }
+};
+
+
+// implementation for multi-ranges
+template <typename EnvelopePolicy>
+struct envelope_multi_range
+{
+ template <typename MultiRange, typename Box>
+ static inline void apply(MultiRange const& multirange, Box& mbr)
+ {
+ typedef typename boost::range_iterator
+ <
+ MultiRange const
+ >::type iterator_type;
+
+ bool initialized = false;
+ for (iterator_type it = boost::begin(multirange);
+ it != boost::end(multirange);
+ ++it)
+ {
+ if (! geometry::is_empty(*it))
+ {
+ if (initialized)
+ {
+ Box helper_mbr;
+ EnvelopePolicy::apply(*it, helper_mbr);
+
+ dispatch::expand<Box, Box>::apply(mbr, helper_mbr);
+ }
+ else
+ {
+ // compute the initial envelope
+ EnvelopePolicy::apply(*it, mbr);
+ initialized = true;
+ }
+ }
+ }
+
+ if (! initialized)
+ {
+ // if not already initialized, initialize MBR
+ initialize<Box, 0, dimension<Box>::value>::apply(mbr);
+ }
+ }
+};
+
+
+// implementation for multi-range on a spheroid (longitude is periodic)
+template <typename EnvelopePolicy>
+struct envelope_multi_range_on_spheroid
+{
+ template <typename MultiRange, typename Box>
+ static inline void apply(MultiRange const& multirange, Box& mbr)
+ {
+ typedef typename boost::range_iterator
+ <
+ MultiRange const
+ >::type iterator_type;
+
+ // due to the periodicity of longitudes we need to compute the boxes
+ // of all the single geometries and keep them in a container
+ std::vector<Box> boxes;
+ for (iterator_type it = boost::begin(multirange);
+ it != boost::end(multirange);
+ ++it)
+ {
+ if (! geometry::is_empty(*it))
+ {
+ Box helper_box;
+ EnvelopePolicy::apply(*it, helper_box);
+ boxes.push_back(helper_box);
+ }
+ }
+
+ // now we need to compute the envelope of the range of boxes
+ // (cannot be done in an incremental fashion as in the
+ // Cartesian coordinate system)
+ // if all single geometries are empty no boxes have been found
+ // and the MBR is simply initialized
+ if (! boxes.empty())
+ {
+ envelope_range_of_boxes::apply(boxes, mbr);
+ }
+ else
+ {
+ initialize<Box, 0, dimension<Box>::value>::apply(mbr);
+ }
+
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp b/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp
new file mode 100644
index 0000000000..64bdb9b9cb
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp
@@ -0,0 +1,326 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_OF_BOXES_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_OF_BOXES_HPP
+
+#include <cstddef>
+
+#include <algorithm>
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/range.hpp>
+
+#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
+#include <boost/geometry/algorithms/detail/max_interval_gap.hpp>
+#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+template <typename T>
+class longitude_interval
+{
+ typedef T const& reference_type;
+
+public:
+ typedef T value_type;
+ typedef T difference_type;
+
+ longitude_interval(T const& left, T const& right)
+ {
+ m_end[0] = left;
+ m_end[1] = right;
+ }
+
+ template <std::size_t Index>
+ reference_type get() const
+ {
+ return m_end[Index];
+ }
+
+ difference_type length() const
+ {
+ return get<1>() - get<0>();
+ }
+
+private:
+ T m_end[2];
+};
+
+
+template <typename Units>
+struct envelope_range_of_longitudes
+{
+ template <std::size_t Index>
+ struct longitude_less
+ {
+ template <typename Interval>
+ inline bool operator()(Interval const& i1, Interval const& i2) const
+ {
+ return math::smaller(i1.template get<Index>(),
+ i2.template get<Index>());
+ }
+ };
+
+ template <typename RangeOfLongitudeIntervals, typename Longitude>
+ static inline void apply(RangeOfLongitudeIntervals const& range,
+ Longitude& lon_min, Longitude& lon_max)
+ {
+ typedef typename math::detail::constants_on_spheroid
+ <
+ Longitude, Units
+ > constants;
+
+ Longitude const zero = 0;
+ Longitude const period = constants::period();
+
+ lon_min = lon_max = zero;
+
+ // the range of longitude intervals can be empty if all input boxes
+ // degenerate to the north or south pole (or combination of the two)
+ // in this case the initialization values for lon_min and
+ // lon_max are valid choices
+ if (! boost::empty(range))
+ {
+ lon_min = std::min_element(boost::begin(range),
+ boost::end(range),
+ longitude_less<0>())->template get<0>();
+ lon_max = std::max_element(boost::begin(range),
+ boost::end(range),
+ longitude_less<1>())->template get<1>();
+
+ if (math::larger(lon_max - lon_min, constants::half_period()))
+ {
+ Longitude max_gap_left, max_gap_right;
+ Longitude max_gap = geometry::maximum_gap(range,
+ max_gap_left,
+ max_gap_right);
+
+ BOOST_GEOMETRY_ASSERT(! math::larger(lon_min, lon_max));
+ BOOST_GEOMETRY_ASSERT
+ (! math::larger(lon_max, constants::max_longitude()));
+ BOOST_GEOMETRY_ASSERT
+ (! math::smaller(lon_min, constants::min_longitude()));
+
+ BOOST_GEOMETRY_ASSERT
+ (! math::larger(max_gap_left, max_gap_right));
+ BOOST_GEOMETRY_ASSERT
+ (! math::larger(max_gap_right, constants::max_longitude()));
+ BOOST_GEOMETRY_ASSERT
+ (! math::smaller(max_gap_left, constants::min_longitude()));
+
+ if (math::larger(max_gap, zero))
+ {
+ Longitude wrapped_gap = period + lon_min - lon_max;
+ if (math::larger(max_gap, wrapped_gap))
+ {
+ lon_min = max_gap_right;
+ lon_max = max_gap_left + period;
+ }
+ }
+ }
+ }
+ }
+};
+
+
+template <std::size_t Dimension, std::size_t DimensionCount>
+struct envelope_range_of_boxes_by_expansion
+{
+ template <typename RangeOfBoxes, typename Box>
+ static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr)
+ {
+ typedef typename boost::range_value<RangeOfBoxes>::type box_type;
+
+ typedef typename boost::range_iterator
+ <
+ RangeOfBoxes const
+ >::type iterator_type;
+
+ // first initialize MBR
+ detail::indexed_point_view<Box, min_corner> mbr_min(mbr);
+ detail::indexed_point_view<Box, max_corner> mbr_max(mbr);
+
+ detail::indexed_point_view<box_type const, min_corner>
+ first_box_min(range::front(range_of_boxes));
+
+ detail::indexed_point_view<box_type const, max_corner>
+ first_box_max(range::front(range_of_boxes));
+
+ detail::conversion::point_to_point
+ <
+ detail::indexed_point_view<box_type const, min_corner>,
+ detail::indexed_point_view<Box, min_corner>,
+ Dimension,
+ DimensionCount
+ >::apply(first_box_min, mbr_min);
+
+ detail::conversion::point_to_point
+ <
+ detail::indexed_point_view<box_type const, max_corner>,
+ detail::indexed_point_view<Box, max_corner>,
+ Dimension,
+ DimensionCount
+ >::apply(first_box_max, mbr_max);
+
+ // now expand using the remaining boxes
+ iterator_type it = boost::begin(range_of_boxes);
+ for (++it; it != boost::end(range_of_boxes); ++it)
+ {
+ detail::expand::indexed_loop
+ <
+ strategy::compare::default_strategy,
+ strategy::compare::default_strategy,
+ min_corner,
+ Dimension,
+ DimensionCount
+ >::apply(mbr, *it);
+
+ detail::expand::indexed_loop
+ <
+ strategy::compare::default_strategy,
+ strategy::compare::default_strategy,
+ max_corner,
+ Dimension,
+ DimensionCount
+ >::apply(mbr, *it);
+ }
+ }
+
+};
+
+
+struct envelope_range_of_boxes
+{
+ template <std::size_t Index>
+ struct latitude_less
+ {
+ template <typename Box>
+ inline bool operator()(Box const& box1, Box const& box2) const
+ {
+ return math::smaller(geometry::get<Index, 1>(box1),
+ geometry::get<Index, 1>(box2));
+ }
+ };
+
+ template <typename RangeOfBoxes, typename Box>
+ static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr)
+ {
+ // boxes in the range are assumed to be normalized already
+
+ typedef typename boost::range_value<RangeOfBoxes>::type box_type;
+ typedef typename coordinate_type<box_type>::type coordinate_type;
+ typedef typename coordinate_system<box_type>::type::units units_type;
+ typedef typename boost::range_iterator
+ <
+ RangeOfBoxes const
+ >::type iterator_type;
+
+ typedef math::detail::constants_on_spheroid
+ <
+ coordinate_type, units_type
+ > constants;
+
+ typedef longitude_interval<coordinate_type> interval_type;
+ typedef std::vector<interval_type> interval_range_type;
+
+ BOOST_GEOMETRY_ASSERT(! boost::empty(range_of_boxes));
+
+ iterator_type it_min = std::min_element(boost::begin(range_of_boxes),
+ boost::end(range_of_boxes),
+ latitude_less<min_corner>());
+ iterator_type it_max = std::max_element(boost::begin(range_of_boxes),
+ boost::end(range_of_boxes),
+ latitude_less<max_corner>());
+
+ coordinate_type const min_longitude = constants::min_longitude();
+ coordinate_type const max_longitude = constants::max_longitude();
+ coordinate_type const period = constants::period();
+
+ interval_range_type intervals;
+ for (iterator_type it = boost::begin(range_of_boxes);
+ it != boost::end(range_of_boxes);
+ ++it)
+ {
+ coordinate_type lat_min = geometry::get<min_corner, 1>(*it);
+ coordinate_type lat_max = geometry::get<max_corner, 1>(*it);
+ if (math::equals(lat_min, constants::max_latitude())
+ || math::equals(lat_max, constants::min_latitude()))
+ {
+ // if the box degenerates to the south or north pole
+ // just ignore it
+ continue;
+ }
+
+ coordinate_type lon_left = geometry::get<min_corner, 0>(*it);
+ coordinate_type lon_right = geometry::get<max_corner, 0>(*it);
+
+ if (math::larger(lon_right, max_longitude))
+ {
+ intervals.push_back(interval_type(lon_left, max_longitude));
+ intervals.push_back
+ (interval_type(min_longitude, lon_right - period));
+ }
+ else
+ {
+ intervals.push_back(interval_type(lon_left, lon_right));
+ }
+ }
+
+ coordinate_type lon_min = 0;
+ coordinate_type lon_max = 0;
+ envelope_range_of_longitudes
+ <
+ units_type
+ >::apply(intervals, lon_min, lon_max);
+
+ // do not convert units; conversion will be performed at a
+ // higher level
+
+ // assign now the min/max longitude/latitude values
+ detail::indexed_point_view<Box, min_corner> mbr_min(mbr);
+ detail::indexed_point_view<Box, max_corner> mbr_max(mbr);
+
+ geometry::set<0>(mbr_min, lon_min);
+ geometry::set<1>(mbr_min, geometry::get<min_corner, 1>(*it_min));
+ geometry::set<0>(mbr_max, lon_max);
+ geometry::set<1>(mbr_max, geometry::get<max_corner, 1>(*it_max));
+
+ // what remains to be done is to compute the envelope range
+ // for the remaining dimensions (if any)
+ envelope_range_of_boxes_by_expansion
+ <
+ 2, dimension<Box>::value
+ >::apply(range_of_boxes, mbr);
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_OF_BOXES_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/segment.hpp b/boost/geometry/algorithms/detail/envelope/segment.hpp
new file mode 100644
index 0000000000..570f0e1a43
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/segment.hpp
@@ -0,0 +1,386 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_SEGMENT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_SEGMENT_HPP
+
+#include <cstddef>
+#include <utility>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/geometries/helper_geometry.hpp>
+
+#include <boost/geometry/strategies/compare.hpp>
+
+#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/point.hpp>
+#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
+
+#include <boost/geometry/algorithms/detail/expand/point.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+template <std::size_t Dimension, std::size_t DimensionCount>
+struct envelope_one_segment
+{
+ template<typename Point, typename Box>
+ static inline void apply(Point const& p1, Point const& p2, Box& mbr)
+ {
+ envelope_one_point<Dimension, DimensionCount>::apply(p1, mbr);
+ detail::expand::point_loop
+ <
+ strategy::compare::default_strategy,
+ strategy::compare::default_strategy,
+ Dimension,
+ DimensionCount
+ >::apply(mbr, p2);
+ }
+};
+
+
+// Computes the MBR of a segment given by (lon1, lat1) and (lon2,
+// lat2), and with azimuths a1 and a2 at the two endpoints of the
+// segment.
+// It is assumed that the spherical coordinates of the segment are
+// normalized and in radians.
+// The longitudes and latitudes of the endpoints are overridden by
+// those of the box.
+class compute_mbr_of_segment
+{
+private:
+ // computes the azimuths of the segment with endpoints (lon1, lat1)
+ // and (lon2, lat2)
+ template <typename CalculationType>
+ static inline void azimuths(CalculationType const& lon1,
+ CalculationType const& lat1,
+ CalculationType const& lon2,
+ CalculationType const& lat2,
+ CalculationType& a1,
+ CalculationType& a2)
+ {
+ BOOST_GEOMETRY_ASSERT(math::smaller(lon1, lon2));
+
+ CalculationType dlon = lon2 - lon1;
+ CalculationType sin_dlon = sin(dlon);
+ CalculationType cos_dlon = cos(dlon);
+ CalculationType cos_lat1 = cos(lat1);
+ CalculationType cos_lat2 = cos(lat2);
+ CalculationType sin_lat1 = sin(lat1);
+ CalculationType sin_lat2 = sin(lat2);
+
+ a1 = atan2(sin_dlon * cos_lat2,
+ cos_lat1 * sin_lat2 - sin_lat1 * cos_lat2 * cos_dlon);
+
+ a2 = atan2(-sin_dlon * cos_lat1,
+ cos_lat2 * sin_lat1 - sin_lat2 * cos_lat1 * cos_dlon);
+ a2 += math::pi<CalculationType>();
+ }
+
+ template <typename CalculationType>
+ static inline void swap(CalculationType& lon1,
+ CalculationType& lat1,
+ CalculationType& lon2,
+ CalculationType& lat2)
+ {
+ std::swap(lon1, lon2);
+ std::swap(lat1, lat2);
+ }
+
+ template <typename CalculationType>
+ static inline bool contains_pi_half(CalculationType const& a1,
+ CalculationType const& a2)
+ {
+ // azimuths a1 and a2 are assumed to be in radians
+ BOOST_GEOMETRY_ASSERT(! math::equals(a1, a2));
+
+ static CalculationType const pi_half = math::half_pi<CalculationType>();
+
+ return (a1 < a2)
+ ? (a1 < pi_half && pi_half < a2)
+ : (a1 > pi_half && pi_half > a2);
+ }
+
+ template <typename CoordinateType>
+ static inline bool crosses_antimeridian(CoordinateType const& lon1,
+ CoordinateType const& lon2)
+ {
+ return math::larger(math::abs(lon1 - lon2), math::pi<CoordinateType>());
+ }
+
+ template <typename CalculationType>
+ static inline CalculationType max_latitude(CalculationType const& azimuth,
+ CalculationType const& latitude)
+ {
+ // azimuth and latitude are assumed to be in radians
+ return acos( math::abs(cos(latitude) * sin(azimuth)) );
+ }
+
+ template <typename CalculationType>
+ static inline void compute_box_corners(CalculationType& lon1,
+ CalculationType& lat1,
+ CalculationType& lon2,
+ CalculationType& lat2,
+ CalculationType const& a1,
+ CalculationType const& a2)
+ {
+ // coordinates are assumed to be in radians
+ BOOST_GEOMETRY_ASSERT(! math::larger(lon1, lon2));
+
+ if (math::equals(a1, a2))
+ {
+ // the segment must lie on the equator; nothing to do
+ BOOST_GEOMETRY_ASSERT(math::equals(lat1, CalculationType(0)));
+ BOOST_GEOMETRY_ASSERT(math::equals(lat2, CalculationType(0)));
+ return;
+ }
+
+ if (math::larger(lat1, lat2))
+ {
+ std::swap(lat1, lat2);
+ }
+
+ if (contains_pi_half(a1, a2))
+ {
+ CalculationType mid_lat = lat1 + lat2;
+ if (mid_lat < 0)
+ {
+ // update using min latitude
+ CalculationType lat_min = -max_latitude(a1, lat1);
+
+ if (math::larger(lat1, lat_min))
+ {
+ lat1 = lat_min;
+ }
+ }
+ else if (mid_lat > 0)
+ {
+ // update using max latitude
+ CalculationType lat_max = max_latitude(a1, lat1);
+
+ if (math::smaller(lat2, lat_max))
+ {
+ lat2 = lat_max;
+ }
+ }
+ }
+ }
+
+ template <typename CalculationType>
+ static inline void apply(CalculationType& lon1,
+ CalculationType& lat1,
+ CalculationType& lon2,
+ CalculationType& lat2)
+ {
+ CalculationType const half_pi = math::half_pi<CalculationType>();
+
+ bool is_pole1 = math::equals(math::abs(lat1), half_pi);
+ bool is_pole2 = math::equals(math::abs(lat2), half_pi);
+
+ if (is_pole1 && is_pole2)
+ {
+ // both points are poles; nothing more to do:
+ // longitudes are already normalized to 0
+ BOOST_GEOMETRY_ASSERT(lon1 == CalculationType(0)
+ &&
+ lon2 == CalculationType(0));
+ }
+ else if (is_pole1 && !is_pole2)
+ {
+ // first point is a pole, second point is not:
+ // make the longitude of the first point the same as that
+ // of the second point
+ lon1 = lon2;
+ }
+ else if (!is_pole1 && is_pole2)
+ {
+ // second point is a pole, first point is not:
+ // make the longitude of the second point the same as that
+ // of the first point
+ lon2 = lon1;
+ }
+
+ if (math::equals(lon1, lon2))
+ {
+ // segment lies on a meridian
+ if (math::larger(lat1, lat2))
+ {
+ std::swap(lat1, lat2);
+ }
+ return;
+ }
+
+ BOOST_GEOMETRY_ASSERT(!is_pole1 && !is_pole2);
+
+ if (math::larger(lon1, lon2))
+ {
+ swap(lon1, lat1, lon2, lat2);
+ }
+
+ if (crosses_antimeridian(lon1, lon2))
+ {
+ lon1 += math::two_pi<CalculationType>();
+ swap(lon1, lat1, lon2, lat2);
+ }
+
+ CalculationType a1 = 0, a2 = 0;
+ azimuths(lon1, lat1, lon2, lat2, a1, a2);
+
+ compute_box_corners(lon1, lat1, lon2, lat2, a1, a2);
+ }
+
+public:
+ template <typename CalculationType, typename Box>
+ static inline void apply(CalculationType lon1,
+ CalculationType lat1,
+ CalculationType lon2,
+ CalculationType lat2,
+ Box& mbr)
+ {
+ typedef typename coordinate_type<Box>::type box_coordinate_type;
+
+ typedef typename helper_geometry
+ <
+ Box, box_coordinate_type, radian
+ >::type helper_box_type;
+
+ helper_box_type radian_mbr;
+
+ apply(lon1, lat1, lon2, lat2);
+
+ geometry::set
+ <
+ min_corner, 0
+ >(radian_mbr, boost::numeric_cast<box_coordinate_type>(lon1));
+
+ geometry::set
+ <
+ min_corner, 1
+ >(radian_mbr, boost::numeric_cast<box_coordinate_type>(lat1));
+
+ geometry::set
+ <
+ max_corner, 0
+ >(radian_mbr, boost::numeric_cast<box_coordinate_type>(lon2));
+
+ geometry::set
+ <
+ max_corner, 1
+ >(radian_mbr, boost::numeric_cast<box_coordinate_type>(lat2));
+
+ transform_units(radian_mbr, mbr);
+ }
+};
+
+
+template <std::size_t DimensionCount>
+struct envelope_segment_on_sphere
+{
+ template <typename Point, typename Box>
+ static inline void apply(Point const& p1, Point const& p2, Box& mbr)
+ {
+ // first compute the envelope range for the first two coordinates
+ Point p1_normalized = detail::return_normalized<Point>(p1);
+ Point p2_normalized = detail::return_normalized<Point>(p2);
+
+ compute_mbr_of_segment::apply(geometry::get_as_radian<0>(p1_normalized),
+ geometry::get_as_radian<1>(p1_normalized),
+ geometry::get_as_radian<0>(p2_normalized),
+ geometry::get_as_radian<1>(p2_normalized),
+ mbr);
+
+ // now compute the envelope range for coordinates of
+ // dimension 2 and higher
+ envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr);
+ }
+
+ template <typename Segment, typename Box>
+ static inline void apply(Segment const& segment, Box& mbr)
+ {
+ typename point_type<Segment>::type p[2];
+ detail::assign_point_from_index<0>(segment, p[0]);
+ detail::assign_point_from_index<1>(segment, p[1]);
+ apply(p[0], p[1], mbr);
+ }
+};
+
+
+
+template <std::size_t DimensionCount, typename CS_Tag>
+struct envelope_segment
+ : envelope_one_segment<0, DimensionCount>
+{};
+
+
+template <std::size_t DimensionCount>
+struct envelope_segment<DimensionCount, spherical_equatorial_tag>
+ : envelope_segment_on_sphere<DimensionCount>
+{};
+
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Segment, typename CS_Tag>
+struct envelope<Segment, segment_tag, CS_Tag>
+{
+ template <typename Box>
+ static inline void apply(Segment const& segment, Box& mbr)
+ {
+ typename point_type<Segment>::type p[2];
+ detail::assign_point_from_index<0>(segment, p[0]);
+ detail::assign_point_from_index<1>(segment, p[1]);
+ detail::envelope::envelope_segment
+ <
+ dimension<Segment>::value, CS_Tag
+ >::apply(p[0], p[1], mbr);
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_SEGMENT_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/transform_units.hpp b/boost/geometry/algorithms/detail/envelope/transform_units.hpp
new file mode 100644
index 0000000000..0c5382a47b
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/transform_units.hpp
@@ -0,0 +1,103 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_TRANSFORM_UNITS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_TRANSFORM_UNITS_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/strategies/strategy_transform.hpp>
+
+#include <boost/geometry/views/detail/indexed_point_view.hpp>
+#include <boost/geometry/views/detail/two_dimensional_view.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/algorithms/transform.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+template
+<
+ typename GeometryIn,
+ typename GeometryOut,
+ typename TagIn = typename tag<GeometryIn>::type,
+ typename TagOut = typename tag<GeometryOut>::type
+>
+struct transform_units_impl
+ : not_implemented<TagIn, TagOut>
+{};
+
+template <typename PointIn, typename PointOut>
+struct transform_units_impl<PointIn, PointOut, point_tag, point_tag>
+{
+ static inline void apply(PointIn const& point_in, PointOut& point_out)
+ {
+ detail::two_dimensional_view<PointIn const> view_in(point_in);
+ detail::two_dimensional_view<PointOut> view_out(point_out);
+
+ geometry::transform(view_in, view_out);
+ }
+};
+
+template <typename BoxIn, typename BoxOut>
+struct transform_units_impl<BoxIn, BoxOut, box_tag, box_tag>
+{
+ template <std::size_t Index>
+ static inline void apply(BoxIn const& box_in, BoxOut& box_out)
+ {
+ typedef detail::indexed_point_view<BoxIn const, Index> view_in_type;
+ typedef detail::indexed_point_view<BoxOut, Index> view_out_type;
+
+ view_in_type view_in(box_in);
+ view_out_type view_out(box_out);
+
+ transform_units_impl
+ <
+ view_in_type, view_out_type
+ >::apply(view_in, view_out);
+ }
+
+ static inline void apply(BoxIn const& box_in, BoxOut& box_out)
+ {
+ apply<min_corner>(box_in, box_out);
+ apply<max_corner>(box_in, box_out);
+ }
+};
+
+
+// Short utility to transform the units of the first two coordinates of
+// geometry_in to the units of geometry_out
+template <typename GeometryIn, typename GeometryOut>
+inline void transform_units(GeometryIn const& geometry_in,
+ GeometryOut& geometry_out)
+{
+ transform_units_impl
+ <
+ GeometryIn, GeometryOut
+ >::apply(geometry_in, geometry_out);
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost:geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_TRANSFORM_UNITS_HPP
diff --git a/boost/geometry/algorithms/detail/expand/box.hpp b/boost/geometry/algorithms/detail/expand/box.hpp
new file mode 100644
index 0000000000..4c89e6f1d4
--- /dev/null
+++ b/boost/geometry/algorithms/detail/expand/box.hpp
@@ -0,0 +1,126 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_BOX_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_BOX_HPP
+
+#include <cstddef>
+#include <algorithm>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/box.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
+
+#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
+
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace expand
+{
+
+
+struct box_on_spheroid
+{
+ template <typename BoxOut, typename BoxIn>
+ static inline void apply(BoxOut& box_out, BoxIn const& box_in)
+ {
+ // normalize both boxes and convert box-in to be of type of box-out
+ BoxOut mbrs[2];
+ detail::envelope::envelope_box_on_spheroid::apply(box_in, mbrs[0]);
+ detail::envelope::envelope_box_on_spheroid::apply(box_out, mbrs[1]);
+
+ // compute the envelope of the two boxes
+ detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out);
+ }
+};
+
+
+}} // namespace detail::expand
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+// Box + box -> new box containing two input boxes
+template
+<
+ typename BoxOut, typename BoxIn,
+ typename StrategyLess, typename StrategyGreater,
+ typename CSTagOut, typename CSTag
+>
+struct expand
+ <
+ BoxOut, BoxIn,
+ StrategyLess, StrategyGreater,
+ box_tag, box_tag,
+ CSTagOut, CSTag
+ > : detail::expand::expand_indexed
+ <
+ 0, dimension<BoxIn>::value, StrategyLess, StrategyGreater
+ >
+{
+ BOOST_MPL_ASSERT_MSG((boost::is_same<CSTagOut, CSTag>::value),
+ COORDINATE_SYSTEMS_MUST_BE_THE_SAME,
+ (types<CSTagOut, CSTag>()));
+};
+
+template
+<
+ typename BoxOut, typename BoxIn,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ BoxOut, BoxIn,
+ StrategyLess, StrategyGreater,
+ box_tag, box_tag,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::expand::box_on_spheroid
+{};
+
+template
+<
+ typename BoxOut, typename BoxIn,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ BoxOut, BoxIn,
+ StrategyLess, StrategyGreater,
+ box_tag, box_tag,
+ geographic_tag, geographic_tag
+ > : detail::expand::box_on_spheroid
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INDEXED_HPP
diff --git a/boost/geometry/algorithms/detail/expand/implementation.hpp b/boost/geometry/algorithms/detail/expand/implementation.hpp
new file mode 100644
index 0000000000..95de1b5049
--- /dev/null
+++ b/boost/geometry/algorithms/detail/expand/implementation.hpp
@@ -0,0 +1,27 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_IMPLEMENTATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_IMPLEMENTATION_HPP
+
+#include <boost/geometry/algorithms/detail/expand/point.hpp>
+#include <boost/geometry/algorithms/detail/expand/segment.hpp>
+#include <boost/geometry/algorithms/detail/expand/box.hpp>
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_IMPLEMENTATION_HPP
diff --git a/boost/geometry/algorithms/detail/expand/indexed.hpp b/boost/geometry/algorithms/detail/expand/indexed.hpp
new file mode 100644
index 0000000000..bdd6eb4506
--- /dev/null
+++ b/boost/geometry/algorithms/detail/expand/indexed.hpp
@@ -0,0 +1,144 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INDEXED_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INDEXED_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+#include <boost/geometry/strategies/compare.hpp>
+#include <boost/geometry/policies/compare.hpp>
+
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace expand
+{
+
+
+template
+<
+ typename StrategyLess, typename StrategyGreater,
+ std::size_t Index,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct indexed_loop
+{
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& box, Geometry const& source)
+ {
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ StrategyLess, 1, Box, Dimension
+ >::type less_type;
+
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ StrategyGreater, -1, Box, Dimension
+ >::type greater_type;
+
+ typedef typename select_coordinate_type
+ <
+ Box,
+ Geometry
+ >::type coordinate_type;
+
+ less_type less;
+ greater_type greater;
+
+ coordinate_type const coord = get<Index, Dimension>(source);
+
+ if (less(coord, get<min_corner, Dimension>(box)))
+ {
+ set<min_corner, Dimension>(box, coord);
+ }
+
+ if (greater(coord, get<max_corner, Dimension>(box)))
+ {
+ set<max_corner, Dimension>(box, coord);
+ }
+
+ indexed_loop
+ <
+ StrategyLess, StrategyGreater,
+ Index, Dimension + 1, DimensionCount
+ >::apply(box, source);
+ }
+};
+
+
+template
+<
+ typename StrategyLess, typename StrategyGreater,
+ std::size_t Index, std::size_t DimensionCount
+>
+struct indexed_loop
+ <
+ StrategyLess, StrategyGreater,
+ Index, DimensionCount, DimensionCount
+ >
+{
+ template <typename Box, typename Geometry>
+ static inline void apply(Box&, Geometry const&) {}
+};
+
+
+
+// Changes a box such that the other box is also contained by the box
+template
+<
+ std::size_t Dimension, std::size_t DimensionCount,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand_indexed
+{
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& box, Geometry const& geometry)
+ {
+ indexed_loop
+ <
+ StrategyLess, StrategyGreater,
+ 0, Dimension, DimensionCount
+ >::apply(box, geometry);
+
+ indexed_loop
+ <
+ StrategyLess, StrategyGreater,
+ 1, Dimension, DimensionCount
+ >::apply(box, geometry);
+ }
+};
+
+
+}} // namespace detail::expand
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INDEXED_HPP
diff --git a/boost/geometry/algorithms/detail/expand/interface.hpp b/boost/geometry/algorithms/detail/expand/interface.hpp
new file mode 100644
index 0000000000..01936387a7
--- /dev/null
+++ b/boost/geometry/algorithms/detail/expand/interface.hpp
@@ -0,0 +1,128 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INTERFACE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INTERFACE_HPP
+
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry>
+struct expand
+{
+ template <typename Box>
+ static inline void apply(Box& box, Geometry const& geometry)
+ {
+ concept::check<Box>();
+ concept::check<Geometry const>();
+ concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
+
+ dispatch::expand<Box, Geometry>::apply(box, geometry);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct expand<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Box>
+ struct visitor: boost::static_visitor<void>
+ {
+ Box& m_box;
+
+ visitor(Box& box) : m_box(box) {}
+
+ template <typename Geometry>
+ void operator()(Geometry const& geometry) const
+ {
+ return expand<Geometry>::apply(m_box, geometry);
+ }
+ };
+
+ template <class Box>
+ static inline void
+ apply(Box& box,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
+ {
+ return boost::apply_visitor(visitor<Box>(box), geometry);
+ }
+};
+
+} // namespace resolve_variant
+
+
+/***
+*!
+\brief Expands a box using the extend (envelope) of another geometry (box, point)
+\ingroup expand
+\tparam Box type of the box
+\tparam Geometry of second geometry, to be expanded with the box
+\param box box to expand another geometry with, might be changed
+\param geometry other geometry
+\param strategy_less
+\param strategy_greater
+\note Strategy is currently ignored
+ *
+template
+<
+ typename Box, typename Geometry,
+ typename StrategyLess, typename StrategyGreater
+>
+inline void expand(Box& box, Geometry const& geometry,
+ StrategyLess const& strategy_less,
+ StrategyGreater const& strategy_greater)
+{
+ concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
+
+ dispatch::expand<Box, Geometry>::apply(box, geometry);
+}
+***/
+
+
+/*!
+\brief Expands a box using the bounding box (envelope) of another geometry (box, point)
+\ingroup expand
+\tparam Box type of the box
+\tparam Geometry \tparam_geometry
+\param box box to be expanded using another geometry, mutable
+\param geometry \param_geometry geometry which envelope (bounding box) will be added to the box
+
+\qbk{[include reference/algorithms/expand.qbk]}
+ */
+template <typename Box, typename Geometry>
+inline void expand(Box& box, Geometry const& geometry)
+{
+ resolve_variant::expand<Geometry>::apply(box, geometry);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INTERFACE_HPP
diff --git a/boost/geometry/algorithms/detail/expand/point.hpp b/boost/geometry/algorithms/detail/expand/point.hpp
new file mode 100644
index 0000000000..56b7f1c738
--- /dev/null
+++ b/boost/geometry/algorithms/detail/expand/point.hpp
@@ -0,0 +1,303 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_POINT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_POINT_HPP
+
+#include <cstddef>
+#include <algorithm>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+#include <boost/geometry/strategies/compare.hpp>
+#include <boost/geometry/policies/compare.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
+
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace expand
+{
+
+
+template
+<
+ typename StrategyLess, typename StrategyGreater,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_loop
+{
+ template <typename Box, typename Point>
+ static inline void apply(Box& box, Point const& source)
+ {
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ StrategyLess, 1, Point, Dimension
+ >::type less_type;
+
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ StrategyGreater, -1, Point, Dimension
+ >::type greater_type;
+
+ typedef typename select_coordinate_type
+ <
+ Point, Box
+ >::type coordinate_type;
+
+ less_type less;
+ greater_type greater;
+
+ coordinate_type const coord = get<Dimension>(source);
+
+ if (less(coord, get<min_corner, Dimension>(box)))
+ {
+ set<min_corner, Dimension>(box, coord);
+ }
+
+ if (greater(coord, get<max_corner, Dimension>(box)))
+ {
+ set<max_corner, Dimension>(box, coord);
+ }
+
+ point_loop
+ <
+ StrategyLess, StrategyGreater, Dimension + 1, DimensionCount
+ >::apply(box, source);
+ }
+};
+
+
+template
+<
+ typename StrategyLess, typename StrategyGreater, std::size_t DimensionCount
+>
+struct point_loop
+ <
+ StrategyLess, StrategyGreater, DimensionCount, DimensionCount
+ >
+{
+ template <typename Box, typename Point>
+ static inline void apply(Box&, Point const&) {}
+};
+
+
+// implementation for the spherical equatorial and geographic coordinate systems
+template
+<
+ typename StrategyLess,
+ typename StrategyGreater,
+ std::size_t DimensionCount
+>
+struct point_loop_on_spheroid
+{
+ template <typename Box, typename Point>
+ static inline void apply(Box& box, Point const& point)
+ {
+ typedef typename point_type<Box>::type box_point_type;
+ typedef typename coordinate_type<Box>::type box_coordinate_type;
+
+ typedef math::detail::constants_on_spheroid
+ <
+ box_coordinate_type,
+ typename coordinate_system<Box>::type::units
+ > constants;
+
+ // normalize input point and input box
+ Point p_normalized = detail::return_normalized<Point>(point);
+ detail::normalize(box, box);
+
+ // transform input point to be of the same type as the box point
+ box_point_type box_point;
+ detail::envelope::transform_units(p_normalized, box_point);
+
+ box_coordinate_type p_lon = geometry::get<0>(box_point);
+ box_coordinate_type p_lat = geometry::get<1>(box_point);
+
+ typename coordinate_type<Box>::type
+ b_lon_min = geometry::get<min_corner, 0>(box),
+ b_lat_min = geometry::get<min_corner, 1>(box),
+ b_lon_max = geometry::get<max_corner, 0>(box),
+ b_lat_max = geometry::get<max_corner, 1>(box);
+
+ if (math::equals(math::abs(p_lat), constants::max_latitude()))
+ {
+ // the point of expansion is the either the north or the
+ // south pole; the only important coordinate here is the
+ // pole's latitude, as the longitude can be anything;
+ // we, thus, take into account the point's latitude only and return
+ geometry::set<min_corner, 1>(box, (std::min)(p_lat, b_lat_min));
+ geometry::set<max_corner, 1>(box, (std::max)(p_lat, b_lat_max));
+ return;
+ }
+
+ if (math::equals(b_lat_min, b_lat_max)
+ && math::equals(math::abs(b_lat_min), constants::max_latitude()))
+ {
+ // the box degenerates to either the north or the south pole;
+ // the only important coordinate here is the pole's latitude,
+ // as the longitude can be anything;
+ // we thus take into account the box's latitude only and return
+ geometry::set<min_corner, 0>(box, p_lon);
+ geometry::set<min_corner, 1>(box, (std::min)(p_lat, b_lat_min));
+ geometry::set<max_corner, 0>(box, p_lon);
+ geometry::set<max_corner, 1>(box, (std::max)(p_lat, b_lat_max));
+ return;
+ }
+
+ // update latitudes
+ b_lat_min = (std::min)(b_lat_min, p_lat);
+ b_lat_max = (std::max)(b_lat_max, p_lat);
+
+ // update longitudes
+ if (math::smaller(p_lon, b_lon_min))
+ {
+ box_coordinate_type p_lon_shifted = p_lon + constants::period();
+
+ if (math::larger(p_lon_shifted, b_lon_max))
+ {
+ // here we could check using: ! math::larger(.., ..)
+ if (math::smaller(b_lon_min - p_lon, p_lon_shifted - b_lon_max))
+ {
+ b_lon_min = p_lon;
+ }
+ else
+ {
+ b_lon_max = p_lon_shifted;
+ }
+ }
+ }
+ else if (math::larger(p_lon, b_lon_max))
+ {
+ // in this case, and since p_lon is normalized in the range
+ // (-180, 180], we must have that b_lon_max <= 180
+ if (b_lon_min < 0
+ && math::larger(p_lon - b_lon_max,
+ constants::period() - p_lon + b_lon_min))
+ {
+ b_lon_min = p_lon;
+ b_lon_max += constants::period();
+ }
+ else
+ {
+ b_lon_max = p_lon;
+ }
+ }
+
+ geometry::set<min_corner, 0>(box, b_lon_min);
+ geometry::set<min_corner, 1>(box, b_lat_min);
+ geometry::set<max_corner, 0>(box, b_lon_max);
+ geometry::set<max_corner, 1>(box, b_lat_max);
+
+ point_loop
+ <
+ StrategyLess, StrategyGreater, 2, DimensionCount
+ >::apply(box, point);
+ }
+};
+
+
+}} // namespace detail::expand
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+// Box + point -> new box containing also point
+template
+<
+ typename BoxOut, typename Point,
+ typename StrategyLess, typename StrategyGreater,
+ typename CSTagOut, typename CSTag
+>
+struct expand
+ <
+ BoxOut, Point,
+ StrategyLess, StrategyGreater,
+ box_tag, point_tag,
+ CSTagOut, CSTag
+ > : detail::expand::point_loop
+ <
+ StrategyLess, StrategyGreater, 0, dimension<Point>::value
+ >
+{
+ BOOST_MPL_ASSERT_MSG((boost::is_same<CSTagOut, CSTag>::value),
+ COORDINATE_SYSTEMS_MUST_BE_THE_SAME,
+ (types<CSTagOut, CSTag>()));
+};
+
+template
+<
+ typename BoxOut, typename Point,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ BoxOut, Point,
+ StrategyLess, StrategyGreater,
+ box_tag, point_tag,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::expand::point_loop_on_spheroid
+ <
+ StrategyLess, StrategyGreater, dimension<Point>::value
+ >
+{};
+
+template
+<
+ typename BoxOut, typename Point,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ BoxOut, Point,
+ StrategyLess, StrategyGreater,
+ box_tag, point_tag,
+ geographic_tag, geographic_tag
+ > : detail::expand::point_loop_on_spheroid
+ <
+ StrategyLess, StrategyGreater, dimension<Point>::value
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_POINT_HPP
diff --git a/boost/geometry/algorithms/detail/expand/segment.hpp b/boost/geometry/algorithms/detail/expand/segment.hpp
new file mode 100644
index 0000000000..041c1e175f
--- /dev/null
+++ b/boost/geometry/algorithms/detail/expand/segment.hpp
@@ -0,0 +1,115 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_SEGMENT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_SEGMENT_HPP
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/box.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
+#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
+
+#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
+
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace expand
+{
+
+
+struct segment_on_sphere
+{
+ template <typename Box, typename Segment>
+ static inline void apply(Box& box, Segment const& segment)
+ {
+ Box mbrs[2];
+
+ // compute the envelope of the segment
+ detail::envelope::envelope_segment_on_sphere
+ <
+ dimension<Segment>::value
+ >::apply(segment, mbrs[0]);
+
+ // normalize the box
+ detail::envelope::envelope_box_on_spheroid::apply(box, mbrs[1]);
+
+ // compute the envelope of the two boxes
+ detail::envelope::envelope_range_of_boxes::apply(mbrs, box);
+ }
+};
+
+
+}} // namespace detail::expand
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Box, typename Segment,
+ typename StrategyLess, typename StrategyGreater,
+ typename CSTagOut, typename CSTag
+>
+struct expand
+ <
+ Box, Segment,
+ StrategyLess, StrategyGreater,
+ box_tag, segment_tag,
+ CSTagOut, CSTag
+ > : detail::expand::expand_indexed
+ <
+ 0, dimension<Segment>::value, StrategyLess, StrategyGreater
+ >
+{
+ BOOST_MPL_ASSERT_MSG((boost::is_same<CSTagOut, CSTag>::value),
+ COORDINATE_SYSTEMS_MUST_BE_THE_SAME,
+ (types<CSTagOut, CSTag>()));
+};
+
+template
+<
+ typename Box, typename Segment,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ Box, Segment,
+ StrategyLess, StrategyGreater,
+ box_tag, segment_tag,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::expand::segment_on_sphere
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_SEGMENT_HPP
diff --git a/boost/geometry/algorithms/detail/get_left_turns.hpp b/boost/geometry/algorithms/detail/get_left_turns.hpp
index 0fd243d8e3..95ab98c236 100644
--- a/boost/geometry/algorithms/detail/get_left_turns.hpp
+++ b/boost/geometry/algorithms/detail/get_left_turns.hpp
@@ -9,6 +9,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
@@ -154,8 +156,8 @@ template <typename AngleCollection, typename Turns>
inline void get_left_turns(AngleCollection const& sorted_angles,
Turns& turns)
{
- std::set<int> good_incoming;
- std::set<int> good_outgoing;
+ std::set<std::size_t> good_incoming;
+ std::set<std::size_t> good_outgoing;
for (typename boost::range_iterator<AngleCollection const>::type it =
sorted_angles.begin(); it != sorted_angles.end(); ++it)
@@ -195,7 +197,7 @@ template <typename Point, typename AngleCollection>
inline std::size_t assign_cluster_indices(AngleCollection& sorted, Point const& origin)
{
// Assign same cluster_index for all turns in same direction
- BOOST_ASSERT(boost::size(sorted) >= 4u);
+ BOOST_GEOMETRY_ASSERT(boost::size(sorted) >= 4u);
angle_equal_to<Point> comparator(origin);
typename boost::range_iterator<AngleCollection>::type it = sorted.begin();
@@ -218,7 +220,7 @@ inline std::size_t assign_cluster_indices(AngleCollection& sorted, Point const&
template <typename AngleCollection>
inline void block_turns(AngleCollection& sorted, std::size_t cluster_size)
{
- BOOST_ASSERT(boost::size(sorted) >= 4u && cluster_size > 0);
+ BOOST_GEOMETRY_ASSERT(boost::size(sorted) >= 4u && cluster_size > 0);
std::vector<std::pair<bool, bool> > directions;
for (std::size_t i = 0; i < cluster_size; i++)
@@ -242,14 +244,14 @@ inline void block_turns(AngleCollection& sorted, std::size_t cluster_size)
for (typename boost::range_iterator<AngleCollection>::type it = sorted.begin();
it != sorted.end(); ++it)
{
- int cluster_index = it->cluster_index;
- int previous_index = cluster_index - 1;
+ signed_size_type cluster_index = static_cast<signed_size_type>(it->cluster_index);
+ signed_size_type previous_index = cluster_index - 1;
if (previous_index < 0)
{
previous_index = cluster_size - 1;
}
- int next_index = cluster_index + 1;
- if (next_index >= static_cast<int>(cluster_size))
+ signed_size_type next_index = cluster_index + 1;
+ if (next_index >= static_cast<signed_size_type>(cluster_size))
{
next_index = 0;
}
diff --git a/boost/geometry/algorithms/detail/intersection/interface.hpp b/boost/geometry/algorithms/detail/intersection/interface.hpp
index d57535e61f..2af618d974 100644
--- a/boost/geometry/algorithms/detail/intersection/interface.hpp
+++ b/boost/geometry/algorithms/detail/intersection/interface.hpp
@@ -120,7 +120,8 @@ struct intersection
>::type rescale_policy_type;
rescale_policy_type robust_policy
- = geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
+ = geometry::get_rescale_policy<rescale_policy_type>(geometry1,
+ geometry2);
typedef strategy_intersection
<
@@ -151,8 +152,8 @@ struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
visitor(Geometry2 const& geometry2,
GeometryOut& geometry_out)
- : m_geometry2(geometry2),
- m_geometry_out(geometry_out)
+ : m_geometry2(geometry2)
+ , m_geometry_out(geometry_out)
{}
template <typename Geometry1>
@@ -176,7 +177,7 @@ struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Geometry2 const& geometry2,
GeometryOut& geometry_out)
{
- return apply_visitor(visitor<GeometryOut>(geometry2, geometry_out), geometry1);
+ return boost::apply_visitor(visitor<GeometryOut>(geometry2, geometry_out), geometry1);
}
};
@@ -192,8 +193,8 @@ struct intersection<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
visitor(Geometry1 const& geometry1,
GeometryOut& geometry_out)
- : m_geometry1(geometry1),
- m_geometry_out(geometry_out)
+ : m_geometry1(geometry1)
+ , m_geometry_out(geometry_out)
{}
template <typename Geometry2>
@@ -213,12 +214,11 @@ struct intersection<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
template <typename GeometryOut>
static inline bool
- apply(
- Geometry1 const& geometry1,
+ apply(Geometry1 const& geometry1,
const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2,
GeometryOut& geometry_out)
{
- return apply_visitor(visitor<GeometryOut>(geometry1, geometry_out), geometry2);
+ return boost::apply_visitor(visitor<GeometryOut>(geometry1, geometry_out), geometry2);
}
};
@@ -232,12 +232,11 @@ struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIAN
GeometryOut& m_geometry_out;
visitor(GeometryOut& geometry_out)
- : m_geometry_out(geometry_out)
+ : m_geometry_out(geometry_out)
{}
template <typename Geometry1, typename Geometry2>
- result_type operator()(
- Geometry1 const& geometry1,
+ result_type operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
{
return intersection
@@ -254,12 +253,11 @@ struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIAN
template <typename GeometryOut>
static inline bool
- apply(
- const variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
+ apply(const variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
const variant<BOOST_VARIANT_ENUM_PARAMS(T2)>& geometry2,
GeometryOut& geometry_out)
{
- return apply_visitor(visitor<GeometryOut>(geometry_out), geometry1, geometry2);
+ return boost::apply_visitor(visitor<GeometryOut>(geometry_out), geometry1, geometry2);
}
};
diff --git a/boost/geometry/algorithms/detail/intersection/multi.hpp b/boost/geometry/algorithms/detail/intersection/multi.hpp
index b1f13862fc..88b49b0167 100644
--- a/boost/geometry/algorithms/detail/intersection/multi.hpp
+++ b/boost/geometry/algorithms/detail/intersection/multi.hpp
@@ -1,9 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -36,8 +36,6 @@
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
-// TODO: remove this after moving num_point from multi directory
-#include <boost/geometry/multi/algorithms/num_points.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/algorithms/detail/is_simple/linear.hpp b/boost/geometry/algorithms/detail/is_simple/linear.hpp
index 4f3e875eef..0f77a49498 100644
--- a/boost/geometry/algorithms/detail/is_simple/linear.hpp
+++ b/boost/geometry/algorithms/detail/is_simple/linear.hpp
@@ -13,9 +13,9 @@
#include <algorithm>
#include <deque>
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
@@ -33,7 +33,7 @@
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
-#include <boost/geometry/algorithms/detail/signed_index_type.hpp>
+#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
@@ -60,7 +60,7 @@ namespace detail { namespace is_simple
template <typename Turn>
inline bool check_segment_indices(Turn const& turn,
- signed_index_type last_index)
+ signed_size_type last_index)
{
return
(turn.operations[0].seg_id.segment_index == 0
@@ -89,7 +89,7 @@ public:
template <typename Turn>
inline bool apply(Turn const& turn) const
{
- BOOST_ASSERT(boost::size(m_linestring) > 1);
+ BOOST_GEOMETRY_ASSERT(boost::size(m_linestring) > 1);
return m_is_closed
&& turn.method == overlay::method_none
&& check_segment_indices(turn, boost::size(m_linestring) - 2)
@@ -112,7 +112,7 @@ private:
static inline bool is_boundary_point_of(Point const& point,
Linestring const& linestring)
{
- BOOST_ASSERT(boost::size(linestring) > 1);
+ BOOST_GEOMETRY_ASSERT(boost::size(linestring) > 1);
return
! geometry::equals(range::front(linestring),
range::back(linestring))
@@ -125,7 +125,7 @@ private:
static inline bool is_closing_point_of(Turn const& turn,
Linestring const& linestring)
{
- BOOST_ASSERT(boost::size(linestring) > 1);
+ BOOST_GEOMETRY_ASSERT(boost::size(linestring) > 1);
return
turn.method == overlay::method_none
&&
diff --git a/boost/geometry/algorithms/detail/is_valid/box.hpp b/boost/geometry/algorithms/detail/is_valid/box.hpp
index 139502af78..e7a67252ba 100644
--- a/boost/geometry/algorithms/detail/is_valid/box.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/box.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -12,6 +13,8 @@
#include <cstddef>
+#include <boost/core/ignore_unused.hpp>
+
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
@@ -57,6 +60,8 @@ struct has_valid_corners<Box, 0>
template <typename VisitPolicy>
static inline bool apply(Box const&, VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
return visitor.template apply<no_failure>();
}
};
diff --git a/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp b/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp
index c59139a92e..f08e70242c 100644
--- a/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp
@@ -17,9 +17,9 @@
#include <utility>
#include <vector>
-#include <boost/assert.hpp>
#include <boost/core/addressof.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/policies/compare.hpp>
@@ -104,12 +104,12 @@ private:
, m_parent_id(num_nodes, -1)
{}
- inline signed_index_type parent_id(vertex_handle v) const
+ inline signed_size_type parent_id(vertex_handle v) const
{
return m_parent_id[v->id()];
}
- inline void set_parent_id(vertex_handle v, signed_index_type id)
+ inline void set_parent_id(vertex_handle v, signed_size_type id)
{
m_parent_id[v->id()] = id;
}
@@ -125,7 +125,7 @@ private:
}
private:
std::vector<bool> m_visited;
- std::vector<signed_index_type> m_parent_id;
+ std::vector<signed_size_type> m_parent_id;
};
@@ -145,7 +145,7 @@ private:
= m_neighbors[v->id()].begin();
nit != m_neighbors[v->id()].end(); ++nit)
{
- if ( static_cast<signed_index_type>((*nit)->id()) != data.parent_id(v) )
+ if ( static_cast<signed_size_type>((*nit)->id()) != data.parent_id(v) )
{
if ( data.visited(*nit) )
{
@@ -153,7 +153,7 @@ private:
}
else
{
- data.set_parent_id(*nit, static_cast<signed_index_type>(v->id()));
+ data.set_parent_id(*nit, static_cast<signed_size_type>(v->id()));
stack.push(*nit);
}
}
@@ -173,7 +173,7 @@ public:
// inserts a ring vertex in the graph and returns its handle
// ring id's are zero-based (so the first interior ring has id 1)
- inline vertex_handle add_vertex(signed_index_type id)
+ inline vertex_handle add_vertex(signed_size_type id)
{
return m_vertices.insert(vertex(static_cast<std::size_t>(id))).first;
}
@@ -197,8 +197,8 @@ public:
inline void add_edge(vertex_handle v1, vertex_handle v2)
{
- BOOST_ASSERT( v1 != m_vertices.end() );
- BOOST_ASSERT( v2 != m_vertices.end() );
+ BOOST_GEOMETRY_ASSERT( v1 != m_vertices.end() );
+ BOOST_GEOMETRY_ASSERT( v2 != m_vertices.end() );
m_neighbors[v1->id()].insert(v2);
m_neighbors[v2->id()].insert(v1);
}
diff --git a/boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp b/boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp
index 5878841e70..685a4aac35 100644
--- a/boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp
@@ -10,6 +10,7 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_DUPLICATES_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_DUPLICATES_HPP
+#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/closure.hpp>
@@ -35,8 +36,13 @@ struct has_duplicates
template <typename VisitPolicy>
static inline bool apply(Range const& range, VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
typedef typename closeable_view<Range const, Closure>::type view_type;
- typedef typename boost::range_iterator<view_type const>::type iterator;
+ typedef typename boost::range_const_iterator
+ <
+ view_type const
+ >::type const_iterator;
view_type view(range);
@@ -47,9 +53,10 @@ struct has_duplicates
geometry::equal_to<typename boost::range_value<Range>::type> equal;
- iterator it = boost::begin(view);
- iterator next = ++boost::begin(view);
- for (; next != boost::end(view); ++it, ++next)
+ const_iterator it = boost::const_begin(view);
+ const_iterator next = it;
+ ++next;
+ for (; next != boost::const_end(view); ++it, ++next)
{
if ( equal(*it, *next) )
{
diff --git a/boost/geometry/algorithms/detail/is_valid/has_spikes.hpp b/boost/geometry/algorithms/detail/is_valid/has_spikes.hpp
index 090c026e8b..aa90e52db6 100644
--- a/boost/geometry/algorithms/detail/is_valid/has_spikes.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/has_spikes.hpp
@@ -12,9 +12,11 @@
#include <algorithm>
+#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/is_same.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -76,10 +78,23 @@ struct not_equal_to
template <typename Range, closure_selector Closure>
struct has_spikes
{
+ template <typename Iterator>
+ static inline Iterator find_different_from_first(Iterator first,
+ Iterator last)
+ {
+ typedef not_equal_to<typename point_type<Range>::type> not_equal;
+
+ BOOST_GEOMETRY_ASSERT(first != last);
+
+ Iterator second = first;
+ ++second;
+ return std::find_if(second, last, not_equal(*first));
+ }
+
template <typename VisitPolicy>
static inline bool apply(Range const& range, VisitPolicy& visitor)
{
- typedef not_equal_to<typename point_type<Range>::type> not_equal;
+ boost::ignore_unused(visitor);
typedef typename closeable_view<Range const, Closure>::type view_type;
typedef typename boost::range_iterator<view_type const>::type iterator;
@@ -91,23 +106,23 @@ struct has_spikes
iterator prev = boost::begin(view);
- iterator cur = std::find_if(prev, boost::end(view), not_equal(*prev));
- if ( cur == boost::end(view) )
+ iterator cur = find_different_from_first(prev, boost::end(view));
+ if (cur == boost::end(view))
{
// the range has only one distinct point, so it
// cannot have a spike
return ! visitor.template apply<no_failure>();
}
- iterator next = std::find_if(cur, boost::end(view), not_equal(*cur));
- if ( next == boost::end(view) )
+ iterator next = find_different_from_first(cur, boost::end(view));
+ if (next == boost::end(view))
{
// the range has only two distinct points, so it
// cannot have a spike
return ! visitor.template apply<no_failure>();
}
- while ( next != boost::end(view) )
+ while (next != boost::end(view))
{
if ( geometry::detail::point_is_spike_or_equal(*prev,
*next,
@@ -118,20 +133,19 @@ struct has_spikes
}
prev = cur;
cur = next;
- next = std::find_if(cur, boost::end(view), not_equal(*cur));
+ next = find_different_from_first(cur, boost::end(view));
}
- if ( geometry::equals(range::front(view), range::back(view)) )
+ if (geometry::equals(range::front(view), range::back(view)))
{
iterator cur = boost::begin(view);
typename boost::range_reverse_iterator
<
view_type const
- >::type prev = std::find_if(boost::rbegin(view),
- boost::rend(view),
- not_equal(range::back(view)));
- iterator next =
- std::find_if(cur, boost::end(view), not_equal(*cur));
+ >::type prev = find_different_from_first(boost::rbegin(view),
+ boost::rend(view));
+
+ iterator next = find_different_from_first(cur, boost::end(view));
if (detail::point_is_spike_or_equal(*prev, *next, *cur))
{
return
diff --git a/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp b/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp
index ecbc4782b2..0a81213743 100644
--- a/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp
@@ -12,9 +12,10 @@
#include <vector>
-#include <boost/assert.hpp>
+#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/policies/predicate_based_interrupt_policy.hpp>
@@ -73,6 +74,8 @@ public:
Turns& turns,
VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry);
@@ -88,7 +91,7 @@ public:
if (interrupt_policy.has_intersections)
{
- BOOST_ASSERT(! boost::empty(turns));
+ BOOST_GEOMETRY_ASSERT(! boost::empty(turns));
return visitor.template apply<failure_self_intersections>(turns);
}
else
diff --git a/boost/geometry/algorithms/detail/is_valid/interface.hpp b/boost/geometry/algorithms/detail/is_valid/interface.hpp
index f83b09c437..0ec13b1b38 100644
--- a/boost/geometry/algorithms/detail/is_valid/interface.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/interface.hpp
@@ -97,7 +97,7 @@ template <typename Geometry>
inline bool is_valid(Geometry const& geometry)
{
is_valid_default_policy<> policy_visitor;
- return is_valid(geometry, policy_visitor);
+ return geometry::is_valid(geometry, policy_visitor);
}
@@ -121,7 +121,7 @@ template <typename Geometry>
inline bool is_valid(Geometry const& geometry, validity_failure_type& failure)
{
failure_type_policy<> policy_visitor;
- bool result = is_valid(geometry, policy_visitor);
+ bool result = geometry::is_valid(geometry, policy_visitor);
failure = policy_visitor.failure();
return result;
}
@@ -148,7 +148,7 @@ inline bool is_valid(Geometry const& geometry, std::string& message)
{
std::ostringstream stream;
failing_reason_policy<> policy_visitor(stream);
- bool result = is_valid(geometry, policy_visitor);
+ bool result = geometry::is_valid(geometry, policy_visitor);
message = stream.str();
return result;
}
diff --git a/boost/geometry/algorithms/detail/is_valid/linear.hpp b/boost/geometry/algorithms/detail/is_valid/linear.hpp
index 69243563ec..e30064faf0 100644
--- a/boost/geometry/algorithms/detail/is_valid/linear.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/linear.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -18,6 +19,7 @@
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/algorithms/equals.hpp>
@@ -138,7 +140,8 @@ public:
static inline bool apply(MultiLinestring const& multilinestring,
VisitPolicy& visitor)
{
- if (AllowEmptyMultiGeometries && boost::empty(multilinestring))
+ if (BOOST_GEOMETRY_CONDITION(
+ AllowEmptyMultiGeometries && boost::empty(multilinestring)))
{
return visitor.template apply<no_failure>();
}
diff --git a/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp b/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
index 9362bfca0e..0025445c2c 100644
--- a/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -13,6 +14,7 @@
#include <deque>
#include <vector>
+#include <boost/core/ignore_unused.hpp>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/range.hpp>
@@ -21,6 +23,7 @@
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/geometries/box.hpp>
@@ -80,8 +83,10 @@ private:
TurnIterator turns_beyond,
VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
// collect all polygons that have turns
- std::set<signed_index_type> multi_indices;
+ std::set<signed_size_type> multi_indices;
for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit)
{
multi_indices.insert(tit->operations[0].seg_id.multi_index);
@@ -90,7 +95,7 @@ private:
// put polygon iterators without turns in a vector
std::vector<PolygonIterator> polygon_iterators;
- signed_index_type multi_index = 0;
+ signed_size_type multi_index = 0;
for (PolygonIterator it = polygons_first; it != polygons_beyond;
++it, ++multi_index)
{
@@ -124,7 +129,7 @@ private:
class has_multi_index
{
public:
- has_multi_index(signed_index_type multi_index)
+ has_multi_index(signed_size_type multi_index)
: m_multi_index(multi_index)
{}
@@ -136,7 +141,7 @@ private:
}
private:
- signed_index_type const m_multi_index;
+ signed_size_type const m_multi_index;
};
@@ -156,7 +161,7 @@ private:
TurnIterator turns_beyond,
VisitPolicy& visitor)
{
- signed_index_type multi_index = 0;
+ signed_size_type multi_index = 0;
for (PolygonIterator it = polygons_first; it != polygons_beyond;
++it, ++multi_index)
{
@@ -250,7 +255,8 @@ public:
{
typedef debug_validity_phase<MultiPolygon> debug_phase;
- if (AllowEmptyMultiGeometries && boost::empty(multipolygon))
+ if (BOOST_GEOMETRY_CONDITION(
+ AllowEmptyMultiGeometries && boost::empty(multipolygon)))
{
return visitor.template apply<no_failure>();
}
diff --git a/boost/geometry/algorithms/detail/is_valid/pointlike.hpp b/boost/geometry/algorithms/detail/is_valid/pointlike.hpp
index 8e5ebaadcc..e51ab74643 100644
--- a/boost/geometry/algorithms/detail/is_valid/pointlike.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/pointlike.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -10,6 +11,7 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_POINTLIKE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_POINTLIKE_HPP
+#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -17,6 +19,8 @@
#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
+#include <boost/geometry/util/condition.hpp>
+
namespace boost { namespace geometry
{
@@ -34,6 +38,7 @@ struct is_valid<Point, point_tag>
template <typename VisitPolicy>
static inline bool apply(Point const&, VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
return visitor.template apply<no_failure>();
}
};
@@ -51,7 +56,10 @@ struct is_valid<MultiPoint, multi_point_tag, AllowEmptyMultiGeometries>
static inline bool apply(MultiPoint const& multipoint,
VisitPolicy& visitor)
{
- if (AllowEmptyMultiGeometries || boost::size(multipoint) > 0)
+ boost::ignore_unused(multipoint, visitor);
+
+ if (BOOST_GEOMETRY_CONDITION(
+ AllowEmptyMultiGeometries || !boost::empty(multipoint)))
{
// we allow empty multi-geometries, so an empty multipoint
// is considered valid
diff --git a/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/boost/geometry/algorithms/detail/is_valid/polygon.hpp
index 17eefd226f..6e87273aa1 100644
--- a/boost/geometry/algorithms/detail/is_valid/polygon.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/polygon.hpp
@@ -18,9 +18,10 @@
#include <set>
#include <vector>
-#include <boost/assert.hpp>
+#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/ring_type.hpp>
@@ -185,24 +186,26 @@ protected:
TurnIterator turns_beyond,
VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
// collect the interior ring indices that have turns with the
// exterior ring
- std::set<signed_index_type> ring_indices;
+ std::set<signed_size_type> ring_indices;
for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit)
{
if (tit->operations[0].seg_id.ring_index == -1)
{
- BOOST_ASSERT(tit->operations[1].seg_id.ring_index != -1);
+ BOOST_GEOMETRY_ASSERT(tit->operations[1].seg_id.ring_index != -1);
ring_indices.insert(tit->operations[1].seg_id.ring_index);
}
else if (tit->operations[1].seg_id.ring_index == -1)
{
- BOOST_ASSERT(tit->operations[0].seg_id.ring_index != -1);
+ BOOST_GEOMETRY_ASSERT(tit->operations[0].seg_id.ring_index != -1);
ring_indices.insert(tit->operations[0].seg_id.ring_index);
}
}
- signed_index_type ring_index = 0;
+ signed_size_type ring_index = 0;
for (RingIterator it = rings_first; it != rings_beyond;
++it, ++ring_index)
{
@@ -303,6 +306,8 @@ protected:
TurnIterator beyond,
VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
typedef typename std::iterator_traits
<
TurnIterator
diff --git a/boost/geometry/algorithms/detail/is_valid/ring.hpp b/boost/geometry/algorithms/detail/is_valid/ring.hpp
index c663a96d28..c35e843418 100644
--- a/boost/geometry/algorithms/detail/is_valid/ring.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/ring.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -12,6 +13,8 @@
#include <deque>
+#include <boost/core/ignore_unused.hpp>
+
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_order.hpp>
@@ -53,6 +56,8 @@ struct is_topologically_closed
template <typename VisitPolicy>
static inline bool apply(Ring const&, VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
return visitor.template apply<no_failure>();
}
};
@@ -63,6 +68,8 @@ struct is_topologically_closed<Ring, closed>
template <typename VisitPolicy>
static inline bool apply(Ring const& ring, VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
if (geometry::equals(range::front(ring), range::back(ring)))
{
return visitor.template apply<no_failure>();
@@ -112,6 +119,8 @@ struct is_properly_oriented
template <typename VisitPolicy>
static inline bool apply(Ring const& ring, VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
typename ring_area_predicate
<
area_result_type, IsInteriorRing
diff --git a/boost/geometry/algorithms/detail/is_valid/segment.hpp b/boost/geometry/algorithms/detail/is_valid/segment.hpp
index 0b60890dc0..a93d2bfe9e 100644
--- a/boost/geometry/algorithms/detail/is_valid/segment.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/segment.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -10,6 +11,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_SEGMENT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_SEGMENT_HPP
+#include <boost/core/ignore_unused.hpp>
+
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -44,6 +47,8 @@ struct is_valid<Segment, segment_tag>
template <typename VisitPolicy>
static inline bool apply(Segment const& segment, VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
typename point_type<Segment>::type p[2];
detail::assign_point_from_index<0>(segment, p[0]);
detail::assign_point_from_index<1>(segment, p[1]);
diff --git a/boost/geometry/algorithms/detail/max_interval_gap.hpp b/boost/geometry/algorithms/detail/max_interval_gap.hpp
new file mode 100644
index 0000000000..e8a70a6b5f
--- /dev/null
+++ b/boost/geometry/algorithms/detail/max_interval_gap.hpp
@@ -0,0 +1,278 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_MAX_INTERVAL_GAP_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_MAX_INTERVAL_GAP_HPP
+
+#include <cstddef>
+#include <queue>
+#include <utility>
+#include <vector>
+
+#include <boost/core/ref.hpp>
+#include <boost/range.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/algorithms/detail/sweep.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace max_interval_gap
+{
+
+// the class Interval must provide the following:
+// * must define the type value_type
+// * must define the type difference_type
+// * must have the methods:
+// value_type get<Index>() const
+// difference_type length() const
+// where an Index value of 0 (resp., 1) refers to the left (resp.,
+// right) endpoint of the interval
+
+template <typename Interval>
+class sweep_event
+{
+public:
+ typedef Interval interval_type;
+ typedef typename Interval::value_type time_type;
+
+ sweep_event(Interval const& interval, bool start_event = true)
+ : m_interval(boost::cref(interval))
+ , m_start_event(start_event)
+ {}
+
+ inline bool is_start_event() const
+ {
+ return m_start_event;
+ }
+
+ inline interval_type const& interval() const
+ {
+ return m_interval;
+ }
+
+ inline time_type time() const
+ {
+ return (m_start_event)
+ ? interval().template get<0>()
+ : interval().template get<1>();
+ }
+
+ inline bool operator<(sweep_event const& other) const
+ {
+ if (! math::equals(time(), other.time()))
+ {
+ return time() < other.time();
+ }
+ // a start-event is before an end-event with the same event time
+ return is_start_event() && ! other.is_start_event();
+ }
+
+private:
+ boost::reference_wrapper<Interval const> m_interval;
+ bool m_start_event;
+};
+
+template <typename Event>
+struct event_greater
+{
+ inline bool operator()(Event const& event1, Event const& event2) const
+ {
+ return event2 < event1;
+ }
+};
+
+
+struct initialization_visitor
+{
+ template <typename Range, typename PriorityQueue, typename EventVisitor>
+ static inline void apply(Range const& range,
+ PriorityQueue& queue,
+ EventVisitor&)
+ {
+ BOOST_GEOMETRY_ASSERT(queue.empty());
+
+ // it is faster to build the queue directly from the entire
+ // range, rather than insert elements one after the other
+ PriorityQueue pq(boost::begin(range), boost::end(range));
+ std::swap(pq, queue);
+ }
+};
+
+
+template <typename Event>
+class event_visitor
+{
+ typedef typename Event::time_type event_time_type;
+ typedef typename Event::interval_type::difference_type difference_type;
+
+ typedef typename boost::remove_const
+ <
+ typename boost::remove_reference
+ <
+ event_time_type
+ >::type
+ >::type bare_time_type;
+
+
+public:
+ event_visitor()
+ : m_overlap_count(0)
+ , m_max_gap_left(0)
+ , m_max_gap_right(0)
+ {}
+
+ template <typename PriorityQueue>
+ inline void apply(Event const& event, PriorityQueue& queue)
+ {
+ if (event.is_start_event())
+ {
+ ++m_overlap_count;
+ queue.push(Event(event.interval(), false));
+ }
+ else
+ {
+ --m_overlap_count;
+ if (m_overlap_count == 0 && ! queue.empty())
+ {
+ // we may have a gap
+ BOOST_GEOMETRY_ASSERT(queue.top().is_start_event());
+
+ event_time_type next_event_time
+ = queue.top().interval().template get<0>();
+ difference_type gap = next_event_time - event.time();
+ if (gap > max_gap())
+ {
+ m_max_gap_left = event.time();
+ m_max_gap_right = next_event_time;
+ }
+ }
+ }
+ }
+
+ bare_time_type const& max_gap_left() const
+ {
+ return m_max_gap_left;
+ }
+
+ bare_time_type const& max_gap_right() const
+ {
+ return m_max_gap_right;
+ }
+
+ difference_type max_gap() const
+ {
+ return m_max_gap_right - m_max_gap_left;
+ }
+
+private:
+ std::size_t m_overlap_count;
+ bare_time_type m_max_gap_left, m_max_gap_right;
+};
+
+}} // namespace detail::max_interval_gap
+#endif // DOXYGEN_NO_DETAIL
+
+
+// Given a range of intervals I1, I2, ..., In, maximum_gap() returns
+// the maximum length of an interval M that satisfies the following
+// properties:
+//
+// 1. M.left >= min(I1, I2, ..., In)
+// 2. M.right <= max(I1, I2, ..., In)
+// 3. intersection(interior(M), Ik) is the empty set for all k=1, ..., n
+// 4. length(M) is maximal
+//
+// where M.left and M.right denote the left and right extreme values
+// for the interval M, and length(M) is equal to M.right - M.left.
+//
+// If M does not exist (or, alternatively, M is identified as the
+// empty set), 0 is returned.
+//
+// The algorithm proceeds for performing a sweep: the left endpoints
+// are inserted into a min-priority queue with the priority being the
+// value of the endpoint. The sweep algorithm maintains an "overlap
+// counter" that counts the number of overlaping intervals at any
+// specific sweep-time value.
+// There are two types of events encountered during the sweep:
+// (a) a start event: the left endpoint of an interval is found.
+// In this case the overlap count is increased by one and the
+// right endpoint of the interval in inserted into the event queue
+// (b) an end event: the right endpoint of an interval is found.
+// In this case the overlap count is decreased by one. If the
+// updated overlap count is 0, then we could expect to have a gap
+// in-between intervals. This gap is measured as the (absolute)
+// distance of the current interval right endpoint (being
+// processed) to the upcoming left endpoint of the next interval
+// to be processed (if such an interval exists). If the measured
+// gap is greater than the current maximum gap, it is recorded.
+// The initial maximum gap is initialized to 0. This value is returned
+// if no gap is found during the sweeping procedure.
+
+template <typename RangeOfIntervals, typename T>
+inline typename boost::range_value<RangeOfIntervals>::type::difference_type
+maximum_gap(RangeOfIntervals const& range_of_intervals,
+ T& max_gap_left, T& max_gap_right)
+{
+ typedef typename boost::range_value<RangeOfIntervals>::type interval_type;
+ typedef detail::max_interval_gap::sweep_event<interval_type> event_type;
+
+ // create a min-priority queue for the events
+ std::priority_queue
+ <
+ event_type,
+ std::vector<event_type>,
+ detail::max_interval_gap::event_greater<event_type>
+ > queue;
+
+ // define initialization and event-process visitors
+ detail::max_interval_gap::initialization_visitor init_visitor;
+ detail::max_interval_gap::event_visitor<event_type> sweep_visitor;
+
+ // perform the sweep
+ geometry::sweep(range_of_intervals,
+ queue,
+ init_visitor,
+ sweep_visitor);
+
+ max_gap_left = sweep_visitor.max_gap_left();
+ max_gap_right = sweep_visitor.max_gap_right();
+ return sweep_visitor.max_gap();
+}
+
+template <typename RangeOfIntervals>
+inline typename boost::range_value<RangeOfIntervals>::type::difference_type
+maximum_gap(RangeOfIntervals const& range_of_intervals)
+{
+ typedef typename boost::remove_const
+ <
+ typename boost::remove_reference
+ <
+ typename boost::range_value
+ <
+ RangeOfIntervals
+ >::type::value_type
+ >::type
+ >::type value_type;
+
+ value_type left, right;
+
+ return maximum_gap(range_of_intervals, left, right);
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_MAX_INTERVAL_GAP_HPP
diff --git a/boost/geometry/algorithms/detail/normalize.hpp b/boost/geometry/algorithms/detail/normalize.hpp
new file mode 100644
index 0000000000..913fe324b7
--- /dev/null
+++ b/boost/geometry/algorithms/detail/normalize.hpp
@@ -0,0 +1,294 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
+#include <boost/geometry/util/normalize_spheroidal_box_coordinates.hpp>
+
+#include <boost/geometry/views/detail/indexed_point_view.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace normalization
+{
+
+
+struct do_nothing
+{
+ template <typename GeometryIn, typename GeometryOut>
+ static inline void apply(GeometryIn const&, GeometryOut&)
+ {
+ }
+};
+
+
+template <std::size_t Dimension, std::size_t DimensionCount>
+struct assign_loop
+{
+ template <typename CoordinateType, typename PointIn, typename PointOut>
+ static inline void apply(CoordinateType const& longitude,
+ CoordinateType const& latitude,
+ PointIn const& point_in,
+ PointOut& point_out)
+ {
+ geometry::set<Dimension>(point_out, boost::numeric_cast
+ <
+ typename coordinate_type<PointOut>::type
+ >(geometry::get<Dimension>(point_in)));
+
+ assign_loop
+ <
+ Dimension + 1, DimensionCount
+ >::apply(longitude, latitude, point_in, point_out);
+ }
+};
+
+template <std::size_t DimensionCount>
+struct assign_loop<DimensionCount, DimensionCount>
+{
+ template <typename CoordinateType, typename PointIn, typename PointOut>
+ static inline void apply(CoordinateType const&,
+ CoordinateType const&,
+ PointIn const&,
+ PointOut&)
+ {
+ }
+};
+
+template <std::size_t DimensionCount>
+struct assign_loop<0, DimensionCount>
+{
+ template <typename CoordinateType, typename PointIn, typename PointOut>
+ static inline void apply(CoordinateType const& longitude,
+ CoordinateType const& latitude,
+ PointIn const& point_in,
+ PointOut& point_out)
+ {
+ geometry::set<0>(point_out, boost::numeric_cast
+ <
+ typename coordinate_type<PointOut>::type
+ >(longitude));
+
+ assign_loop
+ <
+ 1, DimensionCount
+ >::apply(longitude, latitude, point_in, point_out);
+ }
+};
+
+template <std::size_t DimensionCount>
+struct assign_loop<1, DimensionCount>
+{
+ template <typename CoordinateType, typename PointIn, typename PointOut>
+ static inline void apply(CoordinateType const& longitude,
+ CoordinateType const& latitude,
+ PointIn const& point_in,
+ PointOut& point_out)
+ {
+ geometry::set<1>(point_out, boost::numeric_cast
+ <
+ typename coordinate_type<PointOut>::type
+ >(latitude));
+
+ assign_loop
+ <
+ 2, DimensionCount
+ >::apply(longitude, latitude, point_in, point_out);
+ }
+};
+
+
+template <typename PointIn, typename PointOut>
+struct normalize_point
+{
+ static inline void apply(PointIn const& point_in, PointOut& point_out)
+ {
+ typedef typename coordinate_type<PointIn>::type in_coordinate_type;
+
+ in_coordinate_type longitude = geometry::get<0>(point_in);
+ in_coordinate_type latitude = geometry::get<1>(point_in);
+
+ math::normalize_spheroidal_coordinates
+ <
+ typename coordinate_system<PointIn>::type::units,
+ in_coordinate_type
+ >(longitude, latitude);
+
+ assign_loop
+ <
+ 0, dimension<PointIn>::value
+ >::apply(longitude, latitude, point_in, point_out);
+ }
+};
+
+
+template <typename BoxIn, typename BoxOut>
+class normalize_box
+{
+ template <typename UnitsIn, typename UnitsOut, typename CoordinateInType>
+ static inline void apply_to_coordinates(CoordinateInType& lon_min,
+ CoordinateInType& lat_min,
+ CoordinateInType& lon_max,
+ CoordinateInType& lat_max,
+ BoxIn const& box_in,
+ BoxOut& box_out)
+ {
+ detail::indexed_point_view<BoxOut, min_corner> p_min_out(box_out);
+ assign_loop
+ <
+ 0, dimension<BoxIn>::value
+ >::apply(lon_min,
+ lat_min,
+ detail::indexed_point_view
+ <
+ BoxIn const, min_corner
+ >(box_in),
+ p_min_out);
+
+ detail::indexed_point_view<BoxOut, max_corner> p_max_out(box_out);
+ assign_loop
+ <
+ 0, dimension<BoxIn>::value
+ >::apply(lon_max,
+ lat_max,
+ detail::indexed_point_view
+ <
+ BoxIn const, max_corner
+ >(box_in),
+ p_max_out);
+ }
+
+public:
+ static inline void apply(BoxIn const& box_in, BoxOut& box_out)
+ {
+ typedef typename coordinate_type<BoxIn>::type in_coordinate_type;
+
+ in_coordinate_type lon_min = geometry::get<min_corner, 0>(box_in);
+ in_coordinate_type lat_min = geometry::get<min_corner, 1>(box_in);
+ in_coordinate_type lon_max = geometry::get<max_corner, 0>(box_in);
+ in_coordinate_type lat_max = geometry::get<max_corner, 1>(box_in);
+
+ math::normalize_spheroidal_box_coordinates
+ <
+ typename coordinate_system<BoxIn>::type::units,
+ in_coordinate_type
+ >(lon_min, lat_min, lon_max, lat_max);
+
+ apply_to_coordinates
+ <
+ typename coordinate_system<BoxIn>::type::units,
+ typename coordinate_system<BoxOut>::type::units
+ >(lon_min, lat_min, lon_max, lat_max, box_in, box_out);
+ }
+};
+
+
+}} // namespace detail::normalization
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename GeometryIn,
+ typename GeometryOut,
+ typename TagIn = typename tag<GeometryIn>::type,
+ typename TagOut = typename tag<GeometryOut>::type,
+ typename CSTagIn = typename cs_tag<GeometryIn>::type,
+ typename CSTagOut = typename cs_tag<GeometryOut>::type
+>
+struct normalize : detail::normalization::do_nothing
+{};
+
+
+template <typename PointIn, typename PointOut>
+struct normalize
+ <
+ PointIn, PointOut, point_tag, point_tag,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::normalization::normalize_point<PointIn, PointOut>
+{};
+
+
+template <typename PointIn, typename PointOut>
+struct normalize
+ <
+ PointIn, PointOut, point_tag, point_tag, geographic_tag, geographic_tag
+ > : detail::normalization::normalize_point<PointIn, PointOut>
+{};
+
+
+template <typename BoxIn, typename BoxOut>
+struct normalize
+ <
+ BoxIn, BoxOut, box_tag, box_tag,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::normalization::normalize_box<BoxIn, BoxOut>
+{};
+
+
+template <typename BoxIn, typename BoxOut>
+struct normalize
+ <
+ BoxIn, BoxOut, box_tag, box_tag, geographic_tag, geographic_tag
+ > : detail::normalization::normalize_box<BoxIn, BoxOut>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template <typename GeometryIn, typename GeometryOut>
+inline void normalize(GeometryIn const& geometry_in, GeometryOut& geometry_out)
+{
+ dispatch::normalize
+ <
+ GeometryIn, GeometryOut
+ >::apply(geometry_in, geometry_out);
+}
+
+template <typename GeometryOut, typename GeometryIn>
+inline GeometryOut return_normalized(GeometryIn const& geometry_in)
+{
+ GeometryOut geometry_out;
+ detail::normalize(geometry_in, geometry_out);
+ return geometry_out;
+}
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP
diff --git a/boost/geometry/algorithms/detail/occupation_info.hpp b/boost/geometry/algorithms/detail/occupation_info.hpp
index 002c946170..4048d59d75 100644
--- a/boost/geometry/algorithms/detail/occupation_info.hpp
+++ b/boost/geometry/algorithms/detail/occupation_info.hpp
@@ -12,6 +12,7 @@
#include <algorithm>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
@@ -36,7 +37,7 @@ struct angle_info
typedef Point point_type;
segment_identifier seg_id;
- int turn_index;
+ std::size_t turn_index;
int operation_index;
std::size_t cluster_index;
Point intersection_point;
@@ -57,7 +58,7 @@ class occupation_info
public :
typedef std::vector<AngleInfo> collection_type;
- int count;
+ std::size_t count;
inline occupation_info()
: count(0)
@@ -67,7 +68,7 @@ public :
inline void add(RobustPoint const& incoming_point,
RobustPoint const& outgoing_point,
RobustPoint const& intersection_point,
- int turn_index, int operation_index,
+ std::size_t turn_index, int operation_index,
segment_identifier const& seg_id)
{
geometry::equal_to<RobustPoint> comparator;
@@ -125,11 +126,19 @@ private :
};
template<typename Pieces>
-inline void move_index(Pieces const& pieces, int& index, int& piece_index, int direction)
+inline void move_index(Pieces const& pieces, signed_size_type& index, signed_size_type& piece_index, int direction)
{
- BOOST_ASSERT(direction == 1 || direction == -1);
- BOOST_ASSERT(piece_index >= 0 && piece_index < static_cast<int>(boost::size(pieces)) );
- BOOST_ASSERT(index >= 0 && index < static_cast<int>(boost::size(pieces[piece_index].robust_ring)));
+ BOOST_GEOMETRY_ASSERT(direction == 1 || direction == -1);
+ BOOST_GEOMETRY_ASSERT(
+ piece_index >= 0
+ && piece_index < static_cast<signed_size_type>(boost::size(pieces)) );
+ BOOST_GEOMETRY_ASSERT(
+ index >= 0
+ && index < static_cast<signed_size_type>(boost::size(pieces[piece_index].robust_ring)));
+
+ // NOTE: both index and piece_index must be in valid range
+ // this means that then they could be of type std::size_t
+ // if the code below was refactored
index += direction;
if (direction == -1 && index < 0)
@@ -142,10 +151,10 @@ inline void move_index(Pieces const& pieces, int& index, int& piece_index, int d
index = boost::size(pieces[piece_index].robust_ring) - 1;
}
if (direction == 1
- && index >= static_cast<int>(boost::size(pieces[piece_index].robust_ring)))
+ && index >= static_cast<signed_size_type>(boost::size(pieces[piece_index].robust_ring)))
{
piece_index++;
- if (piece_index >= static_cast<int>(boost::size(pieces)))
+ if (piece_index >= static_cast<signed_size_type>(boost::size(pieces)))
{
piece_index = 0;
}
@@ -176,8 +185,8 @@ inline void add_incoming_and_outgoing_angles(
RobustPoint direction_points[2];
for (int i = 0; i < 2; i++)
{
- int index = turn.operations[operation_index].index_in_robust_ring;
- int piece_index = turn.operations[operation_index].piece_index;
+ signed_size_type index = turn.operations[operation_index].index_in_robust_ring;
+ signed_size_type piece_index = turn.operations[operation_index].piece_index;
while(comparator(pieces[piece_index].robust_ring[index], intersection_point))
{
move_index(pieces, index, piece_index, i == 0 ? -1 : 1);
diff --git a/boost/geometry/algorithms/detail/overlay/add_rings.hpp b/boost/geometry/algorithms/detail/overlay/add_rings.hpp
index 5ff0b57d6e..fcb240941f 100644
--- a/boost/geometry/algorithms/detail/overlay/add_rings.hpp
+++ b/boost/geometry/algorithms/detail/overlay/add_rings.hpp
@@ -9,6 +9,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
+#include <boost/range.hpp>
+
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/detail/overlay/convert_ring.hpp>
diff --git a/boost/geometry/algorithms/detail/overlay/assign_parents.hpp b/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
index 178f3825d7..047eb4993e 100644
--- a/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
+++ b/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
@@ -9,6 +9,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ASSIGN_PARENTS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ASSIGN_PARENTS_HPP
+#include <boost/range.hpp>
+
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/expand.hpp>
diff --git a/boost/geometry/algorithms/detail/overlay/check_enrich.hpp b/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
index 03be18e07a..25e442982b 100644
--- a/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
+++ b/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
@@ -12,12 +12,8 @@
#include <cstddef>
-
-#include <boost/assert.hpp>
#include <boost/range.hpp>
-
-
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
diff --git a/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp b/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
index fc4f657322..b1a25c9f5e 100644
--- a/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
+++ b/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -160,10 +165,12 @@ template
typename OutputLinestring,
typename OutputIterator,
typename Range,
+ typename RobustPolicy,
typename Box,
typename Strategy
>
OutputIterator clip_range_with_box(Box const& b, Range const& range,
+ RobustPolicy const&,
OutputIterator out, Strategy const& strategy)
{
if (boost::begin(range) == boost::end(range))
diff --git a/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp b/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
index 13e0a5a51e..dbf3770357 100644
--- a/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
+++ b/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
@@ -11,10 +11,10 @@
#include <boost/array.hpp>
-#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
@@ -43,8 +43,8 @@ struct copy_segment_point_range
{
detail::normalized_view<Range const> view(range);
- signed_index_type const n = boost::size(view);
- signed_index_type index = seg_id.segment_index;
+ signed_size_type const n = boost::size(view);
+ signed_size_type index = seg_id.segment_index;
if (second)
{
index++;
@@ -54,7 +54,7 @@ struct copy_segment_point_range
}
}
- BOOST_ASSERT(index >= 0 && index < n);
+ BOOST_GEOMETRY_ASSERT(index >= 0 && index < n);
geometry::convert(*(boost::begin(view) + index), point);
return true;
@@ -95,7 +95,7 @@ struct copy_segment_point_box
SegmentIdentifier const& seg_id, bool second,
PointOut& point)
{
- signed_index_type index = seg_id.segment_index;
+ signed_size_type index = seg_id.segment_index;
if (second)
{
index++;
@@ -123,7 +123,7 @@ struct copy_segment_point_multi
PointOut& point)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
seg_id.multi_index >= 0
&& seg_id.multi_index < int(boost::size(multi))
@@ -306,7 +306,7 @@ inline bool copy_segment_point(Geometry1 const& geometry1, Geometry2 const& geom
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
- BOOST_ASSERT(seg_id.source_index == 0 || seg_id.source_index == 1);
+ BOOST_GEOMETRY_ASSERT(seg_id.source_index == 0 || seg_id.source_index == 1);
if (seg_id.source_index == 0)
{
diff --git a/boost/geometry/algorithms/detail/overlay/copy_segments.hpp b/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
index ceeb1a3b8b..2eefa03c67 100644
--- a/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
+++ b/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
@@ -19,14 +19,11 @@
#include <vector>
#include <boost/array.hpp>
-#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/integral_constant.hpp>
-#include <boost/geometry/core/tags.hpp>
-
-#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/ring_type.hpp>
@@ -64,7 +61,7 @@ struct copy_segments_ring
>
static inline void apply(Ring const& ring,
SegmentIdentifier const& seg_id,
- signed_index_type to_index,
+ signed_size_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
@@ -93,10 +90,10 @@ struct copy_segments_ring
// So we use the ever-circling iterator and determine when to step out
- signed_index_type const from_index = seg_id.segment_index + 1;
+ signed_size_type const from_index = seg_id.segment_index + 1;
// Sanity check
- BOOST_ASSERT(from_index < static_cast<signed_index_type>(boost::size(view)));
+ BOOST_GEOMETRY_ASSERT(from_index < static_cast<signed_size_type>(boost::size(view)));
ec_iterator it(boost::begin(view), boost::end(view),
boost::begin(view) + from_index);
@@ -104,12 +101,12 @@ struct copy_segments_ring
// [2..4] -> 4 - 2 + 1 = 3 -> {2,3,4} -> OK
// [4..2],size=6 -> 6 - 4 + 2 + 1 = 5 -> {4,5,0,1,2} -> OK
// [1..1], travel the whole ring round
- signed_index_type const count = from_index <= to_index
+ signed_size_type const count = from_index <= to_index
? to_index - from_index + 1
- : static_cast<signed_index_type>(boost::size(view))
+ : static_cast<signed_size_type>(boost::size(view))
- from_index + to_index + 1;
- for (signed_index_type i = 0; i < count; ++i, ++it)
+ for (signed_size_type i = 0; i < count; ++i, ++it)
{
detail::overlay::append_no_dups_or_spikes(current_output, *it, robust_policy);
}
@@ -151,26 +148,26 @@ public:
>
static inline void apply(LineString const& ls,
SegmentIdentifier const& seg_id,
- signed_index_type to_index,
+ signed_size_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
- signed_index_type const from_index = seg_id.segment_index + 1;
+ signed_size_type const from_index = seg_id.segment_index + 1;
// Sanity check
if ( from_index > to_index
|| from_index < 0
- || to_index >= static_cast<signed_index_type>(boost::size(ls)) )
+ || to_index >= static_cast<signed_size_type>(boost::size(ls)) )
{
return;
}
- signed_index_type const count = to_index - from_index + 1;
+ signed_size_type const count = to_index - from_index + 1;
typename boost::range_iterator<LineString const>::type
it = boost::begin(ls) + from_index;
- for (signed_index_type i = 0; i < count; ++i, ++it)
+ for (signed_size_type i = 0; i < count; ++i, ++it)
{
append_to_output(current_output, *it, robust_policy,
boost::integral_constant<bool, RemoveSpikes>());
@@ -190,7 +187,7 @@ struct copy_segments_polygon
>
static inline void apply(Polygon const& polygon,
SegmentIdentifier const& seg_id,
- signed_index_type to_index,
+ signed_size_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
@@ -220,14 +217,14 @@ struct copy_segments_box
>
static inline void apply(Box const& box,
SegmentIdentifier const& seg_id,
- signed_index_type to_index,
+ signed_size_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
- signed_index_type index = seg_id.segment_index + 1;
- BOOST_ASSERT(index < 5);
+ signed_size_type index = seg_id.segment_index + 1;
+ BOOST_GEOMETRY_ASSERT(index < 5);
- signed_index_type const count = index <= to_index
+ signed_size_type const count = index <= to_index
? to_index - index + 1
: 5 - index + to_index + 1;
@@ -238,7 +235,7 @@ struct copy_segments_box
// (possibly cyclic) copy to output
// (see comments in ring-version)
- for (signed_index_type i = 0; i < count; i++, index++)
+ for (signed_size_type i = 0; i < count; i++, index++)
{
detail::overlay::append_no_dups_or_spikes(current_output,
bp[index % 5], robust_policy);
@@ -260,15 +257,15 @@ struct copy_segments_multi
>
static inline void apply(MultiGeometry const& multi_geometry,
SegmentIdentifier const& seg_id,
- signed_index_type to_index,
+ signed_size_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
seg_id.multi_index >= 0
- && seg_id.multi_index < int(boost::size(multi_geometry))
+ && static_cast<std::size_t>(seg_id.multi_index) < boost::size(multi_geometry)
);
// Call the single-version
@@ -348,7 +345,7 @@ template
>
inline void copy_segments(Geometry const& geometry,
SegmentIdentifier const& seg_id,
- signed_index_type to_index,
+ signed_size_type to_index,
RobustPolicy const& robust_policy,
RangeOut& range_out)
{
diff --git a/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp b/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
index 7ed93f542a..3f81c4dca9 100644
--- a/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
+++ b/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
@@ -22,7 +22,6 @@
# define BOOST_GEOMETRY_DEBUG_IDENTIFIER
#endif
-#include <boost/assert.hpp>
#include <boost/range.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
@@ -358,14 +357,14 @@ inline void enrich_assign(Container& operations,
= turn_points[it->turn_index].operations[it->operation_index];
prev_op.enriched.travels_to_ip_index
- = static_cast<int>(it->turn_index);
+ = static_cast<signed_size_type>(it->turn_index);
prev_op.enriched.travels_to_vertex_index
= it->subject->seg_id.segment_index;
if (! first
&& prev_op.seg_id.segment_index == op.seg_id.segment_index)
{
- prev_op.enriched.next_ip_index = static_cast<int>(it->turn_index);
+ prev_op.enriched.next_ip_index = static_cast<signed_size_type>(it->turn_index);
}
first = false;
}
diff --git a/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp b/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp
index ef32edeefa..5964f3ba44 100644
--- a/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp
+++ b/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp
@@ -37,13 +37,13 @@ struct enrichment_info
// vertex to which is free travel after this IP,
// so from "segment_index+1" to "travels_to_vertex_index", without IP-s,
// can be -1
- signed_index_type travels_to_vertex_index;
+ signed_size_type travels_to_vertex_index;
// same but now IP index, so "next IP index" but not on THIS segment
- int travels_to_ip_index;
+ signed_size_type travels_to_ip_index;
// index of next IP on this segment, -1 if there is no one
- int next_ip_index;
+ signed_size_type next_ip_index;
};
diff --git a/boost/geometry/algorithms/detail/overlay/follow.hpp b/boost/geometry/algorithms/detail/overlay/follow.hpp
index acf38d09ab..22807b5140 100644
--- a/boost/geometry/algorithms/detail/overlay/follow.hpp
+++ b/boost/geometry/algorithms/detail/overlay/follow.hpp
@@ -163,7 +163,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
static inline void enter(LineStringOut& current_piece,
LineString const& ,
segment_identifier& segment_id,
- signed_index_type , Point const& point,
+ signed_size_type , Point const& point,
Operation const& operation,
RobustPolicy const& ,
OutputIterator& )
@@ -186,7 +186,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
static inline void leave(LineStringOut& current_piece,
LineString const& linestring,
segment_identifier& segment_id,
- signed_index_type index, Point const& point,
+ signed_size_type index, Point const& point,
Operation const& ,
RobustPolicy const& robust_policy,
OutputIterator& out)
@@ -217,7 +217,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
static inline void isolated_point(LineStringOut&,
LineString const&,
segment_identifier&,
- signed_index_type, Point const& point,
+ signed_size_type, Point const& point,
Operation const& , OutputIterator& out)
{
LineStringOut isolated_point_ls;
@@ -268,7 +268,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
static inline void enter(LineStringOut& current_piece,
LineString const& linestring,
segment_identifier& segment_id,
- signed_index_type index, Point const& point,
+ signed_size_type index, Point const& point,
Operation const& operation,
RobustPolicy const& robust_policy,
OutputIterator& out)
@@ -289,7 +289,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
static inline void leave(LineStringOut& current_piece,
LineString const& linestring,
segment_identifier& segment_id,
- signed_index_type index, Point const& point,
+ signed_size_type index, Point const& point,
Operation const& operation,
RobustPolicy const& robust_policy,
OutputIterator& out)
@@ -309,7 +309,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
static inline void isolated_point(LineStringOut&,
LineString const&,
segment_identifier&,
- signed_index_type, Point const&,
+ signed_size_type, Point const&,
Operation const&, OutputIterator&)
{
}
@@ -496,7 +496,7 @@ public :
false, RemoveSpikes
>::apply(linestring,
current_segment_id,
- static_cast<signed_index_type>(boost::size(linestring) - 1),
+ static_cast<signed_size_type>(boost::size(linestring) - 1),
robust_policy,
current_piece);
}
diff --git a/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp b/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp
index 7bcc0b951e..b2c3836712 100644
--- a/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp
+++ b/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp
@@ -14,9 +14,9 @@
#include <algorithm>
#include <iterator>
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -142,7 +142,7 @@ static inline bool is_isolated_point(Turn const& turn,
if ( turn.method == method_none )
{
- BOOST_ASSERT( operation.operation == operation_continue );
+ BOOST_GEOMETRY_ASSERT( operation.operation == operation_continue );
return true;
}
@@ -282,7 +282,7 @@ protected:
false, false // do not reverse; do not remove spikes
>::apply(linestring,
current_segment_id,
- static_cast<signed_index_type>(boost::size(linestring) - 1),
+ static_cast<signed_size_type>(boost::size(linestring) - 1),
robust_policy,
current_piece);
}
@@ -327,7 +327,7 @@ public:
throw inconsistent_turns_exception();
}
#else
- BOOST_ASSERT(enter_count == 0);
+ BOOST_GEOMETRY_ASSERT(enter_count == 0);
#endif
return process_end(entered, linestring,
@@ -404,7 +404,7 @@ protected:
};
template <typename TurnIterator>
- static inline signed_index_type get_multi_index(TurnIterator it)
+ static inline signed_size_type get_multi_index(TurnIterator it)
{
return boost::begin(it->operations)->seg_id.multi_index;
}
@@ -412,10 +412,10 @@ protected:
class has_other_multi_id
{
private:
- signed_index_type m_multi_id;
+ signed_size_type m_multi_id;
public:
- has_other_multi_id(signed_index_type multi_id)
+ has_other_multi_id(signed_size_type multi_id)
: m_multi_id(multi_id) {}
template <typename Turn>
@@ -433,7 +433,7 @@ public:
TurnIterator first, TurnIterator beyond,
OutputIterator oit)
{
- BOOST_ASSERT( first != beyond );
+ BOOST_GEOMETRY_ASSERT( first != beyond );
typedef copy_linestrings_in_range
<
@@ -446,7 +446,7 @@ public:
// Iterate through all intersection points (they are
// ordered along the each linestring)
- signed_index_type current_multi_id = get_multi_index(first);
+ signed_size_type current_multi_id = get_multi_index(first);
oit = copy_linestrings::apply(ls_first,
ls_first + current_multi_id,
@@ -463,7 +463,7 @@ public:
oit = Base::apply(*(ls_first + current_multi_id),
linear, per_ls_current, per_ls_next, oit);
- signed_index_type next_multi_id(-1);
+ signed_size_type next_multi_id = -1;
linestring_iterator ls_next = ls_beyond;
if ( per_ls_next != beyond )
{
diff --git a/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp b/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
index 63011c7d48..4668189924 100644
--- a/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
@@ -12,6 +12,9 @@
#include <cstddef>
+#include <boost/mpl/if.hpp>
+#include <boost/range.hpp>
+
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
diff --git a/boost/geometry/algorithms/detail/overlay/get_ring.hpp b/boost/geometry/algorithms/detail/overlay/get_ring.hpp
index 131d58d582..460c30def3 100644
--- a/boost/geometry/algorithms/detail/overlay/get_ring.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_ring.hpp
@@ -10,9 +10,9 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/ring_type.hpp>
@@ -82,7 +82,7 @@ struct get_ring<polygon_tag>
ring_identifier const& id,
Polygon const& polygon)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
id.ring_index >= -1
&& id.ring_index < int(boost::size(interior_rings(polygon)))
@@ -102,7 +102,7 @@ struct get_ring<multi_polygon_tag>
ring_identifier const& id,
MultiPolygon const& multi_polygon)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
id.multi_index >= 0
&& id.multi_index < int(boost::size(multi_polygon))
diff --git a/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp b/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
index b3b1a06f68..717f0b47a9 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
@@ -15,10 +15,10 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HPP
-#include <boost/assert.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/strategies/intersection.hpp>
#include <boost/geometry/algorithms/convert.hpp>
@@ -115,7 +115,7 @@ struct base_turn_handler
{
ti.method = method;
- BOOST_ASSERT(index < info.count);
+ BOOST_GEOMETRY_ASSERT(index < info.count);
geometry::convert(info.intersections[index], ti.point);
ti.operations[0].fraction = info.fractions[index].robust_ra;
@@ -597,7 +597,7 @@ struct collinear : public base_turn_handler
int const arrival = dir_info.arrival[0];
// Should not be 0, this is checked before
- BOOST_ASSERT(arrival != 0);
+ BOOST_GEOMETRY_ASSERT(arrival != 0);
int const side_p = side.pk_wrt_p1();
int const side_q = side.qk_wrt_q1();
diff --git a/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp b/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp
index 4a3cacbedd..0b3cb72747 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp
@@ -14,6 +14,7 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
@@ -153,7 +154,7 @@ public:
}
else
{
- BOOST_ASSERT(result.template get<0>().count == 1);
+ BOOST_GEOMETRY_ASSERT(result.template get<0>().count == 1);
ips[0].p_operation = union_or_blocked_same_dirs(arrival_a, is_p_last);
ips[0].q_operation = union_or_blocked_same_dirs(arrival_b, is_q_last);
@@ -297,10 +298,10 @@ struct get_turn_info_for_endpoint
// may this give false positives for INTs?
typename IntersectionResult::point_type const&
inters_pt = result.template get<0>().intersections[ip_index];
- BOOST_ASSERT(ip_info.is_pi == equals::equals_point_point(pi, inters_pt));
- BOOST_ASSERT(ip_info.is_qi == equals::equals_point_point(qi, inters_pt));
- BOOST_ASSERT(ip_info.is_pj == equals::equals_point_point(pj, inters_pt));
- BOOST_ASSERT(ip_info.is_qj == equals::equals_point_point(qj, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_info.is_pi == equals::equals_point_point(pi, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_info.is_qi == equals::equals_point_point(qi, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_info.is_pj == equals::equals_point_point(pj, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_info.is_qj == equals::equals_point_point(qj, inters_pt));
#endif
// TODO - calculate first/last only if needed
@@ -412,8 +413,8 @@ struct get_turn_info_for_endpoint
// may this give false positives for INTs?
typename IntersectionResult::point_type const&
inters_pt = inters.i_info().intersections[ip_index];
- BOOST_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
- BOOST_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
#endif
if ( ip_i2 )
{
@@ -448,7 +449,7 @@ struct get_turn_info_for_endpoint
}
else
{
- BOOST_ASSERT(operations_combination(operations, operation_intersection, operation_union));
+ BOOST_GEOMETRY_ASSERT(operations_combination(operations, operation_intersection, operation_union));
//op1 = operation_union;
//op2 = operation_union;
}
@@ -463,8 +464,8 @@ struct get_turn_info_for_endpoint
// may this give false positives for INTs?
typename IntersectionResult::point_type const&
inters_pt = inters.i_info().intersections[ip_index];
- BOOST_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
- BOOST_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
#endif
if ( ip_i2 )
{
@@ -499,7 +500,7 @@ struct get_turn_info_for_endpoint
}
else
{
- BOOST_ASSERT(operations_combination(operations, operation_intersection, operation_union));
+ BOOST_GEOMETRY_ASSERT(operations_combination(operations, operation_intersection, operation_union));
//op1 = operation_blocked;
//op2 = operation_union;
}
@@ -560,7 +561,7 @@ struct get_turn_info_for_endpoint
// NOTE: is_collinear is NOT set for the first endpoint
// for which there is no preceding segment
- //BOOST_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
+ //BOOST_GEOMETRY_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
if ( ! is_p_first_ip )
{
tp.operations[0].is_collinear = op0 != operation_intersection
diff --git a/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp b/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp
index e0d75108b9..e4f8de42e1 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp
@@ -42,7 +42,8 @@ template <typename PointP, typename PointQ,
>
struct side_calculator
{
- typedef boost::geometry::strategy::side::side_by_triangle<> side; // todo: get from coordinate system
+ // todo: get from coordinate system
+ typedef boost::geometry::strategy::side::side_by_triangle<> side;
inline side_calculator(Pi const& pi, Pj const& pj, Pk const& pk,
Qi const& qi, Qj const& qj, Qk const& qk)
@@ -71,8 +72,9 @@ struct robust_points
{
typedef typename geometry::robust_point_type
<
- Point1, RobustPolicy
+ Point1, RobustPolicy
>::type robust_point1_type;
+
// TODO: define robust_point2_type using Point2?
typedef robust_point1_type robust_point2_type;
@@ -96,23 +98,23 @@ template <typename Point1, typename Point2, typename RobustPolicy>
class intersection_info_base
: private robust_points<Point1, Point2, RobustPolicy>
{
- typedef robust_points<Point1, Point2, RobustPolicy> base_t;
+ typedef robust_points<Point1, Point2, RobustPolicy> base;
public:
typedef Point1 point1_type;
typedef Point2 point2_type;
- typedef typename base_t::robust_point1_type robust_point1_type;
- typedef typename base_t::robust_point2_type robust_point2_type;
+ typedef typename base::robust_point1_type robust_point1_type;
+ typedef typename base::robust_point2_type robust_point2_type;
typedef side_calculator<robust_point1_type, robust_point2_type> side_calculator_type;
intersection_info_base(Point1 const& pi, Point1 const& pj, Point1 const& pk,
Point2 const& qi, Point2 const& qj, Point2 const& qk,
RobustPolicy const& robust_policy)
- : base_t(pi, pj, pk, qi, qj, qk, robust_policy)
- , m_side_calc(base_t::m_rpi, base_t::m_rpj, base_t::m_rpk,
- base_t::m_rqi, base_t::m_rqj, base_t::m_rqk)
+ : base(pi, pj, pk, qi, qj, qk, robust_policy)
+ , m_side_calc(base::m_rpi, base::m_rpj, base::m_rpk,
+ base::m_rqi, base::m_rqj, base::m_rqk)
, m_pi(pi), m_pj(pj), m_pk(pk)
, m_qi(qi), m_qj(qj), m_qk(qk)
{}
@@ -125,13 +127,13 @@ public:
inline Point2 const& qj() const { return m_qj; }
inline Point2 const& qk() const { return m_qk; }
- inline robust_point1_type const& rpi() const { return base_t::m_rpi; }
- inline robust_point1_type const& rpj() const { return base_t::m_rpj; }
- inline robust_point1_type const& rpk() const { return base_t::m_rpk; }
+ inline robust_point1_type const& rpi() const { return base::m_rpi; }
+ inline robust_point1_type const& rpj() const { return base::m_rpj; }
+ inline robust_point1_type const& rpk() const { return base::m_rpk; }
- inline robust_point2_type const& rqi() const { return base_t::m_rqi; }
- inline robust_point2_type const& rqj() const { return base_t::m_rqj; }
- inline robust_point2_type const& rqk() const { return base_t::m_rqk; }
+ inline robust_point2_type const& rqi() const { return base::m_rqi; }
+ inline robust_point2_type const& rqj() const { return base::m_rqj; }
+ inline robust_point2_type const& rqk() const { return base::m_rqk; }
inline side_calculator_type const& sides() const { return m_side_calc; }
@@ -187,11 +189,17 @@ private:
};
-template <typename Point1, typename Point2, typename TurnPoint, typename RobustPolicy>
+template
+<
+ typename Point1,
+ typename Point2,
+ typename TurnPoint,
+ typename RobustPolicy
+>
class intersection_info
: public intersection_info_base<Point1, Point2, RobustPolicy>
{
- typedef intersection_info_base<Point1, Point2, RobustPolicy> base_t;
+ typedef intersection_info_base<Point1, Point2, RobustPolicy> base;
typedef typename strategy_intersection
<
@@ -205,7 +213,7 @@ class intersection_info
public:
typedef model::referring_segment<Point1 const> segment_type1;
typedef model::referring_segment<Point2 const> segment_type2;
- typedef typename base_t::side_calculator_type side_calculator_type;
+ typedef typename base::side_calculator_type side_calculator_type;
typedef typename strategy::return_type result_type;
typedef typename boost::tuples::element<0, result_type>::type i_info_type; // intersection_info
@@ -214,10 +222,12 @@ public:
intersection_info(Point1 const& pi, Point1 const& pj, Point1 const& pk,
Point2 const& qi, Point2 const& qj, Point2 const& qk,
RobustPolicy const& robust_policy)
- : base_t(pi, pj, pk, qi, qj, qk, robust_policy)
+ : base(pi, pj, pk, qi, qj, qk, robust_policy)
, m_result(strategy::apply(segment_type1(pi, pj),
segment_type2(qi, qj),
- robust_policy))
+ robust_policy,
+ base::rpi(), base::rpj(),
+ base::rqi(), base::rqj()))
, m_robust_policy(robust_policy)
{}
@@ -228,19 +238,22 @@ public:
// TODO: it's more like is_spike_ip_p
inline bool is_spike_p() const
{
- if ( base_t::sides().pk_wrt_p1() == 0 )
+ if (base::sides().pk_wrt_p1() == 0)
{
- if ( ! is_ip_j<0>() )
+ if (! is_ip_j<0>())
+ {
return false;
+ }
- int const qk_p1 = base_t::sides().qk_wrt_p1();
- int const qk_p2 = base_t::sides().qk_wrt_p2();
+ int const qk_p1 = base::sides().qk_wrt_p1();
+ int const qk_p2 = base::sides().qk_wrt_p2();
- if ( qk_p1 == -qk_p2 )
+ if (qk_p1 == -qk_p2)
{
- if ( qk_p1 == 0 )
+ if (qk_p1 == 0)
{
- return is_spike_of_collinear(base_t::pi(), base_t::pj(), base_t::pk());
+ return is_spike_of_collinear(base::pi(), base::pj(),
+ base::pk());
}
return true;
@@ -253,19 +266,22 @@ public:
// TODO: it's more like is_spike_ip_q
inline bool is_spike_q() const
{
- if ( base_t::sides().qk_wrt_q1() == 0 )
+ if (base::sides().qk_wrt_q1() == 0)
{
- if ( ! is_ip_j<1>() )
+ if (! is_ip_j<1>())
+ {
return false;
+ }
- int const pk_q1 = base_t::sides().pk_wrt_q1();
- int const pk_q2 = base_t::sides().pk_wrt_q2();
+ int const pk_q1 = base::sides().pk_wrt_q1();
+ int const pk_q2 = base::sides().pk_wrt_q2();
- if ( pk_q1 == -pk_q2 )
+ if (pk_q1 == -pk_q2)
{
- if ( pk_q1 == 0 )
+ if (pk_q1 == 0)
{
- return is_spike_of_collinear(base_t::qi(), base_t::qj(), base_t::qk());
+ return is_spike_of_collinear(base::qi(), base::qj(),
+ base::qk());
}
return true;
@@ -277,9 +293,10 @@ public:
private:
template <typename Point>
- inline bool is_spike_of_collinear(Point const& i, Point const& j, Point const& k) const
+ inline bool is_spike_of_collinear(Point const& i, Point const& j,
+ Point const& k) const
{
- typedef model::referring_segment<Point const> seg_t;
+ typedef model::referring_segment<Point const> seg;
typedef strategy_intersection
<
@@ -289,7 +306,7 @@ private:
typedef typename si::segment_intersection_strategy_type strategy;
typename strategy::return_type result
- = strategy::apply(seg_t(i, j), seg_t(j, k), m_robust_policy);
+ = strategy::apply(seg(i, j), seg(j, k), m_robust_policy);
return result.template get<0>().count == 2;
}
@@ -300,9 +317,9 @@ private:
int arrival = d_info().arrival[OpId];
bool same_dirs = d_info().dir_a == 0 && d_info().dir_b == 0;
- if ( same_dirs )
+ if (same_dirs)
{
- if ( i_info().count == 2 )
+ if (i_info().count == 2)
{
return arrival != -1;
}
diff --git a/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp b/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp
index 71946543ee..ccb42d4c92 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp
@@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LA_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LA_HPP
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
@@ -569,7 +571,7 @@ struct get_turn_info_linear_areal
tp.operations[0].is_collinear = true;
//tp.operations[1].is_collinear = false;
- BOOST_ASSERT(inters.i_info().count > 1);
+ BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1);
base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 1);
AssignPolicy::apply(tp, inters.pi(), inters.qi(), inters);
@@ -816,7 +818,7 @@ struct get_turn_info_linear_areal
if ( inters.i_info().count > 1 )
{
- //BOOST_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
+ //BOOST_GEOMETRY_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
tp.operations[0].is_collinear = true;
tp.operations[1].operation = opposite ? operation_continue : operation_union;
}
diff --git a/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp b/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp
index 1ec88e54a0..19f0859cbb 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp
@@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LL_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LL_HPP
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp>
@@ -579,7 +581,7 @@ struct get_turn_info_linear_linear
tp.operations[0].is_collinear = true;
tp.operations[1].is_collinear = false;
- BOOST_ASSERT(inters.i_info().count > 1);
+ BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1);
base_turn_handler::assign_point(tp, method_touch_interior,
inters.i_info(), 1);
@@ -612,7 +614,7 @@ struct get_turn_info_linear_linear
tp.operations[0].is_collinear = false;
tp.operations[1].is_collinear = true;
- BOOST_ASSERT(inters.i_info().count > 0);
+ BOOST_GEOMETRY_ASSERT(inters.i_info().count > 0);
base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 0);
@@ -686,7 +688,7 @@ struct get_turn_info_linear_linear
operation_type & op0 = turn.operations[0].operation;
operation_type & op1 = turn.operations[1].operation;
- BOOST_ASSERT(op0 != operation_blocked || op1 != operation_blocked );
+ BOOST_GEOMETRY_ASSERT(op0 != operation_blocked || op1 != operation_blocked );
if ( op0 == operation_blocked )
{
diff --git a/boost/geometry/algorithms/detail/overlay/get_turns.hpp b/boost/geometry/algorithms/detail/overlay/get_turns.hpp
index a5d8f3f023..098c7b5642 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turns.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turns.hpp
@@ -22,6 +22,7 @@
#include <boost/array.hpp>
#include <boost/concept_check.hpp>
#include <boost/mpl/if.hpp>
+#include <boost/mpl/vector_c.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/access.hpp>
@@ -142,7 +143,7 @@ class get_turns_in_sections
template <typename Geometry, typename Section>
static inline bool neighbouring(Section const& section,
- int index1, int index2)
+ signed_size_type index1, signed_size_type index2)
{
// About n-2:
// (square: range_count=5, indices 0,1,2,3
@@ -150,7 +151,7 @@ class get_turns_in_sections
// Also tested for open polygons, and/or duplicates
// About first condition: will be optimized by compiler (static)
// It checks if it is areal (box,ring,(multi)polygon
- int const n = int(section.range_count);
+ signed_size_type const n = static_cast<signed_size_type>(section.range_count);
boost::ignore_unused_variable_warning(n);
boost::ignore_unused_variable_warning(index1);
@@ -207,8 +208,8 @@ public :
int const dir1 = sec1.directions[0];
int const dir2 = sec2.directions[0];
- int index1 = sec1.begin_index;
- int ndi1 = sec1.non_duplicate_index;
+ signed_size_type index1 = sec1.begin_index;
+ signed_size_type ndi1 = sec1.non_duplicate_index;
bool const same_source =
source_id1 == source_id2
@@ -236,8 +237,8 @@ public :
begin_range_1, end_range_1, next1, true);
advance_to_non_duplicate_next(nd_next1, it1, sec1, robust_policy);
- int index2 = sec2.begin_index;
- int ndi2 = sec2.non_duplicate_index;
+ signed_size_type index2 = sec2.begin_index;
+ signed_size_type ndi2 = sec2.non_duplicate_index;
range2_iterator prev2, it2, end2;
@@ -359,7 +360,7 @@ private :
typename boost::range_iterator<Range const>::type& it,
typename boost::range_iterator<Range const>::type& prev,
typename boost::range_iterator<Range const>::type& end,
- int& index, int& ndi,
+ signed_size_type& index, signed_size_type& ndi,
int dir, Box const& other_bounding_box, RobustPolicy const& robust_policy)
{
it = boost::begin(range) + section.begin_index;
@@ -524,8 +525,8 @@ struct get_turns_cs
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy,
- signed_index_type multi_index = -1,
- signed_index_type ring_index = -1)
+ signed_size_type multi_index = -1,
+ signed_size_type ring_index = -1)
{
if ( boost::size(range) <= 1)
{
@@ -552,7 +553,7 @@ struct get_turns_cs
//char previous_side[2] = {0, 0};
- signed_index_type index = 0;
+ signed_size_type index = 0;
for (iterator_type prev = it++;
it != boost::end(view);
@@ -696,7 +697,7 @@ struct get_turns_polygon_cs
int source_id2, Box const& box,
RobustPolicy const& robust_policy,
Turns& turns, InterruptPolicy& interrupt_policy,
- signed_index_type multi_index = -1)
+ signed_size_type multi_index = -1)
{
typedef typename geometry::ring_type<Polygon>::type ring_type;
@@ -714,7 +715,7 @@ struct get_turns_polygon_cs
turns, interrupt_policy,
multi_index, -1);
- signed_index_type i = 0;
+ signed_size_type i = 0;
typename interior_return_type<Polygon const>::type
rings = interior_rings(polygon);
@@ -753,7 +754,7 @@ struct get_turns_multi_polygon_cs
Multi const
>::type iterator_type;
- signed_index_type i = 0;
+ signed_size_type i = 0;
for (iterator_type it = boost::begin(multi);
it != boost::end(multi);
++it, ++i)
diff --git a/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp b/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
index 3101de8c35..af0731f5a9 100644
--- a/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
+++ b/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
@@ -1,9 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -39,9 +39,11 @@
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
#include <boost/geometry/views/segment_view.hpp>
+#include <boost/geometry/views/detail/boundary_view.hpp>
#include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
#include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
+#include <boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp>
#if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
#include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
@@ -283,7 +285,8 @@ namespace dispatch
template
<
// real types
- typename Geometry1, typename Geometry2,
+ typename Geometry1,
+ typename Geometry2,
typename GeometryOut,
overlay_type OverlayType,
// orientation
@@ -409,13 +412,13 @@ struct intersection_insert
template <typename RobustPolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(Linestring const& linestring,
Box const& box,
- RobustPolicy const& ,
+ RobustPolicy const& robust_policy,
OutputIterator out, Strategy const& )
{
typedef typename point_type<GeometryOut>::type point_type;
strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
return detail::intersection::clip_range_with_box
- <GeometryOut>(box, linestring, out, lb_strategy);
+ <GeometryOut>(box, linestring, robust_policy, out, lb_strategy);
}
};
@@ -487,7 +490,7 @@ struct intersection_insert
template <typename RobustPolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(Segment const& segment,
Box const& box,
- RobustPolicy const& ,// TODO: propagate to clip_range_with_box
+ RobustPolicy const& robust_policy,
OutputIterator out, Strategy const& )
{
geometry::segment_view<Segment> range(segment);
@@ -495,7 +498,7 @@ struct intersection_insert
typedef typename point_type<GeometryOut>::type point_type;
strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
return detail::intersection::clip_range_with_box
- <GeometryOut>(box, range, out, lb_strategy);
+ <GeometryOut>(box, range, robust_policy, out, lb_strategy);
}
};
@@ -573,6 +576,46 @@ struct intersection_insert_reversed
};
+// dispatch for intersection(areal, areal, linear)
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename LinestringOut,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename Tag1, typename Tag2
+>
+struct intersection_insert
+ <
+ Geometry1, Geometry2,
+ LinestringOut,
+ overlay_intersection,
+ Reverse1, Reverse2, ReverseOut,
+ Tag1, Tag2, linestring_tag,
+ true, true, false
+ >
+{
+ template
+ <
+ typename RobustPolicy, typename OutputIterator, typename Strategy
+ >
+ static inline OutputIterator apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ OutputIterator oit,
+ Strategy const& strategy)
+ {
+ detail::boundary_view<Geometry1 const> view1(geometry1);
+ detail::boundary_view<Geometry2 const> view2(geometry2);
+
+ return detail::overlay::linear_linear_linestring
+ <
+ detail::boundary_view<Geometry1 const>,
+ detail::boundary_view<Geometry2 const>,
+ LinestringOut,
+ overlay_intersection
+ >::apply(view1, view2, robust_policy, oit, strategy);
+ }
+};
// dispatch for non-areal geometries
template
@@ -700,6 +743,79 @@ struct intersection_insert
{};
+// dispatch for difference/intersection of pointlike-linear geometries
+template
+<
+ typename Point, typename Linear, typename PointOut,
+ overlay_type OverlayType,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename Tag
+>
+struct intersection_insert
+ <
+ Point, Linear, PointOut, OverlayType,
+ Reverse1, Reverse2, ReverseOut,
+ point_tag, Tag, point_tag,
+ false, false, false
+ > : detail_dispatch::overlay::pointlike_linear_point
+ <
+ Point, Linear, PointOut, OverlayType,
+ point_tag, typename tag_cast<Tag, segment_tag, linear_tag>::type
+ >
+{};
+
+
+template
+<
+ typename MultiPoint, typename Linear, typename PointOut,
+ overlay_type OverlayType,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename Tag
+>
+struct intersection_insert
+ <
+ MultiPoint, Linear, PointOut, OverlayType,
+ Reverse1, Reverse2, ReverseOut,
+ multi_point_tag, Tag, point_tag,
+ false, false, false
+ > : detail_dispatch::overlay::pointlike_linear_point
+ <
+ MultiPoint, Linear, PointOut, OverlayType,
+ multi_point_tag,
+ typename tag_cast<Tag, segment_tag, linear_tag>::type
+ >
+{};
+
+
+template
+<
+ typename Linestring, typename MultiPoint, typename PointOut,
+ bool Reverse1, bool Reverse2, bool ReverseOut
+>
+struct intersection_insert
+ <
+ Linestring, MultiPoint, PointOut, overlay_intersection,
+ Reverse1, Reverse2, ReverseOut,
+ linestring_tag, multi_point_tag, point_tag,
+ false, false, false
+ >
+{
+ template <typename RobustPolicy, typename OutputIterator, typename Strategy>
+ static inline OutputIterator apply(Linestring const& linestring,
+ MultiPoint const& multipoint,
+ RobustPolicy const& robust_policy,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ return detail_dispatch::overlay::pointlike_linear_point
+ <
+ MultiPoint, Linestring, PointOut, overlay_intersection,
+ multi_point_tag, linear_tag
+ >::apply(multipoint, linestring, robust_policy, out, strategy);
+ }
+};
+
+
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
diff --git a/boost/geometry/algorithms/detail/overlay/linear_linear.hpp b/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
index d4ebcf296b..34517f6590 100644
--- a/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
+++ b/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -157,13 +157,18 @@ protected:
<
typename Turns,
typename LinearGeometry1,
- typename LinearGeometry2
+ typename LinearGeometry2,
+ typename RobustPolicy
>
static inline void compute_turns(Turns& turns,
LinearGeometry1 const& linear1,
- LinearGeometry2 const& linear2)
+ LinearGeometry2 const& linear2,
+ RobustPolicy const& robust_policy)
{
turns.clear();
+
+ detail::get_turns::no_interrupt_policy interrupt_policy;
+
geometry::detail::relate::turns::get_turns
<
LinearGeometry1,
@@ -173,8 +178,9 @@ protected:
LinearGeometry1,
LinearGeometry2,
assign_policy
- >
- >::apply(turns, linear1, linear2);
+ >,
+ RobustPolicy
+ >::apply(turns, linear1, linear2, interrupt_policy, robust_policy);
}
@@ -229,19 +235,27 @@ public:
>
static inline OutputIterator apply(Linear1 const& linear1,
Linear2 const& linear2,
- RobustPolicy const&,
+ RobustPolicy const& robust_policy,
OutputIterator oit,
Strategy const& )
{
typedef typename detail::relate::turns::get_turns
<
- Linear1, Linear2
+ Linear1,
+ Linear2,
+ detail::get_turns::get_turn_info_type
+ <
+ Linear1,
+ Linear2,
+ assign_policy
+ >,
+ RobustPolicy
>::turn_info turn_info;
typedef std::vector<turn_info> turns_container;
turns_container turns;
- compute_turns(turns, linear1, linear2);
+ compute_turns(turns, linear1, linear2, robust_policy);
if ( turns.empty() )
{
diff --git a/boost/geometry/algorithms/detail/overlay/overlay.hpp b/boost/geometry/algorithms/detail/overlay/overlay.hpp
index a2f52848d1..baf9d4777d 100644
--- a/boost/geometry/algorithms/detail/overlay/overlay.hpp
+++ b/boost/geometry/algorithms/detail/overlay/overlay.hpp
@@ -1,7 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -28,7 +33,7 @@
#include <boost/geometry/algorithms/detail/recalculate.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/reverse.hpp>
#include <boost/geometry/algorithms/detail/overlay/add_rings.hpp>
@@ -125,8 +130,7 @@ inline OutputIterator return_if_one_input_is_empty(Geometry1 const& geometry1,
// Intersection: return nothing
// Difference: return first of them
if (Direction == overlay_intersection
- || (Direction == overlay_difference
- && geometry::num_points(geometry1) == 0))
+ || (Direction == overlay_difference && geometry::is_empty(geometry1)))
{
return out;
}
@@ -162,14 +166,15 @@ struct overlay
OutputIterator out,
Strategy const& )
{
- if ( geometry::num_points(geometry1) == 0
- && geometry::num_points(geometry2) == 0 )
+ bool const is_empty1 = geometry::is_empty(geometry1);
+ bool const is_empty2 = geometry::is_empty(geometry2);
+
+ if (is_empty1 && is_empty2)
{
return out;
}
- if ( geometry::num_points(geometry1) == 0
- || geometry::num_points(geometry2) == 0 )
+ if (is_empty1 || is_empty2)
{
return return_if_one_input_is_empty
<
diff --git a/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp b/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp
new file mode 100644
index 0000000000..156cb54867
--- /dev/null
+++ b/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp
@@ -0,0 +1,343 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP
+
+#include <iterator>
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/box.hpp>
+
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+#include <boost/geometry/algorithms/detail/not.hpp>
+#include <boost/geometry/algorithms/detail/partition.hpp>
+#include <boost/geometry/algorithms/detail/relate/less.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
+#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
+#include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+// action struct for pointlike-linear difference/intersection
+// it works the same as its pointlike-pointlike counterpart, hence the
+// derivation
+template <typename PointOut, overlay_type OverlayType>
+struct action_selector_pl_l
+ : action_selector_pl_pl<PointOut, OverlayType>
+{};
+
+// difference/intersection of point-linear
+template
+<
+ typename Point,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType,
+ typename Policy
+>
+struct point_linear_point
+{
+ template <typename RobustPolicy, typename OutputIterator, typename Strategy>
+ static inline OutputIterator apply(Point const& point,
+ Linear const& linear,
+ RobustPolicy const&,
+ OutputIterator oit,
+ Strategy const&)
+ {
+ action_selector_pl_l
+ <
+ PointOut, OverlayType
+ >::apply(point, Policy::apply(point, linear), oit);
+ return oit;
+ }
+};
+
+// difference/intersection of multipoint-segment
+template
+<
+ typename MultiPoint,
+ typename Segment,
+ typename PointOut,
+ overlay_type OverlayType,
+ typename Policy
+>
+struct multipoint_segment_point
+{
+ template <typename RobustPolicy, typename OutputIterator, typename Strategy>
+ static inline OutputIterator apply(MultiPoint const& multipoint,
+ Segment const& segment,
+ RobustPolicy const&,
+ OutputIterator oit,
+ Strategy const&)
+ {
+ for (typename boost::range_iterator<MultiPoint const>::type
+ it = boost::begin(multipoint);
+ it != boost::end(multipoint);
+ ++it)
+ {
+ action_selector_pl_l
+ <
+ PointOut, OverlayType
+ >::apply(*it, Policy::apply(*it, segment), oit);
+ }
+
+ return oit;
+ }
+};
+
+
+// difference/intersection of multipoint-linear
+template
+<
+ typename MultiPoint,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType,
+ typename Policy
+>
+class multipoint_linear_point
+{
+private:
+ // structs for partition -- start
+ struct expand_box
+ {
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& total, Geometry const& geometry)
+ {
+ geometry::expand(total, geometry::return_envelope<Box>(geometry));
+ }
+
+ };
+
+ struct overlaps_box
+ {
+ template <typename Box, typename Geometry>
+ static inline bool apply(Box const& box, Geometry const& geometry)
+ {
+ return ! geometry::disjoint(geometry, box);
+ }
+ };
+
+ template <typename OutputIterator>
+ class item_visitor_type
+ {
+ public:
+ item_visitor_type(OutputIterator& oit) : m_oit(oit) {}
+
+ template <typename Item1, typename Item2>
+ inline void apply(Item1 const& item1, Item2 const& item2)
+ {
+ action_selector_pl_l
+ <
+ PointOut, overlay_intersection
+ >::apply(item1, Policy::apply(item1, item2), m_oit);
+ }
+
+ private:
+ OutputIterator& m_oit;
+ };
+ // structs for partition -- end
+
+ class segment_range
+ {
+ public:
+ typedef geometry::segment_iterator<Linear const> const_iterator;
+ typedef const_iterator iterator;
+
+ segment_range(Linear const& linear)
+ : m_linear(linear)
+ {}
+
+ const_iterator begin() const
+ {
+ return geometry::segments_begin(m_linear);
+ }
+
+ const_iterator end() const
+ {
+ return geometry::segments_end(m_linear);
+ }
+
+ private:
+ Linear const& m_linear;
+ };
+
+ template <typename OutputIterator>
+ static inline OutputIterator get_common_points(MultiPoint const& multipoint,
+ Linear const& linear,
+ OutputIterator oit)
+ {
+ item_visitor_type<OutputIterator> item_visitor(oit);
+
+ segment_range rng(linear);
+
+ geometry::partition
+ <
+ geometry::model::box
+ <
+ typename boost::range_value<MultiPoint>::type
+ >,
+ expand_box,
+ overlaps_box
+ >::apply(multipoint, rng, item_visitor);
+
+ return oit;
+ }
+
+public:
+ template <typename RobustPolicy, typename OutputIterator, typename Strategy>
+ static inline OutputIterator apply(MultiPoint const& multipoint,
+ Linear const& linear,
+ RobustPolicy const& robust_policy,
+ OutputIterator oit,
+ Strategy const& strategy)
+ {
+ typedef std::vector
+ <
+ typename boost::range_value<MultiPoint>::type
+ > point_vector_type;
+
+ point_vector_type common_points;
+
+ // compute the common points
+ get_common_points(multipoint, linear,
+ std::back_inserter(common_points));
+
+ return multipoint_multipoint_point
+ <
+ MultiPoint, point_vector_type, PointOut, OverlayType
+ >::apply(multipoint, common_points, robust_policy, oit, strategy);
+ }
+};
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace detail_dispatch { namespace overlay
+{
+
+// dispatch struct for pointlike-linear difference/intersection computation
+template
+<
+ typename PointLike,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType,
+ typename Tag1,
+ typename Tag2
+>
+struct pointlike_linear_point
+ : not_implemented<PointLike, Linear, PointOut>
+{};
+
+
+template
+<
+ typename Point,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType
+>
+struct pointlike_linear_point
+ <
+ Point, Linear, PointOut, OverlayType, point_tag, linear_tag
+ > : detail::overlay::point_linear_point
+ <
+ Point, Linear, PointOut, OverlayType,
+ detail::not_<detail::disjoint::reverse_covered_by>
+ >
+{};
+
+
+template
+<
+ typename Point,
+ typename Segment,
+ typename PointOut,
+ overlay_type OverlayType
+>
+struct pointlike_linear_point
+ <
+ Point, Segment, PointOut, OverlayType, point_tag, segment_tag
+ > : detail::overlay::point_linear_point
+ <
+ Point, Segment, PointOut, OverlayType,
+ detail::not_<detail::disjoint::reverse_covered_by>
+ >
+{};
+
+
+template
+<
+ typename MultiPoint,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType
+>
+struct pointlike_linear_point
+ <
+ MultiPoint, Linear, PointOut, OverlayType, multi_point_tag, linear_tag
+ > : detail::overlay::multipoint_linear_point
+ <
+ MultiPoint, Linear, PointOut, OverlayType,
+ detail::not_<detail::disjoint::reverse_covered_by>
+ >
+{};
+
+
+template
+<
+ typename MultiPoint,
+ typename Segment,
+ typename PointOut,
+ overlay_type OverlayType
+>
+struct pointlike_linear_point
+ <
+ MultiPoint, Segment, PointOut, OverlayType, multi_point_tag, segment_tag
+ > : detail::overlay::multipoint_segment_point
+ <
+ MultiPoint, Segment, PointOut, OverlayType,
+ detail::not_<detail::disjoint::reverse_covered_by>
+ >
+{};
+
+
+}} // namespace detail_dispatch::overlay
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP
diff --git a/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp b/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp
index 0af062d271..438a377876 100644
--- a/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp
+++ b/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -14,9 +14,9 @@
#include <algorithm>
#include <vector>
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -182,7 +182,7 @@ struct multipoint_point_point
OutputIterator oit,
Strategy const&)
{
- BOOST_ASSERT( OverlayType == overlay_difference );
+ BOOST_GEOMETRY_ASSERT( OverlayType == overlay_difference );
for (typename boost::range_iterator<MultiPoint const>::type
it = boost::begin(multipoint);
@@ -264,7 +264,7 @@ struct multipoint_multipoint_point
>::apply(multipoint2, multipoint1, robust_policy, oit, strategy);
}
- std::vector<typename point_type<MultiPoint2>::type>
+ std::vector<typename boost::range_value<MultiPoint2>::type>
points2(boost::begin(multipoint2), boost::end(multipoint2));
std::sort(points2.begin(), points2.end(), detail::relate::less());
diff --git a/boost/geometry/algorithms/detail/overlay/ring_properties.hpp b/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
index b469052c84..0f2da67b62 100644
--- a/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
+++ b/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
@@ -29,6 +29,8 @@ struct ring_properties
typedef Point point_type;
typedef typename default_area_result<Point>::type area_type;
+ bool valid;
+
// Filled by "select_rings"
Point point;
area_type area;
@@ -43,7 +45,8 @@ struct ring_properties
std::vector<ring_identifier> children;
inline ring_properties()
- : area(area_type())
+ : valid(false)
+ , area(area_type())
, reversed(false)
, discarded(false)
, parent_area(-1)
@@ -59,7 +62,7 @@ struct ring_properties
// We should take a point somewhere in the middle of the ring,
// to avoid taking a point on a (self)tangency,
// in cases where multiple points come together
- geometry::point_on_border(this->point, ring_or_box, true);
+ valid = geometry::point_on_border(this->point, ring_or_box, true);
}
inline area_type get_area() const
diff --git a/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp b/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp
index 516ec349e8..e77a163dd5 100644
--- a/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp
+++ b/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp
@@ -19,7 +19,7 @@
#endif
-#include <boost/geometry/algorithms/detail/signed_index_type.hpp>
+#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
namespace boost { namespace geometry
@@ -40,10 +40,10 @@ struct segment_identifier
, segment_index(-1)
{}
- inline segment_identifier(signed_index_type src,
- signed_index_type mul,
- signed_index_type rin,
- signed_index_type seg)
+ inline segment_identifier(signed_size_type src,
+ signed_size_type mul,
+ signed_size_type rin,
+ signed_size_type seg)
: source_index(src)
, multi_index(mul)
, ring_index(rin)
@@ -81,10 +81,10 @@ struct segment_identifier
}
#endif
- signed_index_type source_index;
- signed_index_type multi_index;
- signed_index_type ring_index;
- signed_index_type segment_index;
+ signed_size_type source_index;
+ signed_size_type multi_index;
+ signed_size_type ring_index;
+ signed_size_type segment_index;
};
diff --git a/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp b/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
index b1f984ffe1..a74cb83f77 100644
--- a/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
+++ b/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
@@ -12,6 +12,7 @@
#include <cstddef>
+#include <boost/mpl/vector_c.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/access.hpp>
diff --git a/boost/geometry/algorithms/detail/overlay/traverse.hpp b/boost/geometry/algorithms/detail/overlay/traverse.hpp
index 59d2ba703e..803a164711 100644
--- a/boost/geometry/algorithms/detail/overlay/traverse.hpp
+++ b/boost/geometry/algorithms/detail/overlay/traverse.hpp
@@ -18,6 +18,7 @@
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
@@ -116,8 +117,8 @@ inline bool assign_next_ip(G1 const& g1, G2 const& g2,
return false;
}
- BOOST_ASSERT(info.enriched.travels_to_vertex_index >= 0);
- BOOST_ASSERT(info.enriched.travels_to_ip_index >= 0);
+ BOOST_GEOMETRY_ASSERT(info.enriched.travels_to_vertex_index >= 0);
+ BOOST_GEOMETRY_ASSERT(info.enriched.travels_to_ip_index >= 0);
if (info.seg_id.source_index == 0)
{
@@ -150,8 +151,8 @@ inline bool assign_next_ip(G1 const& g1, G2 const& g2,
inline bool select_source(operation_type operation,
- signed_index_type source1,
- signed_index_type source2)
+ signed_size_type source1,
+ signed_size_type source2)
{
return (operation == operation_intersection && source1 != source2)
|| (operation == operation_union && source1 == source2)
diff --git a/boost/geometry/algorithms/detail/partition.hpp b/boost/geometry/algorithms/detail/partition.hpp
index 25a34ba2ec..8b19add479 100644
--- a/boost/geometry/algorithms/detail/partition.hpp
+++ b/boost/geometry/algorithms/detail/partition.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2011-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2011-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,10 +14,13 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
+#include <cstddef>
#include <vector>
-#include <boost/range/algorithm/copy.hpp>
-#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/range.hpp>
+#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+
namespace boost { namespace geometry
{
@@ -20,8 +28,6 @@ namespace boost { namespace geometry
namespace detail { namespace partition
{
-typedef std::vector<std::size_t> index_vector_type;
-
template <int Dimension, typename Box>
inline void divide_box(Box const& box, Box& lower_box, Box& upper_box)
{
@@ -38,31 +44,26 @@ inline void divide_box(Box const& box, Box& lower_box, Box& upper_box)
geometry::set<min_corner, Dimension>(upper_box, mid);
}
-// Divide collection into three subsets: lower, upper and oversized
+// Divide forward_range into three subsets: lower, upper and oversized
// (not-fitting)
// (lower == left or bottom, upper == right or top)
-template <typename OverlapsPolicy, typename InputCollection, typename Box>
+template <typename OverlapsPolicy, typename Box, typename IteratorVector>
inline void divide_into_subsets(Box const& lower_box,
Box const& upper_box,
- InputCollection const& collection,
- index_vector_type const& input,
- index_vector_type& lower,
- index_vector_type& upper,
- index_vector_type& exceeding)
+ IteratorVector const& input,
+ IteratorVector& lower,
+ IteratorVector& upper,
+ IteratorVector& exceeding)
{
- typedef boost::range_iterator
+ typedef typename boost::range_iterator
<
- index_vector_type const
- >::type index_iterator_type;
+ IteratorVector const
+ >::type it_type;
- for(index_iterator_type it = boost::begin(input);
- it != boost::end(input);
- ++it)
+ for(it_type it = boost::begin(input); it != boost::end(input); ++it)
{
- bool const lower_overlapping = OverlapsPolicy::apply(lower_box,
- collection[*it]);
- bool const upper_overlapping = OverlapsPolicy::apply(upper_box,
- collection[*it]);
+ bool const lower_overlapping = OverlapsPolicy::apply(lower_box, **it);
+ bool const upper_overlapping = OverlapsPolicy::apply(upper_box, **it);
if (lower_overlapping && upper_overlapping)
{
@@ -84,99 +85,109 @@ inline void divide_into_subsets(Box const& lower_box,
}
}
-template <typename ExpandPolicy, typename Box, typename InputCollection>
-inline void expand_with_elements(Box& total,
- InputCollection const& collection,
- index_vector_type const& input)
+template
+<
+ typename ExpandPolicy,
+ typename Box,
+ typename IteratorVector
+>
+inline void expand_with_elements(Box& total, IteratorVector const& input)
{
- typedef boost::range_iterator<index_vector_type const>::type it_type;
+ typedef typename boost::range_iterator<IteratorVector const>::type it_type;
for(it_type it = boost::begin(input); it != boost::end(input); ++it)
{
- ExpandPolicy::apply(total, collection[*it]);
+ ExpandPolicy::apply(total, **it);
}
}
-// Match collection with itself
-template <typename InputCollection, typename Policy>
-inline void handle_one(InputCollection const& collection,
- index_vector_type const& input,
- Policy& policy)
+// Match forward_range with itself
+template <typename Policy, typename IteratorVector>
+inline void handle_one(IteratorVector const& input, Policy& policy)
{
if (boost::size(input) == 0)
{
return;
}
- typedef boost::range_iterator<index_vector_type const>::type
- index_iterator_type;
+ typedef typename boost::range_iterator<IteratorVector const>::type it_type;
// Quadratic behaviour at lowest level (lowest quad, or all exceeding)
- for(index_iterator_type it1 = boost::begin(input);
- it1 != boost::end(input);
- ++it1)
+ for (it_type it1 = boost::begin(input); it1 != boost::end(input); ++it1)
{
- index_iterator_type it2 = it1;
- for(++it2; it2 != boost::end(input); ++it2)
+ it_type it2 = it1;
+ for (++it2; it2 != boost::end(input); ++it2)
{
- policy.apply(collection[*it1], collection[*it2]);
+ policy.apply(**it1, **it2);
}
}
}
-// Match collection 1 with collection 2
+// Match forward range 1 with forward range 2
template
<
- typename InputCollection1,
- typename InputCollection2,
- typename Policy
+ typename Policy,
+ typename IteratorVector1,
+ typename IteratorVector2
>
-inline void handle_two(
- InputCollection1 const& collection1, index_vector_type const& input1,
- InputCollection2 const& collection2, index_vector_type const& input2,
+inline void handle_two(IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
Policy& policy)
{
+ typedef typename boost::range_iterator
+ <
+ IteratorVector1 const
+ >::type iterator_type1;
+
+ typedef typename boost::range_iterator
+ <
+ IteratorVector2 const
+ >::type iterator_type2;
+
if (boost::size(input1) == 0 || boost::size(input2) == 0)
{
return;
}
- typedef boost::range_iterator
- <
- index_vector_type const
- >::type index_iterator_type;
-
- for(index_iterator_type it1 = boost::begin(input1);
+ for(iterator_type1 it1 = boost::begin(input1);
it1 != boost::end(input1);
++it1)
{
- for(index_iterator_type it2 = boost::begin(input2);
+ for(iterator_type2 it2 = boost::begin(input2);
it2 != boost::end(input2);
++it2)
{
- policy.apply(collection1[*it1], collection2[*it2]);
+ policy.apply(**it1, **it2);
}
}
}
-inline bool recurse_ok(index_vector_type const& input,
+template <typename IteratorVector>
+inline bool recurse_ok(IteratorVector const& input,
std::size_t min_elements, std::size_t level)
{
return boost::size(input) >= min_elements
&& level < 100;
}
-inline bool recurse_ok(index_vector_type const& input1,
- index_vector_type const& input2,
+template <typename IteratorVector1, typename IteratorVector2>
+inline bool recurse_ok(IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
std::size_t min_elements, std::size_t level)
{
return boost::size(input1) >= min_elements
&& recurse_ok(input2, min_elements, level);
}
-inline bool recurse_ok(index_vector_type const& input1,
- index_vector_type const& input2,
- index_vector_type const& input3,
+template
+<
+ typename IteratorVector1,
+ typename IteratorVector2,
+ typename IteratorVector3
+>
+inline bool recurse_ok(IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
+ IteratorVector3 const& input3,
std::size_t min_elements, std::size_t level)
{
return boost::size(input1) >= min_elements
@@ -193,7 +204,7 @@ template
typename ExpandPolicy2,
typename VisitBoxPolicy
>
-class partition_two_collections;
+class partition_two_ranges;
template
@@ -204,79 +215,71 @@ template
typename ExpandPolicy,
typename VisitBoxPolicy
>
-class partition_one_collection
+class partition_one_range
{
- typedef std::vector<std::size_t> index_vector_type;
-
- template <typename InputCollection>
- static inline Box get_new_box(InputCollection const& collection,
- index_vector_type const& input)
+ template <typename IteratorVector>
+ static inline Box get_new_box(IteratorVector const& input)
{
Box box;
geometry::assign_inverse(box);
- expand_with_elements<ExpandPolicy>(box, collection, input);
+ expand_with_elements<ExpandPolicy>(box, input);
return box;
}
- template <typename InputCollection, typename Policy>
+ template <typename Policy, typename IteratorVector>
static inline void next_level(Box const& box,
- InputCollection const& collection,
- index_vector_type const& input,
+ IteratorVector const& input,
std::size_t level, std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
{
if (recurse_ok(input, min_elements, level))
{
- partition_one_collection
+ partition_one_range
<
1 - Dimension,
Box,
OverlapsPolicy,
ExpandPolicy,
VisitBoxPolicy
- >::apply(box, collection, input,
- level + 1, min_elements, policy, box_policy);
+ >::apply(box, input, level + 1, min_elements, policy, box_policy);
}
else
{
- handle_one(collection, input, policy);
+ handle_one(input, policy);
}
}
- // Function to switch to two collections if there are geometries exceeding
- // the separation line
- template <typename InputCollection, typename Policy>
+ // Function to switch to two forward ranges if there are
+ // geometries exceeding the separation line
+ template <typename Policy, typename IteratorVector>
static inline void next_level2(Box const& box,
- InputCollection const& collection,
- index_vector_type const& input1,
- index_vector_type const& input2,
+ IteratorVector const& input1,
+ IteratorVector const& input2,
std::size_t level, std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
{
-
if (recurse_ok(input1, input2, min_elements, level))
{
- partition_two_collections
+ partition_two_ranges
<
1 - Dimension,
Box,
OverlapsPolicy, OverlapsPolicy,
ExpandPolicy, ExpandPolicy,
VisitBoxPolicy
- >::apply(box, collection, input1, collection, input2,
- level + 1, min_elements, policy, box_policy);
+ >::apply(box, input1, input2, level + 1, min_elements,
+ policy, box_policy);
}
else
{
- handle_two(collection, input1, collection, input2, policy);
+ handle_two(input1, input2, policy);
}
}
public :
- template <typename InputCollection, typename Policy>
+ template <typename Policy, typename IteratorVector>
static inline void apply(Box const& box,
- InputCollection const& collection,
- index_vector_type const& input,
+ IteratorVector const& input,
std::size_t level,
std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
@@ -286,33 +289,31 @@ public :
Box lower_box, upper_box;
divide_box<Dimension>(box, lower_box, upper_box);
- index_vector_type lower, upper, exceeding;
- divide_into_subsets<OverlapsPolicy>(lower_box, upper_box, collection,
+ IteratorVector lower, upper, exceeding;
+ divide_into_subsets<OverlapsPolicy>(lower_box, upper_box,
input, lower, upper, exceeding);
if (boost::size(exceeding) > 0)
{
// Get the box of exceeding-only
- Box exceeding_box = get_new_box(collection, exceeding);
+ Box exceeding_box = get_new_box(exceeding);
// Recursively do exceeding elements only, in next dimension they
// will probably be less exceeding within the new box
- next_level(exceeding_box, collection, exceeding, level,
- min_elements, policy, box_policy);
-
- // Switch to two collections, combine exceeding with lower resp upper
- // but not lower/lower, upper/upper
- next_level2(exceeding_box, collection, exceeding, lower, level,
- min_elements, policy, box_policy);
- next_level2(exceeding_box, collection, exceeding, upper, level,
- min_elements, policy, box_policy);
+ next_level(exceeding_box, exceeding, level, min_elements,
+ policy, box_policy);
+
+ // Switch to two forward ranges, combine exceeding with
+ // lower resp upper, but not lower/lower, upper/upper
+ next_level2(exceeding_box, exceeding, lower, level, min_elements,
+ policy, box_policy);
+ next_level2(exceeding_box, exceeding, upper, level, min_elements,
+ policy, box_policy);
}
// Recursively call operation both parts
- next_level(lower_box, collection, lower, level, min_elements,
- policy, box_policy);
- next_level(upper_box, collection, upper, level, min_elements,
- policy, box_policy);
+ next_level(lower_box, lower, level, min_elements, policy, box_policy);
+ next_level(upper_box, upper, level, min_elements, policy, box_policy);
}
};
@@ -326,25 +327,21 @@ template
typename ExpandPolicy2,
typename VisitBoxPolicy
>
-class partition_two_collections
+class partition_two_ranges
{
- typedef std::vector<std::size_t> index_vector_type;
-
template
<
- typename InputCollection1,
- typename InputCollection2,
- typename Policy
+ typename Policy,
+ typename IteratorVector1,
+ typename IteratorVector2
>
static inline void next_level(Box const& box,
- InputCollection1 const& collection1,
- index_vector_type const& input1,
- InputCollection2 const& collection2,
- index_vector_type const& input2,
+ IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
std::size_t level, std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
{
- partition_two_collections
+ partition_two_ranges
<
1 - Dimension,
Box,
@@ -353,50 +350,38 @@ class partition_two_collections
ExpandPolicy1,
ExpandPolicy2,
VisitBoxPolicy
- >::apply(box, collection1, input1, collection2, input2,
- level + 1, min_elements,
- policy, box_policy);
+ >::apply(box, input1, input2, level + 1, min_elements,
+ policy, box_policy);
}
- template
- <
- typename ExpandPolicy,
- typename InputCollection
- >
- static inline Box get_new_box(InputCollection const& collection,
- index_vector_type const& input)
+ template <typename ExpandPolicy, typename IteratorVector>
+ static inline Box get_new_box(IteratorVector const& input)
{
Box box;
geometry::assign_inverse(box);
- expand_with_elements<ExpandPolicy>(box, collection, input);
+ expand_with_elements<ExpandPolicy>(box, input);
return box;
}
- template
- <
- typename InputCollection1,
- typename InputCollection2
- >
- static inline Box get_new_box(InputCollection1 const& collection1,
- index_vector_type const& input1,
- InputCollection2 const& collection2,
- index_vector_type const& input2)
+ template <typename IteratorVector1, typename IteratorVector2>
+ static inline Box get_new_box(IteratorVector1 const& input1,
+ IteratorVector2 const& input2)
{
- Box box = get_new_box<ExpandPolicy1>(collection1, input1);
- expand_with_elements<ExpandPolicy2>(box, collection2, input2);
+ Box box = get_new_box<ExpandPolicy1>(input1);
+ expand_with_elements<ExpandPolicy2>(box, input2);
return box;
}
public :
template
<
- typename InputCollection1,
- typename InputCollection2,
- typename Policy
+ typename Policy,
+ typename IteratorVector1,
+ typename IteratorVector2
>
static inline void apply(Box const& box,
- InputCollection1 const& collection1, index_vector_type const& input1,
- InputCollection2 const& collection2, index_vector_type const& input2,
+ IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
std::size_t level,
std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
@@ -406,11 +391,11 @@ public :
Box lower_box, upper_box;
divide_box<Dimension>(box, lower_box, upper_box);
- index_vector_type lower1, upper1, exceeding1;
- index_vector_type lower2, upper2, exceeding2;
- divide_into_subsets<OverlapsPolicy1>(lower_box, upper_box, collection1,
+ IteratorVector1 lower1, upper1, exceeding1;
+ IteratorVector2 lower2, upper2, exceeding2;
+ divide_into_subsets<OverlapsPolicy1>(lower_box, upper_box,
input1, lower1, upper1, exceeding1);
- divide_into_subsets<OverlapsPolicy2>(lower_box, upper_box, collection2,
+ divide_into_subsets<OverlapsPolicy2>(lower_box, upper_box,
input2, lower2, upper2, exceeding2);
if (boost::size(exceeding1) > 0)
@@ -419,35 +404,31 @@ public :
if (recurse_ok(exceeding1, exceeding2, min_elements, level))
{
- Box exceeding_box = get_new_box(collection1, exceeding1,
- collection2, exceeding2);
- next_level(exceeding_box, collection1, exceeding1,
- collection2, exceeding2, level,
- min_elements, policy, box_policy);
+ Box exceeding_box = get_new_box(exceeding1, exceeding2);
+ next_level(exceeding_box, exceeding1, exceeding2, level,
+ min_elements, policy, box_policy);
}
else
{
- handle_two(collection1, exceeding1, collection2, exceeding2,
- policy);
+ handle_two(exceeding1, exceeding2, policy);
}
// All exceeding from 1 with lower and upper of 2:
- // (Check sizes of all three collections to avoid recurse into
+ // (Check sizes of all three forward ranges to avoid recurse into
// the same combinations again and again)
if (recurse_ok(lower2, upper2, exceeding1, min_elements, level))
{
- Box exceeding_box
- = get_new_box<ExpandPolicy1>(collection1, exceeding1);
- next_level(exceeding_box, collection1, exceeding1,
- collection2, lower2, level, min_elements, policy, box_policy);
- next_level(exceeding_box, collection1, exceeding1,
- collection2, upper2, level, min_elements, policy, box_policy);
+ Box exceeding_box = get_new_box<ExpandPolicy1>(exceeding1);
+ next_level(exceeding_box, exceeding1, lower2, level,
+ min_elements, policy, box_policy);
+ next_level(exceeding_box, exceeding1, upper2, level,
+ min_elements, policy, box_policy);
}
else
{
- handle_two(collection1, exceeding1, collection2, lower2, policy);
- handle_two(collection1, exceeding1, collection2, upper2, policy);
+ handle_two(exceeding1, lower2, policy);
+ handle_two(exceeding1, upper2, policy);
}
}
@@ -456,37 +437,36 @@ public :
// All exceeding from 2 with lower and upper of 1:
if (recurse_ok(lower1, upper1, exceeding2, min_elements, level))
{
- Box exceeding_box
- = get_new_box<ExpandPolicy2>(collection2, exceeding2);
- next_level(exceeding_box, collection1, lower1,
- collection2, exceeding2, level, min_elements, policy, box_policy);
- next_level(exceeding_box, collection1, upper1,
- collection2, exceeding2, level, min_elements, policy, box_policy);
+ Box exceeding_box = get_new_box<ExpandPolicy2>(exceeding2);
+ next_level(exceeding_box, lower1, exceeding2, level,
+ min_elements, policy, box_policy);
+ next_level(exceeding_box, upper1, exceeding2, level,
+ min_elements, policy, box_policy);
}
else
{
- handle_two(collection1, lower1, collection2, exceeding2, policy);
- handle_two(collection1, upper1, collection2, exceeding2, policy);
+ handle_two(lower1, exceeding2, policy);
+ handle_two(upper1, exceeding2, policy);
}
}
if (recurse_ok(lower1, lower2, min_elements, level))
{
- next_level(lower_box, collection1, lower1, collection2, lower2, level,
- min_elements, policy, box_policy);
+ next_level(lower_box, lower1, lower2, level,
+ min_elements, policy, box_policy);
}
else
{
- handle_two(collection1, lower1, collection2, lower2, policy);
+ handle_two(lower1, lower2, policy);
}
if (recurse_ok(upper1, upper2, min_elements, level))
{
- next_level(upper_box, collection1, upper1, collection2, upper2, level,
- min_elements, policy, box_policy);
+ next_level(upper_box, upper1, upper2, level,
+ min_elements, policy, box_policy);
}
else
{
- handle_two(collection1, upper1, collection2, upper2, policy);
+ handle_two(upper1, upper2, policy);
}
}
};
@@ -523,63 +503,67 @@ template
>
class partition
{
- typedef std::vector<std::size_t> index_vector_type;
-
- template <typename ExpandPolicy, typename IncludePolicy, typename InputCollection>
- static inline void expand_to_collection(InputCollection const& collection,
- Box& total, index_vector_type& index_vector)
+ template
+ <
+ typename ExpandPolicy,
+ typename IncludePolicy,
+ typename ForwardRange,
+ typename IteratorVector
+ >
+ static inline void expand_to_range(ForwardRange const& forward_range,
+ Box& total, IteratorVector& iterator_vector)
{
- std::size_t index = 0;
- for(typename boost::range_iterator<InputCollection const>::type it
- = boost::begin(collection);
- it != boost::end(collection);
- ++it, ++index)
+ for(typename boost::range_iterator<ForwardRange const>::type it
+ = boost::begin(forward_range);
+ it != boost::end(forward_range);
+ ++it)
{
if (IncludePolicy::apply(*it))
{
ExpandPolicy::apply(total, *it);
- index_vector.push_back(index);
+ iterator_vector.push_back(it);
}
}
}
public :
- template <typename InputCollection, typename VisitPolicy>
- static inline void apply(InputCollection const& collection,
+ template <typename ForwardRange, typename VisitPolicy>
+ static inline void apply(ForwardRange const& forward_range,
VisitPolicy& visitor,
std::size_t min_elements = 16,
VisitBoxPolicy box_visitor = detail::partition::visit_no_policy()
)
{
- if (std::size_t(boost::size(collection)) > min_elements)
+ typedef typename boost::range_iterator
+ <
+ ForwardRange const
+ >::type iterator_type;
+
+ if (std::size_t(boost::size(forward_range)) > min_elements)
{
- index_vector_type index_vector;
+ std::vector<iterator_type> iterator_vector;
Box total;
assign_inverse(total);
- expand_to_collection<ExpandPolicy1, IncludePolicy1>(collection,
- total, index_vector);
+ expand_to_range<ExpandPolicy1, IncludePolicy1>(forward_range,
+ total, iterator_vector);
- detail::partition::partition_one_collection
+ detail::partition::partition_one_range
<
0, Box,
OverlapsPolicy1,
ExpandPolicy1,
VisitBoxPolicy
- >::apply(total, collection, index_vector, 0, min_elements,
- visitor, box_visitor);
+ >::apply(total, iterator_vector, 0, min_elements,
+ visitor, box_visitor);
}
else
{
- typedef typename boost::range_iterator
- <
- InputCollection const
- >::type iterator_type;
- for(iterator_type it1 = boost::begin(collection);
- it1 != boost::end(collection);
+ for(iterator_type it1 = boost::begin(forward_range);
+ it1 != boost::end(forward_range);
++it1)
{
iterator_type it2 = it1;
- for(++it2; it2 != boost::end(collection); ++it2)
+ for(++it2; it2 != boost::end(forward_range); ++it2)
{
visitor.apply(*it1, *it2);
}
@@ -589,53 +573,55 @@ public :
template
<
- typename InputCollection1,
- typename InputCollection2,
+ typename ForwardRange1,
+ typename ForwardRange2,
typename VisitPolicy
>
- static inline void apply(InputCollection1 const& collection1,
- InputCollection2 const& collection2,
+ static inline void apply(ForwardRange1 const& forward_range1,
+ ForwardRange2 const& forward_range2,
VisitPolicy& visitor,
std::size_t min_elements = 16,
- VisitBoxPolicy box_visitor = detail::partition::visit_no_policy()
+ VisitBoxPolicy box_visitor
+ = detail::partition::visit_no_policy()
)
{
- if (std::size_t(boost::size(collection1)) > min_elements
- && std::size_t(boost::size(collection2)) > min_elements)
+ typedef typename boost::range_iterator
+ <
+ ForwardRange1 const
+ >::type iterator_type1;
+
+ typedef typename boost::range_iterator
+ <
+ ForwardRange2 const
+ >::type iterator_type2;
+
+ if (std::size_t(boost::size(forward_range1)) > min_elements
+ && std::size_t(boost::size(forward_range2)) > min_elements)
{
- index_vector_type index_vector1, index_vector2;
+ std::vector<iterator_type1> iterator_vector1;
+ std::vector<iterator_type2> iterator_vector2;
Box total;
assign_inverse(total);
- expand_to_collection<ExpandPolicy1, IncludePolicy1>(collection1,
- total, index_vector1);
- expand_to_collection<ExpandPolicy2, IncludePolicy2>(collection2,
- total, index_vector2);
+ expand_to_range<ExpandPolicy1, IncludePolicy1>(forward_range1,
+ total, iterator_vector1);
+ expand_to_range<ExpandPolicy2, IncludePolicy2>(forward_range2,
+ total, iterator_vector2);
- detail::partition::partition_two_collections
+ detail::partition::partition_two_ranges
<
0, Box, OverlapsPolicy1, OverlapsPolicy2,
ExpandPolicy1, ExpandPolicy2, VisitBoxPolicy
- >::apply(total,
- collection1, index_vector1,
- collection2, index_vector2,
- 0, min_elements, visitor, box_visitor);
+ >::apply(total, iterator_vector1, iterator_vector2,
+ 0, min_elements, visitor, box_visitor);
}
else
{
- typedef typename boost::range_iterator
- <
- InputCollection1 const
- >::type iterator_type1;
- typedef typename boost::range_iterator
- <
- InputCollection2 const
- >::type iterator_type2;
- for(iterator_type1 it1 = boost::begin(collection1);
- it1 != boost::end(collection1);
+ for(iterator_type1 it1 = boost::begin(forward_range1);
+ it1 != boost::end(forward_range1);
++it1)
{
- for(iterator_type2 it2 = boost::begin(collection2);
- it2 != boost::end(collection2);
+ for(iterator_type2 it2 = boost::begin(forward_range2);
+ it2 != boost::end(forward_range2);
++it2)
{
visitor.apply(*it1, *it2);
diff --git a/boost/geometry/algorithms/detail/recalculate.hpp b/boost/geometry/algorithms/detail/recalculate.hpp
index 2c3ea7413b..056f7c6e1d 100644
--- a/boost/geometry/algorithms/detail/recalculate.hpp
+++ b/boost/geometry/algorithms/detail/recalculate.hpp
@@ -21,6 +21,7 @@
#include <boost/mpl/if.hpp>
#include <boost/numeric/conversion/bounds.hpp>
#include <boost/numeric/conversion/cast.hpp>
+#include <boost/range.hpp>
#include <boost/type_traits.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
diff --git a/boost/geometry/algorithms/detail/relate/areal_areal.hpp b/boost/geometry/algorithms/detail/relate/areal_areal.hpp
index 2859841de4..cc9c1b67ca 100644
--- a/boost/geometry/algorithms/detail/relate/areal_areal.hpp
+++ b/boost/geometry/algorithms/detail/relate/areal_areal.hpp
@@ -88,7 +88,7 @@ public:
// TODO: This is O(N)
// Run in a loop O(NM) - optimize!
int const pig = detail::within::point_in_geometry(pt, m_other_areal);
- //BOOST_ASSERT( pig != 0 );
+ //BOOST_GEOMETRY_ASSERT( pig != 0 );
// inside
if ( pig > 0 )
@@ -104,9 +104,9 @@ public:
// Check if any interior ring is outside
ring_identifier ring_id(0, -1, 0);
- int const irings_count = boost::numeric_cast<int>(
- geometry::num_interior_rings(areal) );
- for ( ; ring_id.ring_index < irings_count ; ++ring_id.ring_index )
+ std::size_t const irings_count = geometry::num_interior_rings(areal);
+ for ( ; static_cast<std::size_t>(ring_id.ring_index) < irings_count ;
+ ++ring_id.ring_index )
{
typename detail::sub_range_return_type<Areal const>::type
range_ref = detail::sub_range(areal, ring_id);
@@ -140,9 +140,9 @@ public:
// Check if any interior ring is inside
ring_identifier ring_id(0, -1, 0);
- int const irings_count = boost::numeric_cast<int>(
- geometry::num_interior_rings(areal) );
- for ( ; ring_id.ring_index < irings_count ; ++ring_id.ring_index )
+ std::size_t const irings_count = geometry::num_interior_rings(areal);
+ for ( ; static_cast<std::size_t>(ring_id.ring_index) < irings_count ;
+ ++ring_id.ring_index )
{
typename detail::sub_range_return_type<Areal const>::type
range_ref = detail::sub_range(areal, ring_id);
@@ -405,7 +405,7 @@ struct areal_areal
typename TurnIt>
void apply(Result & result, TurnIt it)
{
- //BOOST_ASSERT( it != last );
+ //BOOST_GEOMETRY_ASSERT( it != last );
overlay::operation_type const op = it->operations[op_id].operation;
@@ -498,7 +498,7 @@ struct areal_areal
template <typename Result>
void apply(Result & result)
{
- //BOOST_ASSERT( first != last );
+ //BOOST_GEOMETRY_ASSERT( first != last );
if ( m_exit_detected /*m_previous_operation == overlay::operation_union*/ )
{
@@ -618,7 +618,7 @@ struct areal_areal
// O(N) - running it in a loop gives O(NM)
int const pig = detail::within::point_in_geometry(range::front(range_ref), other_geometry);
- //BOOST_ASSERT(pig != 0);
+ //BOOST_GEOMETRY_ASSERT(pig != 0);
if ( pig > 0 )
{
update<interior, interior, '2', transpose_result>(m_result);
@@ -793,8 +793,8 @@ struct areal_areal
{
segment_identifier const& seg_id = turn.operations[OpId].seg_id;
- signed_index_type
- count = boost::numeric_cast<signed_index_type>(
+ signed_size_type
+ count = boost::numeric_cast<signed_size_type>(
geometry::num_interior_rings(
detail::single_geometry(analyser.geometry, seg_id)));
@@ -804,8 +804,8 @@ struct areal_areal
template <typename Analyser, typename Turn>
static inline void for_no_turns_rings(Analyser & analyser,
Turn const& turn,
- signed_index_type first,
- signed_index_type last)
+ signed_size_type first,
+ signed_size_type last)
{
segment_identifier seg_id = turn.operations[OpId].seg_id;
diff --git a/boost/geometry/algorithms/detail/relate/boundary_checker.hpp b/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
index f98c3e9b82..9de1bacb7d 100644
--- a/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
+++ b/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
@@ -47,7 +47,7 @@ public:
boost::ignore_unused_variable_warning(pt);
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
// may give false positives for INT
- BOOST_ASSERT( (BoundaryQuery == boundary_front || BoundaryQuery == boundary_any)
+ BOOST_GEOMETRY_ASSERT( (BoundaryQuery == boundary_front || BoundaryQuery == boundary_any)
&& detail::equals::equals_point_point(pt, range::front(geometry))
|| (BoundaryQuery == boundary_back || BoundaryQuery == boundary_any)
&& detail::equals::equals_point_point(pt, range::back(geometry)) );
diff --git a/boost/geometry/algorithms/detail/relate/de9im.hpp b/boost/geometry/algorithms/detail/relate/de9im.hpp
new file mode 100644
index 0000000000..713a3fc8f0
--- /dev/null
+++ b/boost/geometry/algorithms/detail/relate/de9im.hpp
@@ -0,0 +1,439 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP
+
+#include <boost/mpl/is_sequence.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/vector_c.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/tuple/tuple.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/result.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/core/topological_dimension.hpp>
+#include <boost/geometry/core/tag.hpp>
+
+// TEMP - move this header to geometry/detail
+#include <boost/geometry/index/detail/tuples.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace de9im
+{
+
+/*!
+\brief DE-9IM model intersection matrix.
+\ingroup de9im
+\details This matrix can be used to express spatial relations as defined in
+ Dimensionally Extended 9-Intersection Model.
+
+\qbk{[heading See also]}
+\qbk{* [link geometry.reference.algorithms.relation relation]}
+ */
+class matrix
+ : public detail::relate::matrix<3, 3>
+{
+#ifdef DOXYGEN_INVOKED
+public:
+ /*!
+ \brief Initializes all of the matrix elements to F
+ */
+ matrix();
+ /*!
+ \brief Subscript operator
+ \param index The index of the element
+ \return The element
+ */
+ char operator[](std::size_t index) const;
+ /*!
+ \brief Returns the iterator to the first element
+ \return const RandomAccessIterator
+ */
+ const_iterator begin() const;
+ /*!
+ \brief Returns the iterator past the last element
+ \return const RandomAccessIterator
+ */
+ const_iterator end() const;
+ /*!
+ \brief Returns the number of elements
+ \return 9
+ */
+ static std::size_t size();
+ /*!
+ \brief Returns raw pointer to elements
+ \return const pointer to array of elements
+ */
+ inline const char * data() const;
+ /*!
+ \brief Returns std::string containing elements
+ \return string containing elements
+ */
+ inline std::string str() const;
+#endif
+};
+
+/*!
+\brief DE-9IM model intersection mask.
+\ingroup de9im
+\details This mask can be used to check spatial relations as defined in
+ Dimensionally Extended 9-Intersection Model.
+
+\qbk{[heading See also]}
+\qbk{* [link geometry.reference.algorithms.relate relate]}
+ */
+class mask
+ : public detail::relate::mask<3, 3>
+{
+ typedef detail::relate::mask<3, 3> base_type;
+
+public:
+ /*!
+ \brief The constructor.
+ \param code The mask pattern.
+ */
+ inline explicit mask(const char* code)
+ : base_type(code)
+ {}
+
+ /*!
+ \brief The constructor.
+ \param code The mask pattern.
+ */
+ inline explicit mask(std::string const& code)
+ : base_type(code.c_str(), code.size())
+ {}
+};
+
+// static_mask
+
+/*!
+\brief DE-9IM model intersection mask (static version).
+\ingroup de9im
+\details This mask can be used to check spatial relations as defined in
+ Dimensionally Extended 9-Intersection Model.
+\tparam II Interior/Interior intersection mask element
+\tparam IB Interior/Boundary intersection mask element
+\tparam IE Interior/Exterior intersection mask element
+\tparam BI Boundary/Interior intersection mask element
+\tparam BB Boundary/Boundary intersection mask element
+\tparam BE Boundary/Exterior intersection mask element
+\tparam EI Exterior/Interior intersection mask element
+\tparam EB Exterior/Boundary intersection mask element
+\tparam EE Exterior/Exterior intersection mask element
+
+\qbk{[heading See also]}
+\qbk{* [link geometry.reference.algorithms.relate relate]}
+ */
+template
+<
+ char II = '*', char IB = '*', char IE = '*',
+ char BI = '*', char BB = '*', char BE = '*',
+ char EI = '*', char EB = '*', char EE = '*'
+>
+class static_mask
+ : public detail::relate::static_mask
+ <
+ boost::mpl::vector_c
+ <
+ char, II, IB, IE, BI, BB, BE, EI, EB, EE
+ >,
+ 3, 3
+ >
+{};
+
+} // namespace de9im
+
+namespace detail { namespace de9im
+{
+
+// a small helper util for ORing static masks
+
+template
+<
+ typename Seq,
+ typename T,
+ bool IsSeq = boost::mpl::is_sequence<Seq>::value
+>
+struct push_back
+{
+ typedef typename boost::mpl::push_back
+ <
+ Seq,
+ T
+ >::type type;
+};
+
+template <typename Seq, typename T>
+struct push_back<Seq, T, false>
+{};
+
+}} // namespace detail::de9im
+
+namespace de9im
+{
+
+inline
+boost::tuples::cons
+ <
+ mask,
+ boost::tuples::cons<mask, boost::tuples::null_type>
+ >
+operator||(mask const& m1, mask const& m2)
+{
+ namespace bt = boost::tuples;
+
+ return bt::cons<mask, bt::cons<mask, bt::null_type> >
+ ( m1, bt::cons<mask, bt::null_type>(m2, bt::null_type()) );
+}
+
+template <typename Tail>
+inline
+typename index::detail::tuples::push_back
+ <
+ boost::tuples::cons<mask, Tail>,
+ mask
+ >::type
+operator||(boost::tuples::cons<mask, Tail> const& t, mask const& m)
+{
+ namespace bt = boost::tuples;
+
+ return index::detail::tuples::push_back
+ <
+ bt::cons<mask, Tail>,
+ mask
+ >::apply(t, m);
+}
+
+template
+<
+ char II1, char IB1, char IE1,
+ char BI1, char BB1, char BE1,
+ char EI1, char EB1, char EE1,
+ char II2, char IB2, char IE2,
+ char BI2, char BB2, char BE2,
+ char EI2, char EB2, char EE2
+>
+inline
+boost::mpl::vector<
+ static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1>,
+ static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2>
+>
+operator||(static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1> const& ,
+ static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2> const& )
+{
+ return boost::mpl::vector
+ <
+ static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1>,
+ static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2>
+ >();
+}
+
+template
+<
+ typename Seq,
+ char II, char IB, char IE,
+ char BI, char BB, char BE,
+ char EI, char EB, char EE
+>
+inline
+typename detail::de9im::push_back
+ <
+ Seq,
+ static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
+ >::type
+operator||(Seq const& ,
+ static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE> const& )
+{
+ return typename detail::de9im::push_back
+ <
+ Seq,
+ static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
+ >::type();
+}
+
+} // namespace de9im
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace de9im
+{
+
+// PREDEFINED MASKS
+
+// TODO:
+// 1. specialize for simplified masks if available
+// e.g. for TOUCHES use 1 mask for A/A
+// 2. Think about dimensions > 2 e.g. should TOUCHES be true
+// if the interior of the Areal overlaps the boundary of the Volumetric
+// like it's true for Linear/Areal
+
+// EQUALS
+template <typename Geometry1, typename Geometry2>
+struct static_mask_equals_type
+{
+ typedef geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', 'F', 'F', '*'> type; // wikipedia
+ //typedef geometry::de9im::static_mask<'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F', 'T'> type; // OGC
+};
+
+// DISJOINT
+template <typename Geometry1, typename Geometry2>
+struct static_mask_disjoint_type
+{
+ typedef geometry::de9im::static_mask<'F', 'F', '*', 'F', 'F', '*', '*', '*', '*'> type;
+};
+
+// TOUCHES - NOT P/P
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
+ std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value
+>
+struct static_mask_touches_impl
+{
+ typedef boost::mpl::vector
+ <
+ geometry::de9im::static_mask<'F', 'T', '*', '*', '*', '*', '*', '*', '*'>,
+ geometry::de9im::static_mask<'F', '*', '*', 'T', '*', '*', '*', '*', '*'>,
+ geometry::de9im::static_mask<'F', '*', '*', '*', 'T', '*', '*', '*', '*'>
+ > type;
+};
+// According to OGC, doesn't apply to P/P
+// Using the above mask the result would be always false
+template <typename Geometry1, typename Geometry2>
+struct static_mask_touches_impl<Geometry1, Geometry2, 0, 0>
+ : not_implemented<typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type>
+{};
+
+template <typename Geometry1, typename Geometry2>
+struct static_mask_touches_type
+ : static_mask_touches_impl<Geometry1, Geometry2>
+{};
+
+// WITHIN
+template <typename Geometry1, typename Geometry2>
+struct static_mask_within_type
+{
+ typedef geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'> type;
+};
+
+// COVERED_BY (non OGC)
+template <typename Geometry1, typename Geometry2>
+struct static_mask_covered_by_type
+{
+ typedef boost::mpl::vector
+ <
+ geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'>,
+ geometry::de9im::static_mask<'*', 'T', 'F', '*', '*', 'F', '*', '*', '*'>,
+ geometry::de9im::static_mask<'*', '*', 'F', 'T', '*', 'F', '*', '*', '*'>,
+ geometry::de9im::static_mask<'*', '*', 'F', '*', 'T', 'F', '*', '*', '*'>
+ > type;
+};
+
+// CROSSES
+// dim(G1) < dim(G2) - P/L P/A L/A
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
+ std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value,
+ bool D1LessD2 = (Dim1 < Dim2)
+>
+struct static_mask_crosses_impl
+{
+ typedef geometry::de9im::static_mask<'T', '*', 'T', '*', '*', '*', '*', '*', '*'> type;
+};
+// TODO: I'm not sure if this one below should be available!
+// dim(G1) > dim(G2) - L/P A/P A/L
+template
+<
+ typename Geometry1, typename Geometry2, std::size_t Dim1, std::size_t Dim2
+>
+struct static_mask_crosses_impl<Geometry1, Geometry2, Dim1, Dim2, false>
+{
+ typedef geometry::de9im::static_mask<'T', '*', '*', '*', '*', '*', 'T', '*', '*'> type;
+};
+// dim(G1) == dim(G2) - P/P A/A
+template
+<
+ typename Geometry1, typename Geometry2, std::size_t Dim
+>
+struct static_mask_crosses_impl<Geometry1, Geometry2, Dim, Dim, false>
+ : not_implemented
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type
+ >
+{};
+// dim(G1) == 1 && dim(G2) == 1 - L/L
+template <typename Geometry1, typename Geometry2>
+struct static_mask_crosses_impl<Geometry1, Geometry2, 1, 1, false>
+{
+ typedef geometry::de9im::static_mask<'0', '*', '*', '*', '*', '*', '*', '*', '*'> type;
+};
+
+template <typename Geometry1, typename Geometry2>
+struct static_mask_crosses_type
+ : static_mask_crosses_impl<Geometry1, Geometry2>
+{};
+
+// OVERLAPS
+
+// dim(G1) != dim(G2) - NOT P/P, L/L, A/A
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
+ std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value
+>
+struct static_mask_overlaps_impl
+ : not_implemented
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type
+ >
+{};
+// dim(G1) == D && dim(G2) == D - P/P A/A
+template <typename Geometry1, typename Geometry2, std::size_t Dim>
+struct static_mask_overlaps_impl<Geometry1, Geometry2, Dim, Dim>
+{
+ typedef geometry::de9im::static_mask<'T', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
+};
+// dim(G1) == 1 && dim(G2) == 1 - L/L
+template <typename Geometry1, typename Geometry2>
+struct static_mask_overlaps_impl<Geometry1, Geometry2, 1, 1>
+{
+ typedef geometry::de9im::static_mask<'1', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
+};
+
+template <typename Geometry1, typename Geometry2>
+struct static_mask_overlaps_type
+ : static_mask_overlaps_impl<Geometry1, Geometry2>
+{};
+
+}} // namespace detail::de9im
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP
diff --git a/boost/geometry/algorithms/detail/relate/follow_helpers.hpp b/boost/geometry/algorithms/detail/relate/follow_helpers.hpp
index 2c44b009e7..20122471e5 100644
--- a/boost/geometry/algorithms/detail/relate/follow_helpers.hpp
+++ b/boost/geometry/algorithms/detail/relate/follow_helpers.hpp
@@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_FOLLOW_HELPERS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_FOLLOW_HELPERS_HPP
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
//#include <boost/geometry/algorithms/detail/sub_range.hpp>
@@ -89,7 +91,7 @@ struct for_each_disjoint_geometry_if<OpId, Geometry, Tag, true>
Geometry const& geometry,
Pred & pred)
{
- BOOST_ASSERT(first != last);
+ BOOST_GEOMETRY_ASSERT(first != last);
const std::size_t count = boost::size(geometry);
boost::ignore_unused_variable_warning(count);
@@ -99,10 +101,10 @@ struct for_each_disjoint_geometry_if<OpId, Geometry, Tag, true>
std::vector<bool> detected_intersections(count, false);
for ( TurnIt it = first ; it != last ; ++it )
{
- signed_index_type multi_index = it->operations[OpId].seg_id.multi_index;
- BOOST_ASSERT(multi_index >= 0);
+ signed_size_type multi_index = it->operations[OpId].seg_id.multi_index;
+ BOOST_GEOMETRY_ASSERT(multi_index >= 0);
std::size_t const index = static_cast<std::size_t>(multi_index);
- BOOST_ASSERT(index < count);
+ BOOST_GEOMETRY_ASSERT(index < count);
detected_intersections[index] = true;
}
@@ -141,12 +143,12 @@ public:
{}
segment_identifier const& seg_id() const
{
- BOOST_ASSERT(sid_ptr);
+ BOOST_GEOMETRY_ASSERT(sid_ptr);
return *sid_ptr;
}
Point const& point() const
{
- BOOST_ASSERT(pt_ptr);
+ BOOST_GEOMETRY_ASSERT(pt_ptr);
return *pt_ptr;
}
@@ -300,15 +302,15 @@ public:
point_type const& get_exit_point() const
{
- BOOST_ASSERT(m_exit_operation != overlay::operation_none);
- BOOST_ASSERT(m_exit_turn_ptr);
+ BOOST_GEOMETRY_ASSERT(m_exit_operation != overlay::operation_none);
+ BOOST_GEOMETRY_ASSERT(m_exit_turn_ptr);
return m_exit_turn_ptr->point;
}
TurnInfo const& get_exit_turn() const
{
- BOOST_ASSERT(m_exit_operation != overlay::operation_none);
- BOOST_ASSERT(m_exit_turn_ptr);
+ BOOST_GEOMETRY_ASSERT(m_exit_operation != overlay::operation_none);
+ BOOST_GEOMETRY_ASSERT(m_exit_turn_ptr);
return *m_exit_turn_ptr;
}
diff --git a/boost/geometry/algorithms/detail/relate/implementation.hpp b/boost/geometry/algorithms/detail/relate/implementation.hpp
new file mode 100644
index 0000000000..a6f1545ed1
--- /dev/null
+++ b/boost/geometry/algorithms/detail/relate/implementation.hpp
@@ -0,0 +1,110 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_ALGORITHMS_DETAIL_RELATE_IMPLEMENTATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_IMPLEMENTATION_HPP
+
+
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/interface.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/point_point.hpp>
+#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
+#include <boost/geometry/algorithms/detail/relate/linear_linear.hpp>
+#include <boost/geometry/algorithms/detail/relate/linear_areal.hpp>
+#include <boost/geometry/algorithms/detail/relate/areal_areal.hpp>
+
+
+namespace boost { namespace geometry {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+template <typename Point1, typename Point2>
+struct relate<Point1, Point2, point_tag, point_tag, 0, 0, false>
+ : detail::relate::point_point<Point1, Point2>
+{};
+
+template <typename Point, typename MultiPoint>
+struct relate<Point, MultiPoint, point_tag, multi_point_tag, 0, 0, false>
+ : detail::relate::point_multipoint<Point, MultiPoint>
+{};
+
+template <typename MultiPoint, typename Point>
+struct relate<MultiPoint, Point, multi_point_tag, point_tag, 0, 0, false>
+ : detail::relate::multipoint_point<MultiPoint, Point>
+{};
+
+template <typename MultiPoint1, typename MultiPoint2>
+struct relate<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag, 0, 0, false>
+ : detail::relate::multipoint_multipoint<MultiPoint1, MultiPoint2>
+{};
+
+// TODO - for now commented out because before implementing it we must consider:
+// 1. how the Box degenerated to a Point should be treated
+// 2. what should be the definition of a Box degenerated to a Point
+// 3. what fields should the matrix/mask contain for dimension > 2 and dimension > 9
+//
+//template <typename Point, typename Box, int TopDim2>
+//struct relate<Point, Box, point_tag, box_tag, 0, TopDim2, false>
+// : detail::relate::point_box<Point, Box>
+//{};
+//
+//template <typename Box, typename Point, int TopDim1>
+//struct relate<Box, Point, box_tag, point_tag, TopDim1, 0, false>
+// : detail::relate::box_point<Box, Point>
+//{};
+
+
+template <typename Point, typename Geometry, typename Tag2, int TopDim2>
+struct relate<Point, Geometry, point_tag, Tag2, 0, TopDim2, true>
+ : detail::relate::point_geometry<Point, Geometry>
+{};
+
+template <typename Geometry, typename Point, typename Tag1, int TopDim1>
+struct relate<Geometry, Point, Tag1, point_tag, TopDim1, 0, true>
+ : detail::relate::geometry_point<Geometry, Point>
+{};
+
+
+template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
+struct relate<Linear1, Linear2, Tag1, Tag2, 1, 1, true>
+ : detail::relate::linear_linear<Linear1, Linear2>
+{};
+
+
+template <typename Linear, typename Areal, typename Tag1, typename Tag2>
+struct relate<Linear, Areal, Tag1, Tag2, 1, 2, true>
+ : detail::relate::linear_areal<Linear, Areal>
+{};
+
+template <typename Areal, typename Linear, typename Tag1, typename Tag2>
+struct relate<Areal, Linear, Tag1, Tag2, 2, 1, true>
+ : detail::relate::areal_linear<Areal, Linear>
+{};
+
+
+template <typename Areal1, typename Areal2, typename Tag1, typename Tag2>
+struct relate<Areal1, Areal2, Tag1, Tag2, 2, 2, true>
+ : detail::relate::areal_areal<Areal1, Areal2>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_IMPLEMENTATION_HPP
diff --git a/boost/geometry/algorithms/detail/relate/interface.hpp b/boost/geometry/algorithms/detail/relate/interface.hpp
new file mode 100644
index 0000000000..e2c067b68d
--- /dev/null
+++ b/boost/geometry/algorithms/detail/relate/interface.hpp
@@ -0,0 +1,348 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
+
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/core/topological_dimension.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/de9im.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+
+
+namespace boost { namespace geometry {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace relate {
+
+// Those are used only to allow dispatch::relate to produce compile-time error
+
+template <typename Geometry,
+ typename Tag = typename geometry::tag<Geometry>::type>
+struct is_supported_by_generic
+{
+ static const bool value
+ = boost::is_same<Tag, linestring_tag>::value
+ || boost::is_same<Tag, multi_linestring_tag>::value
+ || boost::is_same<Tag, ring_tag>::value
+ || boost::is_same<Tag, polygon_tag>::value
+ || boost::is_same<Tag, multi_polygon_tag>::value;
+};
+
+template <typename Geometry1,
+ typename Geometry2,
+ typename Tag1 = typename geometry::tag<Geometry1>::type,
+ typename Tag2 = typename geometry::tag<Geometry2>::type>
+struct is_generic
+{
+ static const bool value = is_supported_by_generic<Geometry1>::value
+ && is_supported_by_generic<Geometry2>::value;
+};
+
+
+template <typename Point, typename Geometry, typename Tag>
+struct is_generic<Point, Geometry, point_tag, Tag>
+{
+ static const bool value = is_supported_by_generic<Geometry>::value;
+};
+
+template <typename Geometry, typename Point, typename Tag>
+struct is_generic<Geometry, Point, Tag, point_tag>
+{
+ static const bool value = is_supported_by_generic<Geometry>::value;
+};
+
+template <typename Point1, typename Point2>
+struct is_generic<Point1, Point2, point_tag, point_tag>
+{
+ static const bool value = false;
+};
+
+
+}} // namespace detail::relate
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+
+template <typename Geometry1,
+ typename Geometry2,
+ typename Tag1 = typename geometry::tag<Geometry1>::type,
+ typename Tag2 = typename geometry::tag<Geometry2>::type,
+ int TopDim1 = geometry::topological_dimension<Geometry1>::value,
+ int TopDim2 = geometry::topological_dimension<Geometry2>::value,
+ bool IsGeneric = detail::relate::is_generic<Geometry1, Geometry2>::value
+>
+struct relate : not_implemented<Tag1, Tag2>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace relate {
+
+template <typename Geometry1, typename Geometry2>
+struct interruption_enabled
+{
+ static const bool value =
+ dispatch::relate<Geometry1, Geometry2>::interruption_enabled;
+};
+
+template <typename Geometry1,
+ typename Geometry2,
+ typename Result,
+ bool IsSequence = boost::mpl::is_sequence<Result>::value>
+struct result_handler_type
+ : not_implemented<Result>
+{};
+
+template <typename Geometry1, typename Geometry2>
+struct result_handler_type<Geometry1, Geometry2, geometry::de9im::mask, false>
+{
+ typedef mask_handler
+ <
+ geometry::de9im::mask,
+ interruption_enabled
+ <
+ Geometry1,
+ Geometry2
+ >::value
+ > type;
+};
+
+template <typename Geometry1, typename Geometry2, typename Head, typename Tail>
+struct result_handler_type<Geometry1, Geometry2, boost::tuples::cons<Head, Tail>, false>
+{
+ typedef mask_handler
+ <
+ boost::tuples::cons<Head, Tail>,
+ interruption_enabled
+ <
+ Geometry1,
+ Geometry2
+ >::value
+ > type;
+};
+
+template <typename Geometry1, typename Geometry2,
+ char II, char IB, char IE,
+ char BI, char BB, char BE,
+ char EI, char EB, char EE>
+struct result_handler_type
+ <
+ Geometry1,
+ Geometry2,
+ geometry::de9im::static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>,
+ false
+ >
+{
+ typedef static_mask_handler
+ <
+ geometry::de9im::static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>,
+ interruption_enabled
+ <
+ Geometry1,
+ Geometry2
+ >::value
+ > type;
+};
+
+template <typename Geometry1, typename Geometry2, typename StaticSequence>
+struct result_handler_type<Geometry1, Geometry2, StaticSequence, true>
+{
+ typedef static_mask_handler
+ <
+ StaticSequence,
+ interruption_enabled
+ <
+ Geometry1,
+ Geometry2
+ >::value
+ > type;
+};
+
+}} // namespace detail::relate
+#endif // DOXYGEN_NO_DETAIL
+
+namespace resolve_variant {
+
+template <typename Geometry1, typename Geometry2>
+struct relate
+{
+ template <typename Mask>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Mask const& mask)
+ {
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ assert_dimension_equal<Geometry1, Geometry2>();
+
+ typename detail::relate::result_handler_type
+ <
+ Geometry1,
+ Geometry2,
+ Mask
+ >::type handler(mask);
+
+ dispatch::relate
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, handler);
+
+ return handler.result();
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
+struct relate<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
+{
+ template <typename Mask>
+ struct visitor : boost::static_visitor<bool>
+ {
+ Geometry2 const& m_geometry2;
+ Mask const& m_mask;
+
+ visitor(Geometry2 const& geometry2, Mask const& mask)
+ : m_geometry2(geometry2), m_mask(mask) {}
+
+ template <typename Geometry1>
+ bool operator()(Geometry1 const& geometry1) const
+ {
+ return relate<Geometry1, Geometry2>
+ ::apply(geometry1, m_geometry2, m_mask);
+ }
+ };
+
+ template <typename Mask>
+ static inline bool
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2,
+ Mask const& mask)
+ {
+ return boost::apply_visitor(visitor<Mask>(geometry2, mask), geometry1);
+ }
+};
+
+template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct relate<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Mask>
+ struct visitor : boost::static_visitor<bool>
+ {
+ Geometry1 const& m_geometry1;
+ Mask const& m_mask;
+
+ visitor(Geometry1 const& geometry1, Mask const& mask)
+ : m_geometry1(geometry1), m_mask(mask) {}
+
+ template <typename Geometry2>
+ bool operator()(Geometry2 const& geometry2) const
+ {
+ return relate<Geometry1, Geometry2>
+ ::apply(m_geometry1, geometry2, m_mask);
+ }
+ };
+
+ template <typename Mask>
+ static inline bool
+ apply(Geometry1 const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
+ Mask const& mask)
+ {
+ return boost::apply_visitor(visitor<Mask>(geometry1, mask), geometry2);
+ }
+};
+
+template <
+ BOOST_VARIANT_ENUM_PARAMS(typename T1),
+ BOOST_VARIANT_ENUM_PARAMS(typename T2)
+>
+struct relate<
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
+>
+{
+ template <typename Mask>
+ struct visitor : boost::static_visitor<bool>
+ {
+ Mask const& m_mask;
+
+ visitor(Mask const& mask)
+ : m_mask(mask) {}
+
+ template <typename Geometry1, typename Geometry2>
+ bool operator()(Geometry1 const& geometry1,
+ Geometry2 const& geometry2) const
+ {
+ return relate<Geometry1, Geometry2>
+ ::apply(geometry1, geometry2, m_mask);
+ }
+ };
+
+ template <typename Mask>
+ static inline bool
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
+ Mask const& mask)
+ {
+ return boost::apply_visitor(visitor<Mask>(mask), geometry1, geometry2);
+ }
+};
+
+} // namespace resolve_variant
+
+/*!
+\brief Checks relation between a pair of geometries defined by a mask.
+\ingroup relate
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Mask An intersection model Mask type.
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param mask An intersection model mask object.
+\return true if the relation is compatible with the mask, false otherwise.
+
+\qbk{[include reference/algorithms/relate.qbk]}
+ */
+template <typename Geometry1, typename Geometry2, typename Mask>
+inline bool relate(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Mask const& mask)
+{
+ return resolve_variant::relate
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, mask);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
diff --git a/boost/geometry/algorithms/detail/relate/less.hpp b/boost/geometry/algorithms/detail/relate/less.hpp
index 3f11d4e87d..462fcc35f1 100644
--- a/boost/geometry/algorithms/detail/relate/less.hpp
+++ b/boost/geometry/algorithms/detail/relate/less.hpp
@@ -14,6 +14,10 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LESS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LESS_HPP
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/util/math.hpp>
+
namespace boost { namespace geometry
{
diff --git a/boost/geometry/algorithms/detail/relate/linear_areal.hpp b/boost/geometry/algorithms/detail/relate/linear_areal.hpp
index 7d85a1d9a1..e7cbf6f6c2 100644
--- a/boost/geometry/algorithms/detail/relate/linear_areal.hpp
+++ b/boost/geometry/algorithms/detail/relate/linear_areal.hpp
@@ -15,7 +15,9 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_AREAL_HPP
#include <boost/core/ignore_unused.hpp>
+#include <boost/range/size.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/topological_dimension.hpp>
#include <boost/geometry/util/condition.hpp>
@@ -97,7 +99,7 @@ public:
}
int const pig = detail::within::point_in_geometry(range::front(linestring), m_geometry2);
- //BOOST_ASSERT_MSG(pig != 0, "There should be no IPs");
+ //BOOST_GEOMETRY_ASSERT_MSG(pig != 0, "There should be no IPs");
if ( pig > 0 )
{
@@ -323,8 +325,8 @@ struct linear_areal
// if there was some previous ring
if ( prev_seg_id_ptr != NULL )
{
- signed_index_type const next_ring_index = prev_seg_id_ptr->ring_index + 1;
- BOOST_ASSERT(next_ring_index >= 0);
+ signed_size_type const next_ring_index = prev_seg_id_ptr->ring_index + 1;
+ BOOST_GEOMETRY_ASSERT(next_ring_index >= 0);
// if one of the last rings of previous single geometry was ommited
if ( static_cast<std::size_t>(next_ring_index)
@@ -394,8 +396,8 @@ struct linear_areal
// if there was some previous ring
if ( prev_seg_id_ptr != NULL )
{
- signed_index_type const next_ring_index = prev_seg_id_ptr->ring_index + 1;
- BOOST_ASSERT(next_ring_index >= 0);
+ signed_size_type const next_ring_index = prev_seg_id_ptr->ring_index + 1;
+ BOOST_GEOMETRY_ASSERT(next_ring_index >= 0);
// if one of the last rings of previous single geometry was ommited
if ( static_cast<std::size_t>(next_ring_index)
@@ -456,7 +458,7 @@ struct linear_areal
template <typename TurnIt>
void operator()(TurnIt first, TurnIt last) const
{
- BOOST_ASSERT(first != last);
+ BOOST_GEOMETRY_ASSERT(first != last);
static OpToPriority op_to_priority;
// find the operation with the least priority
int least_priority = op_to_priority(first->operations[0]);
@@ -736,6 +738,8 @@ struct linear_areal
// handle the interior overlap
if ( m_interior_detected )
{
+ BOOST_GEOMETRY_ASSERT_MSG(m_previous_turn_ptr, "non-NULL ptr expected");
+
// real interior overlap
if ( ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it) )
{
@@ -745,21 +749,16 @@ struct linear_areal
// new range detected - reset previous state and check the boundary
if ( first_in_range )
{
- // actually it should be != NULL if m_interior_detected
- // so an assert could be checked here
- if ( m_previous_turn_ptr )
- {
- segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
+ segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
- bool const prev_back_b = is_endpoint_on_boundary<boundary_back>(
- range::back(sub_range(geometry, prev_seg_id)),
- boundary_checker);
+ bool const prev_back_b = is_endpoint_on_boundary<boundary_back>(
+ range::back(sub_range(geometry, prev_seg_id)),
+ boundary_checker);
- // if there is a boundary on the last point
- if ( prev_back_b )
- {
- update<boundary, interior, '0', TransposeResult>(res);
- }
+ // if there is a boundary on the last point
+ if ( prev_back_b )
+ {
+ update<boundary, interior, '0', TransposeResult>(res);
}
// The exit_watcher is reset below
@@ -1002,7 +1001,7 @@ struct linear_areal
/*&& ( op == overlay::operation_blocked
|| op == overlay::operation_union )*/ ) // if we're here it's u or x
{
- BOOST_ASSERT(m_first_from_unknown);
+ BOOST_GEOMETRY_ASSERT(m_first_from_unknown);
m_first_from_unknown_boundary_detected = true;
}
else
@@ -1043,7 +1042,7 @@ struct linear_areal
BoundaryChecker const& boundary_checker)
{
boost::ignore_unused(first, last);
- //BOOST_ASSERT( first != last );
+ //BOOST_GEOMETRY_ASSERT( first != last );
// For MultiPolygon many x/u operations may be generated as a first IP
// if for all turns x/u was generated and any of the Polygons doesn't contain the LineString
@@ -1071,8 +1070,8 @@ struct linear_areal
// for sure
update<interior, exterior, '1', TransposeResult>(res);
- BOOST_ASSERT(first != last);
- BOOST_ASSERT(m_previous_turn_ptr);
+ BOOST_GEOMETRY_ASSERT(first != last);
+ BOOST_GEOMETRY_ASSERT(m_previous_turn_ptr);
segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
@@ -1094,8 +1093,8 @@ struct linear_areal
update<interior, interior, '1', TransposeResult>(res);
m_interior_detected = false;
- BOOST_ASSERT(first != last);
- BOOST_ASSERT(m_previous_turn_ptr);
+ BOOST_GEOMETRY_ASSERT(first != last);
+ BOOST_GEOMETRY_ASSERT(m_previous_turn_ptr);
segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
@@ -1112,7 +1111,7 @@ struct linear_areal
// This condition may be false if the Linestring is lying on the Polygon's collinear spike
// if Polygon's spikes are not handled in get_turns() or relate() (they currently aren't)
- //BOOST_ASSERT_MSG(m_previous_operation != overlay::operation_continue,
+ //BOOST_GEOMETRY_ASSERT_MSG(m_previous_operation != overlay::operation_continue,
// "Unexpected operation! Probably the error in get_turns(L,A) or relate(L,A)");
// Currently one c/c turn is generated for the exit
// when a Linestring is going out on a collinear spike
@@ -1160,16 +1159,16 @@ struct linear_areal
typedef typename boost::range_iterator<range2_type>::type range2_iterator;
range2_type range2(sub_range(geometry2, turn.operations[other_op_id].seg_id));
- BOOST_ASSERT(boost::size(range1));
+ BOOST_GEOMETRY_ASSERT(boost::size(range1));
std::size_t const s2 = boost::size(range2);
- BOOST_ASSERT(s2 > 2);
+ BOOST_GEOMETRY_ASSERT(s2 > 2);
std::size_t const seg_count2 = s2 - 1;
std::size_t const p_seg_ij = static_cast<std::size_t>(turn.operations[op_id].seg_id.segment_index);
std::size_t const q_seg_ij = static_cast<std::size_t>(turn.operations[other_op_id].seg_id.segment_index);
- BOOST_ASSERT(p_seg_ij + 1 < boost::size(range1));
- BOOST_ASSERT(q_seg_ij + 1 < s2);
+ BOOST_GEOMETRY_ASSERT(p_seg_ij + 1 < boost::size(range1));
+ BOOST_GEOMETRY_ASSERT(q_seg_ij + 1 < s2);
point1_type const& pi = range::at(range1, p_seg_ij);
point2_type const& qi = range::at(range2, q_seg_ij);
@@ -1178,8 +1177,8 @@ struct linear_areal
geometry::convert(qi, qi_conv);
bool const is_ip_qj = equals::equals_point_point(turn.point, qj);
// TODO: test this!
-// BOOST_ASSERT(!equals::equals_point_point(turn.point, pi));
-// BOOST_ASSERT(!equals::equals_point_point(turn.point, qi));
+// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, pi));
+// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, qi));
point1_type new_pj;
geometry::convert(turn.point, new_pj);
@@ -1211,7 +1210,7 @@ struct linear_areal
template <typename It>
static inline It find_next_non_duplicated(It first, It current, It last)
{
- BOOST_ASSERT( current != last );
+ BOOST_GEOMETRY_ASSERT( current != last );
It it = current;
@@ -1332,8 +1331,8 @@ struct linear_areal
if ( first == last )
return last;
- signed_index_type const multi_index = first->operations[1].seg_id.multi_index;
- signed_index_type const ring_index = first->operations[1].seg_id.ring_index;
+ signed_size_type const multi_index = first->operations[1].seg_id.multi_index;
+ signed_size_type const ring_index = first->operations[1].seg_id.ring_index;
fun(*first);
++first;
@@ -1379,7 +1378,7 @@ struct linear_areal
if ( is_union_detected )
{
- BOOST_ASSERT(m_previous_turn_ptr != NULL);
+ BOOST_GEOMETRY_ASSERT(m_previous_turn_ptr != NULL);
if ( !detail::equals::equals_point_point(it->point, m_previous_turn_ptr->point) )
{
// break
diff --git a/boost/geometry/algorithms/detail/relate/linear_linear.hpp b/boost/geometry/algorithms/detail/relate/linear_linear.hpp
index 20a22c3018..7a3f373e03 100644
--- a/boost/geometry/algorithms/detail/relate/linear_linear.hpp
+++ b/boost/geometry/algorithms/detail/relate/linear_linear.hpp
@@ -14,7 +14,12 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_LINEAR_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_LINEAR_HPP
+#include <algorithm>
+
#include <boost/core/ignore_unused.hpp>
+#include <boost/range/size.hpp>
+
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
@@ -23,6 +28,7 @@
#include <boost/geometry/algorithms/detail/single_geometry.hpp>
#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
+#include <boost/geometry/algorithms/detail/relate/result.hpp>
#include <boost/geometry/algorithms/detail/relate/turns.hpp>
#include <boost/geometry/algorithms/detail/relate/boundary_checker.hpp>
#include <boost/geometry/algorithms/detail/relate/follow_helpers.hpp>
@@ -576,7 +582,7 @@ struct linear_linear
OtherBoundaryChecker const& /*other_boundary_checker*/)
{
boost::ignore_unused(first, last);
- //BOOST_ASSERT( first != last );
+ //BOOST_GEOMETRY_ASSERT( first != last );
// here, the possible exit is the real one
// we know that we entered and now we exit
@@ -586,7 +592,7 @@ struct linear_linear
{
update<interior, exterior, '1', transpose_result>(res);
- BOOST_ASSERT(first != last);
+ BOOST_GEOMETRY_ASSERT(first != last);
const TurnInfo * turn_ptr = NULL;
if ( m_degenerated_turn_ptr )
@@ -598,7 +604,7 @@ struct linear_linear
{
segment_identifier const& prev_seg_id = turn_ptr->operations[op_id].seg_id;
- //BOOST_ASSERT(!boost::empty(sub_range(geometry, prev_seg_id)));
+ //BOOST_GEOMETRY_ASSERT(!boost::empty(sub_range(geometry, prev_seg_id)));
bool const prev_back_b = is_endpoint_on_boundary<boundary_back>(
range::back(sub_range(geometry, prev_seg_id)),
boundary_checker);
@@ -688,7 +694,7 @@ struct linear_linear
if ( first_in_range )
{
- //BOOST_ASSERT(!boost::empty(ls1_ref));
+ //BOOST_GEOMETRY_ASSERT(!boost::empty(ls1_ref));
bool const front_b = is_endpoint_on_boundary<boundary_front>(
range::front(ls1_ref), boundary_checker);
if ( front_b )
@@ -717,7 +723,7 @@ struct linear_linear
if ( first_in_range )
{
- //BOOST_ASSERT(!boost::empty(ls1_ref));
+ //BOOST_GEOMETRY_ASSERT(!boost::empty(ls1_ref));
bool const front_b = is_endpoint_on_boundary<boundary_front>(
range::front(ls1_ref), boundary_checker);
if ( front_b )
diff --git a/boost/geometry/algorithms/detail/relate/point_geometry.hpp b/boost/geometry/algorithms/detail/relate/point_geometry.hpp
index 62ab100919..be08016a16 100644
--- a/boost/geometry/algorithms/detail/relate/point_geometry.hpp
+++ b/boost/geometry/algorithms/detail/relate/point_geometry.hpp
@@ -18,6 +18,7 @@
//#include <boost/geometry/algorithms/within.hpp>
//#include <boost/geometry/algorithms/covered_by.hpp>
+#include <boost/geometry/algorithms/detail/relate/result.hpp>
#include <boost/geometry/algorithms/detail/relate/topology_check.hpp>
#include <boost/geometry/util/condition.hpp>
@@ -43,18 +44,18 @@ struct point_geometry
if ( pig > 0 ) // within
{
- set<interior, interior, '0', Transpose>(result);
+ relate::set<interior, interior, '0', Transpose>(result);
}
else if ( pig == 0 )
{
- set<interior, boundary, '0', Transpose>(result);
+ relate::set<interior, boundary, '0', Transpose>(result);
}
else // pig < 0 - not within
{
- set<interior, exterior, '0', Transpose>(result);
+ relate::set<interior, exterior, '0', Transpose>(result);
}
- set<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
+ relate::set<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
@@ -69,9 +70,9 @@ struct point_geometry
typedef detail::relate::topology_check<Geometry> tc_t;
//tc_t tc(geometry, point);
//if ( tc.has_interior )
- set<exterior, interior, tc_t::interior, Transpose>(result);
+ relate::set<exterior, interior, tc_t::interior, Transpose>(result);
//if ( tc.has_boundary )
- set<exterior, boundary, tc_t::boundary, Transpose>(result);
+ relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
}
else
{
@@ -79,9 +80,9 @@ struct point_geometry
typedef detail::relate::topology_check<Geometry> tc_t;
tc_t tc(geometry);
if ( tc.has_interior )
- set<exterior, interior, tc_t::interior, Transpose>(result);
+ relate::set<exterior, interior, tc_t::interior, Transpose>(result);
if ( tc.has_boundary )
- set<exterior, boundary, tc_t::boundary, Transpose>(result);
+ relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
}
}
};
diff --git a/boost/geometry/algorithms/detail/relate/point_point.hpp b/boost/geometry/algorithms/detail/relate/point_point.hpp
index e623868b92..e55be08225 100644
--- a/boost/geometry/algorithms/detail/relate/point_point.hpp
+++ b/boost/geometry/algorithms/detail/relate/point_point.hpp
@@ -17,9 +17,12 @@
#include <algorithm>
#include <vector>
+#include <boost/range/empty.hpp>
+
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
#include <boost/geometry/algorithms/detail/relate/less.hpp>
+#include <boost/geometry/algorithms/detail/relate/result.hpp>
namespace boost { namespace geometry
{
@@ -38,15 +41,15 @@ struct point_point
bool equal = detail::equals::equals_point_point(point1, point2);
if ( equal )
{
- set<interior, interior, '0'>(result);
+ relate::set<interior, interior, '0'>(result);
}
else
{
- set<interior, exterior, '0'>(result);
- set<exterior, interior, '0'>(result);
+ relate::set<interior, exterior, '0'>(result);
+ relate::set<exterior, interior, '0'>(result);
}
- set<exterior, exterior, result_dimension<Point1>::value>(result);
+ relate::set<exterior, exterior, result_dimension<Point1>::value>(result);
}
};
@@ -89,7 +92,7 @@ struct point_multipoint
if ( boost::empty(multi_point) )
{
// TODO: throw on empty input?
- set<interior, exterior, '0', Transpose>(result);
+ relate::set<interior, exterior, '0', Transpose>(result);
return;
}
@@ -97,20 +100,20 @@ struct point_multipoint
if ( rel.first ) // some point of MP is equal to P
{
- set<interior, interior, '0', Transpose>(result);
+ relate::set<interior, interior, '0', Transpose>(result);
if ( rel.second ) // a point of MP was found outside P
{
- set<exterior, interior, '0', Transpose>(result);
+ relate::set<exterior, interior, '0', Transpose>(result);
}
}
else
{
- set<interior, exterior, '0', Transpose>(result);
- set<exterior, interior, '0', Transpose>(result);
+ relate::set<interior, exterior, '0', Transpose>(result);
+ relate::set<exterior, interior, '0', Transpose>(result);
}
- set<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
+ relate::set<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
}
};
@@ -144,12 +147,12 @@ struct multipoint_multipoint
}
else if ( empty1 )
{
- set<exterior, interior, '0'>(result);
+ relate::set<exterior, interior, '0'>(result);
return;
}
else if ( empty2 )
{
- set<interior, exterior, '0'>(result);
+ relate::set<interior, exterior, '0'>(result);
return;
}
}
@@ -165,7 +168,7 @@ struct multipoint_multipoint
// NlogN + MlogN
bool all_handled = search<false>(multi_point1, multi_point2, result);
- if ( all_handled || result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION(all_handled || result.interrupt) )
return;
// MlogM + NlogM
@@ -212,23 +215,23 @@ struct multipoint_multipoint
// TODO: if I/I is set for one MPt, this won't be changed when the other one in analysed
// so if e.g. only I/I must be analysed we musn't check the other MPt
- set<interior, interior, '0', Transpose>(result);
+ relate::set<interior, interior, '0', Transpose>(result);
if ( found_outside ) // some point of MP2 was found outside of MP1
{
- set<exterior, interior, '0', Transpose>(result);
+ relate::set<exterior, interior, '0', Transpose>(result);
}
}
else
{
- set<interior, exterior, '0', Transpose>(result);
- set<exterior, interior, '0', Transpose>(result);
+ relate::set<interior, exterior, '0', Transpose>(result);
+ relate::set<exterior, interior, '0', Transpose>(result);
// if no point is intersecting the other MPt then we musn't analyse the reversed case
all_handled = true;
}
- set<exterior, exterior, result_dimension<point_type>::value, Transpose>(result);
+ relate::set<exterior, exterior, result_dimension<point_type>::value, Transpose>(result);
return all_handled;
}
diff --git a/boost/geometry/algorithms/detail/relate/relate.hpp b/boost/geometry/algorithms/detail/relate/relate.hpp
deleted file mode 100644
index 946653452a..0000000000
--- a/boost/geometry/algorithms/detail/relate/relate.hpp
+++ /dev/null
@@ -1,339 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
-
-// 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)
-
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
-#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_HPP
-
-#include <cstddef>
-
-#include <boost/concept_check.hpp>
-#include <boost/range.hpp>
-
-#include <boost/mpl/if.hpp>
-#include <boost/mpl/or.hpp>
-#include <boost/type_traits/is_base_of.hpp>
-
-#include <boost/geometry/algorithms/make.hpp>
-#include <boost/geometry/algorithms/not_implemented.hpp>
-
-#include <boost/geometry/core/access.hpp>
-#include <boost/geometry/core/closure.hpp>
-#include <boost/geometry/core/cs.hpp>
-#include <boost/geometry/core/exterior_ring.hpp>
-#include <boost/geometry/core/interior_rings.hpp>
-#include <boost/geometry/core/point_order.hpp>
-#include <boost/geometry/core/ring_type.hpp>
-#include <boost/geometry/core/interior_rings.hpp>
-#include <boost/geometry/core/tags.hpp>
-
-#include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/geometry/strategies/concepts/within_concept.hpp>
-#include <boost/geometry/strategies/default_strategy.hpp>
-#include <boost/geometry/strategies/within.hpp>
-#include <boost/geometry/util/math.hpp>
-#include <boost/geometry/util/order_as_direction.hpp>
-#include <boost/geometry/views/closeable_view.hpp>
-#include <boost/geometry/views/reversible_view.hpp>
-
-#include <boost/geometry/algorithms/detail/relate/result.hpp>
-
-#include <boost/geometry/algorithms/detail/relate/point_point.hpp>
-#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
-#include <boost/geometry/algorithms/detail/relate/linear_linear.hpp>
-#include <boost/geometry/algorithms/detail/relate/linear_areal.hpp>
-#include <boost/geometry/algorithms/detail/relate/areal_areal.hpp>
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace relate {
-
-// Those are used only to allow dispatch::relate to produce compile-time error
-
-template <typename Geometry,
- typename Tag = typename geometry::tag<Geometry>::type>
-struct is_supported_by_generic
-{
- static const bool value
- = boost::is_same<Tag, linestring_tag>::value
- || boost::is_same<Tag, multi_linestring_tag>::value
- || boost::is_same<Tag, ring_tag>::value
- || boost::is_same<Tag, polygon_tag>::value
- || boost::is_same<Tag, multi_polygon_tag>::value;
-};
-
-template <typename Geometry1,
- typename Geometry2,
- typename Tag1 = typename geometry::tag<Geometry1>::type,
- typename Tag2 = typename geometry::tag<Geometry2>::type>
-struct is_generic
-{
- static const bool value = is_supported_by_generic<Geometry1>::value
- && is_supported_by_generic<Geometry2>::value;
-};
-
-
-template <typename Point, typename Geometry, typename Tag>
-struct is_generic<Point, Geometry, point_tag, Tag>
-{
- static const bool value = is_supported_by_generic<Geometry>::value;
-};
-
-template <typename Geometry, typename Point, typename Tag>
-struct is_generic<Geometry, Point, Tag, point_tag>
-{
- static const bool value = is_supported_by_generic<Geometry>::value;
-};
-
-template <typename Point1, typename Point2>
-struct is_generic<Point1, Point2, point_tag, point_tag>
-{
- static const bool value = false;
-};
-
-
-}} // namespace detail::relate
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace detail_dispatch { namespace relate {
-
-
-template <typename Geometry1,
- typename Geometry2,
- typename Tag1 = typename geometry::tag<Geometry1>::type,
- typename Tag2 = typename geometry::tag<Geometry2>::type,
- int TopDim1 = geometry::topological_dimension<Geometry1>::value,
- int TopDim2 = geometry::topological_dimension<Geometry2>::value,
- bool IsGeneric = detail::relate::is_generic<Geometry1, Geometry2>::value
->
-struct relate : not_implemented<Tag1, Tag2>
-{};
-
-
-template <typename Point1, typename Point2>
-struct relate<Point1, Point2, point_tag, point_tag, 0, 0, false>
- : detail::relate::point_point<Point1, Point2>
-{};
-
-template <typename Point, typename MultiPoint>
-struct relate<Point, MultiPoint, point_tag, multi_point_tag, 0, 0, false>
- : detail::relate::point_multipoint<Point, MultiPoint>
-{};
-
-template <typename MultiPoint, typename Point>
-struct relate<MultiPoint, Point, multi_point_tag, point_tag, 0, 0, false>
- : detail::relate::multipoint_point<MultiPoint, Point>
-{};
-
-template <typename MultiPoint1, typename MultiPoint2>
-struct relate<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag, 0, 0, false>
- : detail::relate::multipoint_multipoint<MultiPoint1, MultiPoint2>
-{};
-
-//template <typename Point, typename Box, int TopDim2>
-//struct relate<Point, Box, point_tag, box_tag, 0, TopDim2, false>
-// : detail::relate::point_box<Point, Box>
-//{};
-//
-//template <typename Box, typename Point, int TopDim1>
-//struct relate<Box, Point, box_tag, point_tag, TopDim1, 0, false>
-// : detail::relate::box_point<Box, Point>
-//{};
-
-
-template <typename Point, typename Geometry, typename Tag2, int TopDim2>
-struct relate<Point, Geometry, point_tag, Tag2, 0, TopDim2, true>
- : detail::relate::point_geometry<Point, Geometry>
-{};
-
-template <typename Geometry, typename Point, typename Tag1, int TopDim1>
-struct relate<Geometry, Point, Tag1, point_tag, TopDim1, 0, true>
- : detail::relate::geometry_point<Geometry, Point>
-{};
-
-
-template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
-struct relate<Linear1, Linear2, Tag1, Tag2, 1, 1, true>
- : detail::relate::linear_linear<Linear1, Linear2>
-{};
-
-
-template <typename Linear, typename Areal, typename Tag1, typename Tag2>
-struct relate<Linear, Areal, Tag1, Tag2, 1, 2, true>
- : detail::relate::linear_areal<Linear, Areal>
-{};
-
-template <typename Areal, typename Linear, typename Tag1, typename Tag2>
-struct relate<Areal, Linear, Tag1, Tag2, 2, 1, true>
- : detail::relate::areal_linear<Areal, Linear>
-{};
-
-
-template <typename Areal1, typename Areal2, typename Tag1, typename Tag2>
-struct relate<Areal1, Areal2, Tag1, Tag2, 2, 2, true>
- : detail::relate::areal_areal<Areal1, Areal2>
-{};
-
-
-}} // namespace detail_dispatch::relate
-#endif // DOXYGEN_NO_DISPATCH
-
-namespace detail { namespace relate {
-
-template <typename Geometry1, typename Geometry2>
-struct interruption_enabled
-{
- static const bool value =
- detail_dispatch::relate::relate<Geometry1, Geometry2>::interruption_enabled;
-};
-
-template <typename Geometry1,
- typename Geometry2,
- typename Result,
- bool IsSequence = boost::mpl::is_sequence<Result>::value>
-struct result_handler_type
- : not_implemented<Result>
-{};
-
-template <typename Geometry1, typename Geometry2>
-struct result_handler_type<Geometry1, Geometry2, matrix9, false>
-{
- typedef matrix_handler<matrix9> type;
-};
-
-template <typename Geometry1, typename Geometry2>
-struct result_handler_type<Geometry1, Geometry2, mask9, false>
-{
- typedef mask_handler
- <
- mask9,
- interruption_enabled
- <
- Geometry1,
- Geometry2
- >::value
- > type;
-};
-
-template <typename Geometry1, typename Geometry2, typename Head, typename Tail>
-struct result_handler_type<Geometry1, Geometry2, boost::tuples::cons<Head, Tail>, false>
-{
- typedef mask_handler
- <
- boost::tuples::cons<Head, Tail>,
- interruption_enabled
- <
- Geometry1,
- Geometry2
- >::value
- > type;
-};
-
-template <typename Geometry1, typename Geometry2,
- char II, char IB, char IE,
- char BI, char BB, char BE,
- char EI, char EB, char EE>
-struct result_handler_type<Geometry1, Geometry2, static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>, false>
-{
- typedef static_mask_handler
- <
- static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>,
- interruption_enabled
- <
- Geometry1,
- Geometry2
- >::value
- > type;
-};
-
-template <typename Geometry1, typename Geometry2, typename StaticSequence>
-struct result_handler_type<Geometry1, Geometry2, StaticSequence, true>
-{
- typedef static_mask_handler
- <
- StaticSequence,
- interruption_enabled
- <
- Geometry1,
- Geometry2
- >::value
- > type;
-};
-
-template <typename MatrixOrMask, typename Geometry1, typename Geometry2>
-inline
-typename result_handler_type
- <
- Geometry1,
- Geometry2,
- MatrixOrMask
- >::type::result_type
-relate(Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- MatrixOrMask const& matrix_or_mask = MatrixOrMask())
-{
- typedef typename result_handler_type
- <
- Geometry1,
- Geometry2,
- MatrixOrMask
- >::type handler_type;
-
- handler_type handler(matrix_or_mask);
- detail_dispatch::relate::relate<Geometry1, Geometry2>::apply(geometry1, geometry2, handler);
- return handler.result();
-}
-
-struct implemented_tag {};
-
-template <template <typename, typename> class StaticMaskTrait,
- typename Geometry1,
- typename Geometry2>
-struct relate_base
- : boost::mpl::if_
- <
- boost::mpl::or_
- <
- boost::is_base_of
- <
- nyi::not_implemented_tag,
- StaticMaskTrait<Geometry1, Geometry2>
- >,
- boost::is_base_of
- <
- nyi::not_implemented_tag,
- detail_dispatch::relate::relate<Geometry1, Geometry2>
- >
- >,
- not_implemented
- <
- typename geometry::tag<Geometry1>::type,
- typename geometry::tag<Geometry2>::type
- >,
- implemented_tag
- >::type
-{
- static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
- {
- typedef typename StaticMaskTrait<Geometry1, Geometry2>::type static_mask;
- return detail::relate::relate<static_mask>(g1, g2);
- }
-};
-
-}} // namespace detail::relate
-#endif // DOXYGEN_NO_DETAIL
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_HPP
diff --git a/boost/geometry/algorithms/detail/relate/relate_impl.hpp b/boost/geometry/algorithms/detail/relate/relate_impl.hpp
new file mode 100644
index 0000000000..e8e422993d
--- /dev/null
+++ b/boost/geometry/algorithms/detail/relate/relate_impl.hpp
@@ -0,0 +1,80 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_IMPL_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_IMPL_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/interface.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/core/tag.hpp>
+
+namespace boost { namespace geometry {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace relate {
+
+struct implemented_tag {};
+
+template <template <typename, typename> class StaticMaskTrait,
+ typename Geometry1,
+ typename Geometry2>
+struct relate_impl
+ : boost::mpl::if_
+ <
+ boost::mpl::or_
+ <
+ boost::is_base_of
+ <
+ nyi::not_implemented_tag,
+ StaticMaskTrait<Geometry1, Geometry2>
+ >,
+ boost::is_base_of
+ <
+ nyi::not_implemented_tag,
+ dispatch::relate<Geometry1, Geometry2>
+ >
+ >,
+ not_implemented
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type
+ >,
+ implemented_tag
+ >::type
+{
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ {
+ typename detail::relate::result_handler_type
+ <
+ Geometry1,
+ Geometry2,
+ typename StaticMaskTrait<Geometry1, Geometry2>::type
+ >::type handler;
+
+ dispatch::relate<Geometry1, Geometry2>::apply(g1, g2, handler);
+
+ return handler.result();
+ }
+};
+
+}} // namespace detail::relate
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_IMPL_HPP
diff --git a/boost/geometry/algorithms/detail/relate/result.hpp b/boost/geometry/algorithms/detail/relate/result.hpp
index e26bda67f2..b7b9264449 100644
--- a/boost/geometry/algorithms/detail/relate/result.hpp
+++ b/boost/geometry/algorithms/detail/relate/result.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
@@ -14,21 +14,24 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
-#include <boost/tuple/tuple.hpp>
+#include <cstddef>
-#include <boost/mpl/is_sequence.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/at.hpp>
#include <boost/mpl/begin.hpp>
+#include <boost/mpl/deref.hpp>
#include <boost/mpl/end.hpp>
+#include <boost/mpl/is_sequence.hpp>
#include <boost/mpl/next.hpp>
-#include <boost/mpl/at.hpp>
-#include <boost/mpl/vector_c.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/integral_constant.hpp>
-#include <boost/geometry/core/topological_dimension.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/exception.hpp>
#include <boost/geometry/util/condition.hpp>
-// TEMP - move this header to geometry/detail
-#include <boost/geometry/index/detail/tuples.hpp>
-
namespace boost { namespace geometry {
#ifndef DOXYGEN_NO_DETAIL
@@ -42,125 +45,110 @@ enum field { interior = 0, boundary = 1, exterior = 2 };
// but for safety reasons (STATIC_ASSERT) we should check if parameter D is valid and set() doesn't do that
// so some additional function could be added, e.g. set_dim()
-// matrix
+// --------------- MATRIX ----------------
-// TODO add height?
+// matrix
-template <std::size_t Width>
+template <std::size_t Height, std::size_t Width = Height>
class matrix
{
- BOOST_STATIC_ASSERT(Width == 2 || Width == 3);
-
public:
-
- static const std::size_t size = Width * Width;
+ typedef char value_type;
+ typedef std::size_t size_type;
+ typedef const char * const_iterator;
+ typedef const_iterator iterator;
+
+ static const std::size_t static_width = Width;
+ static const std::size_t static_height = Height;
+ static const std::size_t static_size = Width * Height;
inline matrix()
{
- ::memset(m_array, 'F', size);
+ ::memset(m_array, 'F', static_size);
}
template <field F1, field F2>
inline char get() const
{
- static const bool in_bounds = F1 * Width + F2 < size;
- return get_dispatch<F1, F2>(integral_constant<bool, in_bounds>());
+ BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
+ static const std::size_t index = F1 * Width + F2;
+ BOOST_STATIC_ASSERT(index < static_size);
+ return m_array[index];
}
template <field F1, field F2, char V>
inline void set()
{
- static const bool in_bounds = F1 * Width + F2 < size;
- set_dispatch<F1, F2, V>(integral_constant<bool, in_bounds>());
+ BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
+ static const std::size_t index = F1 * Width + F2;
+ BOOST_STATIC_ASSERT(index < static_size);
+ m_array[index] = V;
}
- template <field F1, field F2, char D>
- inline void update()
+ inline char operator[](std::size_t index) const
{
- static const bool in_bounds = F1 * Width + F2 < size;
- update_dispatch<F1, F2, D>(integral_constant<bool, in_bounds>());
+ BOOST_GEOMETRY_ASSERT(index < static_size);
+ return m_array[index];
}
-
- inline const char * data() const
+
+ inline const_iterator begin() const
{
return m_array;
}
-private:
- template <field F1, field F2>
- inline char get_dispatch(integral_constant<bool, true>) const
+ inline const_iterator end() const
{
- return m_array[F1 * Width + F2];
+ return m_array + static_size;
}
- template <field F1, field F2>
- inline char get_dispatch(integral_constant<bool, false>) const
+
+ inline static std::size_t size()
{
- return 'F';
+ return static_size;
}
-
- template <field F1, field F2, char V>
- inline void set_dispatch(integral_constant<bool, true>)
+
+ inline const char * data() const
{
- BOOST_STATIC_ASSERT(('0' <= V && V <= '9') || V == 'T' || V == 'F');
- m_array[F1 * Width + F2] = V;
+ return m_array;
}
- template <field F1, field F2, char V>
- inline void set_dispatch(integral_constant<bool, false>)
- {}
- template <field F1, field F2, char D>
- inline void update_dispatch(integral_constant<bool, true>)
+ inline std::string str() const
{
- BOOST_STATIC_ASSERT('0' <= D && D <= '9');
- char c = m_array[F1 * Width + F2];
- if ( D > c || c > '9')
- m_array[F1 * Width + F2] = D;
+ return std::string(m_array, static_size);
}
- template <field F1, field F2, char D>
- inline void update_dispatch(integral_constant<bool, false>)
- {}
- char m_array[size];
-};
-
-// TODO add EnableDimensions parameter?
-
-struct matrix9 {};
-//struct matrix4 {};
-
-// matrix_width
-
-template <typename MatrixOrMask>
-struct matrix_width
- : not_implemented<MatrixOrMask>
-{};
-
-template <>
-struct matrix_width<matrix9>
-{
- static const std::size_t value = 3;
+private:
+ char m_array[static_size];
};
// matrix_handler
template <typename Matrix>
class matrix_handler
- : private matrix<matrix_width<Matrix>::value>
{
- typedef matrix<matrix_width<Matrix>::value> base_t;
-
public:
- typedef std::string result_type;
+ typedef Matrix result_type;
static const bool interrupt = false;
+ matrix_handler()
+ {}
+
matrix_handler(Matrix const&)
{}
- result_type result() const
+ result_type const& result() const
{
- return std::string(this->data(),
- this->data() + base_t::size);
+ return m_matrix;
+ }
+
+ result_type const& matrix() const
+ {
+ return m_matrix;
+ }
+
+ result_type & matrix()
+ {
+ return m_matrix;
}
template <field F1, field F2, char D>
@@ -168,53 +156,124 @@ public:
{
BOOST_STATIC_ASSERT('0' <= D && D <= '9');
- char const c = static_cast<base_t const&>(*this).template get<F1, F2>();
+ char const c = m_matrix.template get<F1, F2>();
return D > c || c > '9';
}
- //template <field F1, field F2>
- //inline char get() const
- //{
- // return static_cast<base_t const&>(*this).template get<F1, F2>();
- //}
-
template <field F1, field F2, char V>
inline void set()
{
- static_cast<base_t&>(*this).template set<F1, F2, V>();
+ static const bool in_bounds = F1 < Matrix::static_height
+ && F2 < Matrix::static_width;
+ typedef boost::integral_constant<bool, in_bounds> in_bounds_t;
+ set_dispatch<F1, F2, V>(in_bounds_t());
}
template <field F1, field F2, char D>
inline void update()
{
- static_cast<base_t&>(*this).template update<F1, F2, D>();
+ static const bool in_bounds = F1 < Matrix::static_height
+ && F2 < Matrix::static_width;
+ typedef boost::integral_constant<bool, in_bounds> in_bounds_t;
+ update_dispatch<F1, F2, D>(in_bounds_t());
}
+
+private:
+ template <field F1, field F2, char V>
+ inline void set_dispatch(integral_constant<bool, true>)
+ {
+ static const std::size_t index = F1 * Matrix::static_width + F2;
+ BOOST_STATIC_ASSERT(index < Matrix::static_size);
+ BOOST_STATIC_ASSERT(('0' <= V && V <= '9') || V == 'T' || V == 'F');
+ m_matrix.template set<F1, F2, V>();
+ }
+ template <field F1, field F2, char V>
+ inline void set_dispatch(integral_constant<bool, false>)
+ {}
+
+ template <field F1, field F2, char D>
+ inline void update_dispatch(integral_constant<bool, true>)
+ {
+ static const std::size_t index = F1 * Matrix::static_width + F2;
+ BOOST_STATIC_ASSERT(index < Matrix::static_size);
+ BOOST_STATIC_ASSERT('0' <= D && D <= '9');
+ char const c = m_matrix.template get<F1, F2>();
+ if ( D > c || c > '9')
+ m_matrix.template set<F1, F2, D>();
+ }
+ template <field F1, field F2, char D>
+ inline void update_dispatch(integral_constant<bool, false>)
+ {}
+
+ Matrix m_matrix;
};
-// RUN-TIME MASKS
+// --------------- RUN-TIME MASK ----------------
-// mask9
+// run-time mask
-class mask9
+template <std::size_t Height, std::size_t Width = Height>
+class mask
{
public:
- static const std::size_t width = 3; // TEMP
+ static const std::size_t static_width = Width;
+ static const std::size_t static_height = Height;
+ static const std::size_t static_size = Width * Height;
+
+ inline mask(const char * s)
+ {
+ char * it = m_array;
+ char * const last = m_array + static_size;
+ for ( ; it != last && *s != '\0' ; ++it, ++s )
+ {
+ char c = *s;
+ check_char(c);
+ *it = c;
+ }
+ if ( it != last )
+ {
+ ::memset(it, '*', last - it);
+ }
+ }
- inline mask9(std::string const& de9im_mask)
+ inline mask(const char * s, std::size_t count)
{
- // TODO: throw an exception here?
- BOOST_ASSERT(de9im_mask.size() == 9);
- ::memcpy(m_mask, de9im_mask.c_str(), 9);
+ if ( count > static_size )
+ {
+ count = static_size;
+ }
+ if ( count > 0 )
+ {
+ std::for_each(s, s + count, check_char);
+ ::memcpy(m_array, s, count);
+ }
+ if ( count < static_size )
+ {
+ ::memset(m_array + count, '*', static_size - count);
+ }
}
template <field F1, field F2>
inline char get() const
{
- return m_mask[F1 * 3 + F2];
+ BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
+ static const std::size_t index = F1 * Width + F2;
+ BOOST_STATIC_ASSERT(index < static_size);
+ return m_array[index];
}
private:
- char m_mask[9];
+ static inline void check_char(char c)
+ {
+ bool const is_valid = c == '*' || c == 'T' || c == 'F'
+ || ( c >= '0' && c <= '9' );
+ if ( !is_valid )
+ {
+ throw geometry::invalid_input_exception();
+ }
+ }
+
+ char m_array[static_size];
};
// interrupt()
@@ -277,18 +336,18 @@ struct interrupt_dispatch_tuple<Masks, N, N>
}
};
-template <typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6, typename T7, typename T8, typename T9>
-struct interrupt_dispatch<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, true>
-{
- typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
+//template <typename T0, typename T1, typename T2, typename T3, typename T4,
+// typename T5, typename T6, typename T7, typename T8, typename T9>
+//struct interrupt_dispatch<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, true>
+//{
+// typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
- template <field F1, field F2, char V>
- static inline bool apply(mask_type const& mask)
- {
- return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
- }
-};
+// template <field F1, field F2, char V>
+// static inline bool apply(mask_type const& mask)
+// {
+// return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
+// }
+//};
template <typename Head, typename Tail>
struct interrupt_dispatch<boost::tuples::cons<Head, Tail>, true>
@@ -363,18 +422,18 @@ struct may_update_dispatch_tuple<Masks, N, N>
}
};
-template <typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6, typename T7, typename T8, typename T9>
-struct may_update_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
-{
- typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
+//template <typename T0, typename T1, typename T2, typename T3, typename T4,
+// typename T5, typename T6, typename T7, typename T8, typename T9>
+//struct may_update_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
+//{
+// typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
- template <field F1, field F2, char D, typename Matrix>
- static inline bool apply(mask_type const& mask, Matrix const& matrix)
- {
- return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
- }
-};
+// template <field F1, field F2, char D, typename Matrix>
+// static inline bool apply(mask_type const& mask, Matrix const& matrix)
+// {
+// return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
+// }
+//};
template <typename Head, typename Tail>
struct may_update_dispatch< boost::tuples::cons<Head, Tail> >
@@ -460,18 +519,18 @@ struct check_dispatch_tuple<Masks, N, N>
}
};
-template <typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6, typename T7, typename T8, typename T9>
-struct check_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
-{
- typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
+//template <typename T0, typename T1, typename T2, typename T3, typename T4,
+// typename T5, typename T6, typename T7, typename T8, typename T9>
+//struct check_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
+//{
+// typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
- template <typename Matrix>
- static inline bool apply(mask_type const& mask, Matrix const& matrix)
- {
- return check_dispatch_tuple<mask_type>::apply(mask, matrix);
- }
-};
+// template <typename Matrix>
+// static inline bool apply(mask_type const& mask, Matrix const& matrix)
+// {
+// return check_dispatch_tuple<mask_type>::apply(mask, matrix);
+// }
+//};
template <typename Head, typename Tail>
struct check_dispatch< boost::tuples::cons<Head, Tail> >
@@ -493,10 +552,10 @@ inline bool check_matrix(Mask const& mask, Matrix const& matrix)
// matrix_width
-template <>
-struct matrix_width<mask9>
+template <typename MatrixOrMask>
+struct matrix_width
{
- static const std::size_t value = 3;
+ static const std::size_t value = MatrixOrMask::static_width;
};
template <typename Tuple,
@@ -526,20 +585,30 @@ struct matrix_width< boost::tuples::cons<Head, Tail> >
value = matrix_width_tuple< boost::tuples::cons<Head, Tail> >::value;
};
-// matrix_handler
+// mask_handler
template <typename Mask, bool Interrupt>
class mask_handler
- : private matrix<matrix_width<Mask>::value>
+ : private matrix_handler
+ <
+ relate::matrix<matrix_width<Mask>::value>
+ >
{
- typedef matrix<matrix_width<Mask>::value> base_t;
+ typedef matrix_handler
+ <
+ relate::matrix<matrix_width<Mask>::value>
+ > base_t;
public:
typedef bool result_type;
bool interrupt;
- inline mask_handler(Mask const& m)
+ inline mask_handler()
+ : interrupt(false)
+ {}
+
+ inline explicit mask_handler(Mask const& m)
: interrupt(false)
, m_mask(m)
{}
@@ -547,23 +616,17 @@ public:
result_type result() const
{
return !interrupt
- && check_matrix(m_mask, static_cast<base_t const&>(*this));
+ && check_matrix(m_mask, base_t::matrix());
}
template <field F1, field F2, char D>
inline bool may_update() const
{
return detail::relate::may_update<F1, F2, D>(
- m_mask, static_cast<base_t const&>(*this)
+ m_mask, base_t::matrix()
);
}
- //template <field F1, field F2>
- //inline char get() const
- //{
- // return static_cast<base_t const&>(*this).template get<F1, F2>();
- //}
-
template <field F1, field F2, char V>
inline void set()
{
@@ -594,29 +657,65 @@ private:
Mask const& m_mask;
};
-// STATIC MASKS
+// --------------- COMPILE-TIME MASK ----------------
+
+// static_check_characters
+template
+<
+ typename Seq,
+ typename First = typename boost::mpl::begin<Seq>::type,
+ typename Last = typename boost::mpl::end<Seq>::type
+>
+struct static_check_characters
+ : static_check_characters
+ <
+ Seq,
+ typename boost::mpl::next<First>::type
+ >
+{
+ typedef typename boost::mpl::deref<First>::type type;
+ static const char value = type::value;
+ static const bool is_valid = (value >= '0' && value <= '9')
+ || value == 'T' || value == 'F' || value == '*';
+ BOOST_MPL_ASSERT_MSG((is_valid),
+ INVALID_STATIC_MASK_CHARACTER,
+ (type));
+};
+
+template <typename Seq, typename Last>
+struct static_check_characters<Seq, Last, Last>
+{};
// static_mask
-template <char II, char IB, char IE,
- char BI, char BB, char BE,
- char EI, char EB, char EE>
-class static_mask
+template
+<
+ typename Seq,
+ std::size_t Height,
+ std::size_t Width = Height
+>
+struct static_mask
{
- typedef boost::mpl::vector_c
- <
- char, II, IB, IE, BI, BB, BE, EI, EB, EE
- > vector_type;
+ static const std::size_t static_width = Width;
+ static const std::size_t static_height = Height;
+ static const std::size_t static_size = Width * Height;
-public:
- template <field F1, field F2>
- struct get
+ BOOST_STATIC_ASSERT(
+ std::size_t(boost::mpl::size<Seq>::type::value) == static_size);
+
+ template <detail::relate::field F1, detail::relate::field F2>
+ struct static_get
{
- BOOST_STATIC_ASSERT(F1 * 3 + F2 < boost::mpl::size<vector_type>::value);
+ BOOST_STATIC_ASSERT(std::size_t(F1) < static_height);
+ BOOST_STATIC_ASSERT(std::size_t(F2) < static_width);
static const char value
- = boost::mpl::at_c<vector_type, F1 * 3 + F2>::type::value;
+ = boost::mpl::at_c<Seq, F1 * static_width + F2>::type::value;
};
+
+private:
+ // check static_mask characters
+ enum { mask_check = sizeof(static_check_characters<Seq>) };
};
// static_should_handle_element
@@ -624,7 +723,7 @@ public:
template <typename StaticMask, field F1, field F2, bool IsSequence>
struct static_should_handle_element_dispatch
{
- static const char mask_el = StaticMask::template get<F1, F2>::value;
+ static const char mask_el = StaticMask::template static_get<F1, F2>::value;
static const bool value = mask_el == 'F'
|| mask_el == 'T'
|| ( mask_el >= '0' && mask_el <= '9' );
@@ -691,7 +790,7 @@ struct static_interrupt_dispatch
template <typename StaticMask, char V, field F1, field F2, bool IsSequence>
struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, IsSequence>
{
- static const char mask_el = StaticMask::template get<F1, F2>::value;
+ static const char mask_el = StaticMask::template static_get<F1, F2>::value;
static const bool value
= ( V >= '0' && V <= '9' ) ?
@@ -756,7 +855,7 @@ struct static_interrupt
template <typename StaticMask, char D, field F1, field F2, bool IsSequence>
struct static_may_update_dispatch
{
- static const char mask_el = StaticMask::template get<F1, F2>::value;
+ static const char mask_el = StaticMask::template static_get<F1, F2>::value;
static const int version
= mask_el == 'F' ? 0
: mask_el == 'T' ? 1
@@ -860,7 +959,7 @@ struct static_may_update
}
};
-// static_check
+// static_check_matrix
template <typename StaticMask, bool IsSequence>
struct static_check_dispatch
@@ -882,7 +981,7 @@ struct static_check_dispatch
template <field F1, field F2>
struct per_one
{
- static const char mask_el = StaticMask::template get<F1, F2>::value;
+ static const char mask_el = StaticMask::template static_get<F1, F2>::value;
static const int version
= mask_el == 'F' ? 0
: mask_el == 'T' ? 1
@@ -982,31 +1081,34 @@ struct static_check_matrix
template <typename StaticMask, bool Interrupt>
class static_mask_handler
- : private matrix<3>
+ : private matrix_handler< matrix<3> >
{
- typedef matrix<3> base_t;
+ typedef matrix_handler< relate::matrix<3> > base_type;
public:
typedef bool result_type;
bool interrupt;
- inline static_mask_handler(StaticMask const& /*dummy*/)
+ inline static_mask_handler()
+ : interrupt(false)
+ {}
+
+ inline explicit static_mask_handler(StaticMask const& /*dummy*/)
: interrupt(false)
{}
result_type result() const
{
return (!Interrupt || !interrupt)
- && static_check_matrix<StaticMask>::
- apply(static_cast<base_t const&>(*this));
+ && static_check_matrix<StaticMask>::apply(base_type::matrix());
}
template <field F1, field F2, char D>
inline bool may_update() const
{
return static_may_update<StaticMask, D, F1, F2>::
- apply(static_cast<base_t const&>(*this));
+ apply(base_type::matrix());
}
template <field F1, field F2>
@@ -1015,12 +1117,6 @@ public:
return static_should_handle_element<StaticMask, F1, F2>::value;
}
- //template <field F1, field F2>
- //inline char get() const
- //{
- // return base_t::template get<F1, F2>();
- //}
-
template <field F1, field F2, char V>
inline void set()
{
@@ -1056,7 +1152,7 @@ private:
template <field F1, field F2, char V>
inline void set_dispatch(integral_constant<int, 1>)
{
- base_t::template set<F1, F2, V>();
+ base_type::template set<F1, F2, V>();
}
// else
template <field F1, field F2, char V>
@@ -1073,7 +1169,7 @@ private:
template <field F1, field F2, char V>
inline void update_dispatch(integral_constant<int, 1>)
{
- base_t::template update<F1, F2, V>();
+ base_type::template update<F1, F2, V>();
}
// else
template <field F1, field F2, char V>
@@ -1081,165 +1177,9 @@ private:
{}
};
-// OPERATORS
-
-template <typename Mask1, typename Mask2> inline
-boost::tuples::cons<
- Mask1,
- boost::tuples::cons<Mask2, boost::tuples::null_type>
->
-operator||(Mask1 const& m1, Mask2 const& m2)
-{
- namespace bt = boost::tuples;
-
- return
- bt::cons< Mask1, bt::cons<Mask2, bt::null_type> >
- ( m1, bt::cons<Mask2, bt::null_type>(m2, bt::null_type()) );
-}
-
-template <typename Head, typename Tail, typename Mask> inline
-typename index::detail::tuples::push_back<
- boost::tuples::cons<Head, Tail>, Mask
->::type
-operator||(boost::tuples::cons<Head, Tail> const& t, Mask const& m)
-{
- namespace bt = boost::tuples;
-
- return
- index::detail::tuples::push_back<
- bt::cons<Head, Tail>, Mask
- >::apply(t, m);
-}
-
-// PREDEFINED MASKS
-
-// TODO:
-// 1. specialize for simplified masks if available
-// e.g. for TOUCHES use 1 mask for A/A
-// 2. Think about dimensions > 2 e.g. should TOUCHES be true
-// if the interior of the Areal overlaps the boundary of the Volumetric
-// like it's true for Linear/Areal
-
-// EQUALS
-template <typename Geometry1, typename Geometry2>
-struct static_mask_equals_type
-{
- typedef static_mask<'T', '*', 'F', '*', '*', 'F', 'F', 'F', '*'> type; // wikipedia
- //typedef static_mask<'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F', 'T'> type; // OGC
-};
-
-// DISJOINT
-typedef static_mask<'F', 'F', '*', 'F', 'F', '*', '*', '*', '*'> static_mask_disjoint;
+// --------------- UTIL FUNCTIONS ----------------
-// TOUCHES - NOT P/P
-template <typename Geometry1,
- typename Geometry2,
- std::size_t Dim1 = topological_dimension<Geometry1>::value,
- std::size_t Dim2 = topological_dimension<Geometry2>::value>
-struct static_mask_touches_impl
-{
- typedef boost::mpl::vector<
- static_mask<'F', 'T', '*', '*', '*', '*', '*', '*', '*'>,
- static_mask<'F', '*', '*', 'T', '*', '*', '*', '*', '*'>,
- static_mask<'F', '*', '*', '*', 'T', '*', '*', '*', '*'>
- > type;
-};
-// According to OGC, doesn't apply to P/P
-// Using the above mask the result would be always false
-template <typename Geometry1, typename Geometry2>
-struct static_mask_touches_impl<Geometry1, Geometry2, 0, 0>
- : not_implemented<typename geometry::tag<Geometry1>::type,
- typename geometry::tag<Geometry2>::type>
-{};
-
-template <typename Geometry1, typename Geometry2>
-struct static_mask_touches_type
- : static_mask_touches_impl<Geometry1, Geometry2>
-{};
-
-// WITHIN
-typedef static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'> static_mask_within;
-
-// COVERED_BY (non OGC)
-typedef boost::mpl::vector<
- static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'>,
- static_mask<'*', 'T', 'F', '*', '*', 'F', '*', '*', '*'>,
- static_mask<'*', '*', 'F', 'T', '*', 'F', '*', '*', '*'>,
- static_mask<'*', '*', 'F', '*', 'T', 'F', '*', '*', '*'>
- > static_mask_covered_by;
-
-// CROSSES
-// dim(G1) < dim(G2) - P/L P/A L/A
-template <typename Geometry1,
- typename Geometry2,
- std::size_t Dim1 = topological_dimension<Geometry1>::value,
- std::size_t Dim2 = topological_dimension<Geometry2>::value,
- bool D1LessD2 = (Dim1 < Dim2)
->
-struct static_mask_crosses_impl
-{
- typedef static_mask<'T', '*', 'T', '*', '*', '*', '*', '*', '*'> type;
-};
-// TODO: I'm not sure if this one below should be available!
-// dim(G1) > dim(G2) - L/P A/P A/L
-template <typename Geometry1, typename Geometry2,
- std::size_t Dim1, std::size_t Dim2
->
-struct static_mask_crosses_impl<Geometry1, Geometry2, Dim1, Dim2, false>
-{
- typedef static_mask<'T', '*', '*', '*', '*', '*', 'T', '*', '*'> type;
-};
-// dim(G1) == dim(G2) - P/P A/A
-template <typename Geometry1, typename Geometry2,
- std::size_t Dim
->
-struct static_mask_crosses_impl<Geometry1, Geometry2, Dim, Dim, false>
- : not_implemented<typename geometry::tag<Geometry1>::type,
- typename geometry::tag<Geometry2>::type>
-{};
-// dim(G1) == 1 && dim(G2) == 1 - L/L
-template <typename Geometry1, typename Geometry2>
-struct static_mask_crosses_impl<Geometry1, Geometry2, 1, 1, false>
-{
- typedef static_mask<'0', '*', '*', '*', '*', '*', '*', '*', '*'> type;
-};
-
-template <typename Geometry1, typename Geometry2>
-struct static_mask_crosses_type
- : static_mask_crosses_impl<Geometry1, Geometry2>
-{};
-
-// OVERLAPS
-
-// dim(G1) != dim(G2) - NOT P/P, L/L, A/A
-template <typename Geometry1,
- typename Geometry2,
- std::size_t Dim1 = topological_dimension<Geometry1>::value,
- std::size_t Dim2 = topological_dimension<Geometry2>::value
->
-struct static_mask_overlaps_impl
- : not_implemented<typename geometry::tag<Geometry1>::type,
- typename geometry::tag<Geometry2>::type>
-{};
-// dim(G1) == D && dim(G2) == D - P/P A/A
-template <typename Geometry1, typename Geometry2, std::size_t Dim>
-struct static_mask_overlaps_impl<Geometry1, Geometry2, Dim, Dim>
-{
- typedef static_mask<'T', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
-};
-// dim(G1) == 1 && dim(G2) == 1 - L/L
-template <typename Geometry1, typename Geometry2>
-struct static_mask_overlaps_impl<Geometry1, Geometry2, 1, 1>
-{
- typedef static_mask<'1', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
-};
-
-template <typename Geometry1, typename Geometry2>
-struct static_mask_overlaps_type
- : static_mask_overlaps_impl<Geometry1, Geometry2>
-{};
-
-// RESULTS/HANDLERS UTILS
+// set
template <field F1, field F2, char V, typename Result>
inline void set(Result & res)
@@ -1273,33 +1213,7 @@ inline void set(Result & res)
set_dispatch<F1, F2, V, Transpose>::apply(res);
}
-template <char V, typename Result>
-inline void set(Result & res)
-{
- res.template set<interior, interior, V>();
- res.template set<interior, boundary, V>();
- res.template set<interior, exterior, V>();
- res.template set<boundary, interior, V>();
- res.template set<boundary, boundary, V>();
- res.template set<boundary, exterior, V>();
- res.template set<exterior, interior, V>();
- res.template set<exterior, boundary, V>();
- res.template set<exterior, exterior, V>();
-}
-
-template <char II, char IB, char IE, char BI, char BB, char BE, char EI, char EB, char EE, typename Result>
-inline void set(Result & res)
-{
- res.template set<interior, interior, II>();
- res.template set<interior, boundary, IB>();
- res.template set<interior, exterior, IE>();
- res.template set<boundary, interior, BI>();
- res.template set<boundary, boundary, BB>();
- res.template set<boundary, exterior, BE>();
- res.template set<exterior, interior, EI>();
- res.template set<exterior, boundary, EB>();
- res.template set<exterior, exterior, EE>();
-}
+// update
template <field F1, field F2, char D, typename Result>
inline void update(Result & res)
@@ -1333,6 +1247,8 @@ inline void update(Result & res)
update_result_dispatch<F1, F2, D, Transpose>::apply(res);
}
+// may_update
+
template <field F1, field F2, char D, typename Result>
inline bool may_update(Result const& res)
{
@@ -1365,13 +1281,7 @@ inline bool may_update(Result const& res)
return may_update_result_dispatch<F1, F2, D, Transpose>::apply(res);
}
-template <typename Result, char II, char IB, char IE, char BI, char BB, char BE, char EI, char EB, char EE>
-inline Result return_result()
-{
- Result res;
- set<II, IB, IE, BI, BB, BE, EI, EB, EE>(res);
- return res;
-}
+// result_dimension
template <typename Geometry>
struct result_dimension
diff --git a/boost/geometry/algorithms/detail/relate/turns.hpp b/boost/geometry/algorithms/detail/relate/turns.hpp
index 636c9756d8..d54948e1f5 100644
--- a/boost/geometry/algorithms/detail/relate/turns.hpp
+++ b/boost/geometry/algorithms/detail/relate/turns.hpp
@@ -84,14 +84,30 @@ struct get_turns
Geometry2 const& geometry2,
InterruptPolicy & interrupt_policy)
{
- static const bool reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value;
- static const bool reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value;
-
RobustPolicy robust_policy = geometry::get_rescale_policy
<
RobustPolicy
>(geometry1, geometry2);
+ apply(turns, geometry1, geometry2, interrupt_policy, robust_policy);
+ }
+
+ template <typename Turns, typename InterruptPolicy>
+ static inline void apply(Turns & turns,
+ Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ InterruptPolicy & interrupt_policy,
+ RobustPolicy const& robust_policy)
+ {
+ static const bool reverse1 = detail::overlay::do_reverse
+ <
+ geometry::point_order<Geometry1>::value
+ >::value;
+
+ static const bool reverse2 = detail::overlay::do_reverse
+ <
+ geometry::point_order<Geometry2>::value
+ >::value;
dispatch::get_turns
<
@@ -255,9 +271,14 @@ struct less
{
static LessOp less_op;
- return left.operations[OpId].fraction < right.operations[OpId].fraction
- || ( left.operations[OpId].fraction == right.operations[OpId].fraction
- && less_op(left, right) );
+ return
+ geometry::math::equals(left.operations[OpId].fraction,
+ right.operations[OpId].fraction)
+ ?
+ less_op(left, right)
+ :
+ (left.operations[OpId].fraction < right.operations[OpId].fraction)
+ ;
}
template <typename Turn>
diff --git a/boost/geometry/algorithms/detail/relation/implementation.hpp b/boost/geometry/algorithms/detail/relation/implementation.hpp
new file mode 100644
index 0000000000..b9a238d6c8
--- /dev/null
+++ b/boost/geometry/algorithms/detail/relation/implementation.hpp
@@ -0,0 +1,18 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_ALGORITHMS_DETAIL_RELATION_IMPLEMENTATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATION_IMPLEMENTATION_HPP
+
+
+#include <boost/geometry/algorithms/detail/relate/implementation.hpp>
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATION_IMPLEMENTATION_HPP
diff --git a/boost/geometry/algorithms/detail/relation/interface.hpp b/boost/geometry/algorithms/detail/relation/interface.hpp
new file mode 100644
index 0000000000..73737cf2c2
--- /dev/null
+++ b/boost/geometry/algorithms/detail/relation/interface.hpp
@@ -0,0 +1,186 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_ALGORITHMS_DETAIL_RELATION_INTERFACE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATION_INTERFACE_HPP
+
+
+#include <boost/geometry/algorithms/detail/relate/interface.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace relate
+{
+
+template <typename Geometry1, typename Geometry2>
+struct result_handler_type<Geometry1, Geometry2, geometry::de9im::matrix, false>
+{
+ typedef matrix_handler<geometry::de9im::matrix> type;
+};
+
+
+}} // namespace detail::relate
+#endif // DOXYGEN_NO_DETAIL
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry1, typename Geometry2>
+struct relation
+{
+ template <typename Matrix>
+ static inline Matrix apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2)
+ {
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ assert_dimension_equal<Geometry1, Geometry2>();
+
+ typename detail::relate::result_handler_type
+ <
+ Geometry1,
+ Geometry2,
+ Matrix
+ >::type handler;
+
+ dispatch::relate
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, handler);
+
+ return handler.result();
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
+struct relation<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
+{
+ template <typename Matrix>
+ struct visitor : boost::static_visitor<Matrix>
+ {
+ Geometry2 const& m_geometry2;
+
+ visitor(Geometry2 const& geometry2)
+ : m_geometry2(geometry2) {}
+
+ template <typename Geometry1>
+ Matrix operator()(Geometry1 const& geometry1) const
+ {
+ return relation<Geometry1, Geometry2>
+ ::template apply<Matrix>(geometry1, m_geometry2);
+ }
+ };
+
+ template <typename Matrix>
+ static inline Matrix
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2)
+ {
+ return boost::apply_visitor(visitor<Matrix>(geometry2), geometry1);
+ }
+};
+
+template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct relation<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Matrix>
+ struct visitor : boost::static_visitor<Matrix>
+ {
+ Geometry1 const& m_geometry1;
+
+ visitor(Geometry1 const& geometry1)
+ : m_geometry1(geometry1) {}
+
+ template <typename Geometry2>
+ Matrix operator()(Geometry2 const& geometry2) const
+ {
+ return relation<Geometry1, Geometry2>
+ ::template apply<Matrix>(m_geometry1, geometry2);
+ }
+ };
+
+ template <typename Matrix>
+ static inline Matrix
+ apply(Geometry1 const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
+ {
+ return boost::apply_visitor(visitor<Matrix>(geometry1), geometry2);
+ }
+};
+
+template
+<
+ BOOST_VARIANT_ENUM_PARAMS(typename T1),
+ BOOST_VARIANT_ENUM_PARAMS(typename T2)
+>
+struct relation
+ <
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
+ >
+{
+ template <typename Matrix>
+ struct visitor : boost::static_visitor<Matrix>
+ {
+ template <typename Geometry1, typename Geometry2>
+ Matrix operator()(Geometry1 const& geometry1,
+ Geometry2 const& geometry2) const
+ {
+ return relation<Geometry1, Geometry2>
+ ::template apply<Matrix>(geometry1, geometry2);
+ }
+ };
+
+ template <typename Matrix>
+ static inline Matrix
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
+ {
+ return boost::apply_visitor(visitor<Matrix>(), geometry1, geometry2);
+ }
+};
+
+} // namespace resolve_variant
+
+
+/*!
+\brief Calculates the relation between a pair of geometries as defined in DE-9IM.
+\ingroup relation
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\return The DE-9IM matrix expressing the relation between geometries.
+
+\qbk{[include reference/algorithms/relation.qbk]}
+ */
+template <typename Geometry1, typename Geometry2>
+inline de9im::matrix relation(Geometry1 const& geometry1,
+ Geometry2 const& geometry2)
+{
+ return resolve_variant::relation
+ <
+ Geometry1,
+ Geometry2
+ >::template apply<de9im::matrix>(geometry1, geometry2);
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
diff --git a/boost/geometry/algorithms/detail/result_inverse.hpp b/boost/geometry/algorithms/detail/result_inverse.hpp
new file mode 100644
index 0000000000..01a1997e49
--- /dev/null
+++ b/boost/geometry/algorithms/detail/result_inverse.hpp
@@ -0,0 +1,44 @@
+// Boost.Geometry
+
+// Copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_ALGORITHMS_DETAIL_RESULT_INVERSE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RESULT_INVERSE_HPP
+
+
+#include <boost/math/constants/constants.hpp>
+
+#include <boost/geometry/core/radius.hpp>
+#include <boost/geometry/core/srs.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/flattening.hpp>
+
+
+namespace boost { namespace geometry { namespace detail
+{
+
+template <typename T>
+struct result_inverse
+{
+ void set(T const& d, T const& a)
+ {
+ distance = d;
+ azimuth = a;
+ }
+
+ T distance;
+ T azimuth;
+};
+
+}}} // namespace boost::geometry::detail
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RESULT_INVERSE_HPP
diff --git a/boost/geometry/algorithms/detail/ring_identifier.hpp b/boost/geometry/algorithms/detail/ring_identifier.hpp
index bc3fe1fef3..9ba39e4a8b 100644
--- a/boost/geometry/algorithms/detail/ring_identifier.hpp
+++ b/boost/geometry/algorithms/detail/ring_identifier.hpp
@@ -15,7 +15,7 @@
#endif
-#include <boost/geometry/algorithms/detail/signed_index_type.hpp>
+#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
namespace boost { namespace geometry
@@ -32,9 +32,9 @@ struct ring_identifier
, ring_index(-1)
{}
- inline ring_identifier(signed_index_type src,
- signed_index_type mul,
- signed_index_type rin)
+ inline ring_identifier(signed_size_type src,
+ signed_size_type mul,
+ signed_size_type rin)
: source_index(src)
, multi_index(mul)
, ring_index(rin)
@@ -68,9 +68,9 @@ struct ring_identifier
#endif
- signed_index_type source_index;
- signed_index_type multi_index;
- signed_index_type ring_index;
+ signed_size_type source_index;
+ signed_size_type multi_index;
+ signed_size_type ring_index;
};
diff --git a/boost/geometry/algorithms/detail/sections/range_by_section.hpp b/boost/geometry/algorithms/detail/sections/range_by_section.hpp
index d139a3fdd2..02cec6cb48 100644
--- a/boost/geometry/algorithms/detail/sections/range_by_section.hpp
+++ b/boost/geometry/algorithms/detail/sections/range_by_section.hpp
@@ -19,11 +19,11 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
-#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
@@ -77,7 +77,7 @@ struct full_section_multi
{
typedef typename boost::range_size<MultiGeometry>::type size_type;
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
section.ring_id.multi_index >= 0
&& size_type(section.ring_id.multi_index) < boost::size(multi)
diff --git a/boost/geometry/algorithms/detail/sections/sectionalize.hpp b/boost/geometry/algorithms/detail/sections/sectionalize.hpp
index a744ea0a34..1ced394353 100644
--- a/boost/geometry/algorithms/detail/sections/sectionalize.hpp
+++ b/boost/geometry/algorithms/detail/sections/sectionalize.hpp
@@ -1,12 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013, 2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -36,6 +36,7 @@
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/detail/recalculate.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
+#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/closure.hpp>
@@ -80,12 +81,14 @@ struct section
ring_identifier ring_id;
Box bounding_box;
- int begin_index;
- int end_index;
+ // NOTE: size_type could be passed as template parameter
+ // NOTE: these probably also could be of type std::size_t
+ signed_size_type begin_index;
+ signed_size_type end_index;
std::size_t count;
std::size_t range_count;
bool duplicate;
- int non_duplicate_index;
+ signed_size_type non_duplicate_index;
bool is_non_duplicate_first;
bool is_non_duplicate_last;
@@ -248,7 +251,7 @@ struct check_duplicate_loop<DimensionCount, DimensionCount>
template <typename T, std::size_t Index, std::size_t Count>
struct assign_loop
{
- static inline void apply(T dims[Count], int const value)
+ static inline void apply(T dims[Count], T const value)
{
dims[Index] = value;
assign_loop<T, Index + 1, Count>::apply(dims, value);
@@ -258,7 +261,7 @@ struct assign_loop
template <typename T, std::size_t Count>
struct assign_loop<T, Count, Count>
{
- static inline void apply(T [Count], int const)
+ static inline void apply(T [Count], T const)
{
}
};
@@ -291,8 +294,8 @@ struct sectionalize_part
typedef typename boost::range_value<Sections>::type section_type;
BOOST_STATIC_ASSERT
(
- (static_cast<int>(section_type::dimension_count)
- == static_cast<int>(boost::mpl::size<DimensionVector>::value))
+ (static_cast<std::size_t>(section_type::dimension_count)
+ == static_cast<std::size_t>(boost::mpl::size<DimensionVector>::value))
);
typedef typename geometry::robust_point_type
@@ -307,8 +310,8 @@ struct sectionalize_part
return;
}
- int index = 0;
- int ndi = 0; // non duplicate index
+ signed_size_type index = 0;
+ signed_size_type ndi = 0; // non duplicate index
section_type section;
bool mark_first_non_duplicated = true;
diff --git a/boost/geometry/algorithms/detail/signed_index_type.hpp b/boost/geometry/algorithms/detail/signed_size_type.hpp
index 36dcf4de4c..db7344ec80 100644
--- a/boost/geometry/algorithms/detail/signed_index_type.hpp
+++ b/boost/geometry/algorithms/detail/signed_size_type.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -8,8 +8,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_INDEX_TYPE_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_INDEX_TYPE_HPP
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_SIZE_TYPE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_SIZE_TYPE_HPP
#include <cstddef>
@@ -20,10 +20,9 @@ namespace boost { namespace geometry
{
-typedef boost::make_signed<std::size_t>::type signed_index_type;
-//typedef std::ptrdiff_t signed_index_type;
+typedef boost::make_signed<std::size_t>::type signed_size_type;
}} // namespace boost::geometry
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_INDEX_TYPE_HPP
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_SIZE_TYPE_HPP
diff --git a/boost/geometry/algorithms/detail/single_geometry.hpp b/boost/geometry/algorithms/detail/single_geometry.hpp
index f38295ada6..31e4401099 100644
--- a/boost/geometry/algorithms/detail/single_geometry.hpp
+++ b/boost/geometry/algorithms/detail/single_geometry.hpp
@@ -14,7 +14,10 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SINGLE_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SINGLE_GEOMETRY_HPP
+#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_base_of.hpp>
+
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/util/range.hpp>
@@ -44,17 +47,12 @@ struct single_geometry
template <typename Geometry>
struct single_geometry<Geometry, true>
{
- typedef typename boost::mpl::if_c
- <
- boost::is_const<Geometry>::value,
- typename boost::range_value<Geometry>::type const&,
- typename boost::range_value<Geometry>::type
- >::type return_type;
+ typedef typename boost::range_reference<Geometry>::type return_type;
template <typename Id>
static inline return_type apply(Geometry & g, Id const& id)
{
- BOOST_ASSERT(id.multi_index >= 0);
+ BOOST_GEOMETRY_ASSERT(id.multi_index >= 0);
typedef typename boost::range_size<Geometry>::type size_type;
return range::at(g, static_cast<size_type>(id.multi_index));
}
diff --git a/boost/geometry/algorithms/detail/sub_range.hpp b/boost/geometry/algorithms/detail/sub_range.hpp
index eda3ce58ba..29edc94e6c 100644
--- a/boost/geometry/algorithms/detail/sub_range.hpp
+++ b/boost/geometry/algorithms/detail/sub_range.hpp
@@ -14,6 +14,9 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
+#include <boost/mpl/if.hpp>
+
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry {
@@ -84,7 +87,7 @@ struct sub_range<Geometry, Tag, true>
template <typename Id> static inline
return_type apply(Geometry & geometry, Id const& id)
{
- BOOST_ASSERT(0 <= id.multi_index);
+ BOOST_GEOMETRY_ASSERT(0 <= id.multi_index);
typedef typename boost::range_size<Geometry>::type size_type;
size_type const mi = static_cast<size_type>(id.multi_index);
return sub_sub_range::apply(range::at(geometry, mi), id);
@@ -111,6 +114,13 @@ sub_range(Geometry & geometry, Id const& id)
return detail_dispatch::sub_range<Geometry>::apply(geometry, id);
}
+template <typename Geometry, typename Id> inline
+typename sub_range_return_type<Geometry const>::type
+sub_range(Geometry const& geometry, Id const& id)
+{
+ return detail_dispatch::sub_range<Geometry const>::apply(geometry, id);
+}
+
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
diff --git a/boost/geometry/algorithms/detail/sweep.hpp b/boost/geometry/algorithms/detail/sweep.hpp
new file mode 100644
index 0000000000..3dc78261f2
--- /dev/null
+++ b/boost/geometry/algorithms/detail/sweep.hpp
@@ -0,0 +1,87 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SWEEP_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SWEEP_HPP
+
+#include <boost/core/ignore_unused.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace sweep
+{
+
+struct no_interrupt_policy
+{
+ static bool const enabled = false;
+
+ template <typename Event>
+ static inline bool apply(Event const&)
+ {
+ return false;
+ }
+};
+
+}} // namespace detail::sweep
+#endif // DOXYGEN_NO_DETAIL
+
+
+template
+<
+ typename Range,
+ typename PriorityQueue,
+ typename InitializationVisitor,
+ typename EventVisitor,
+ typename InterruptPolicy
+>
+inline void sweep(Range const& range, PriorityQueue& queue,
+ InitializationVisitor& initialization_visitor,
+ EventVisitor& event_visitor,
+ InterruptPolicy const& interrupt_policy)
+{
+ typedef typename PriorityQueue::value_type event_type;
+
+ initialization_visitor.apply(range, queue, event_visitor);
+ while (! queue.empty())
+ {
+ event_type event = queue.top();
+ queue.pop();
+ event_visitor.apply(event, queue);
+ if (interrupt_policy.enabled && interrupt_policy.apply(event))
+ {
+ break;
+ }
+ }
+
+ boost::ignore_unused(interrupt_policy);
+}
+
+
+template
+<
+ typename Range,
+ typename PriorityQueue,
+ typename InitializationVisitor,
+ typename EventVisitor
+>
+inline void sweep(Range const& range, PriorityQueue& queue,
+ InitializationVisitor& initialization_visitor,
+ EventVisitor& event_visitor)
+{
+ sweep(range, queue, initialization_visitor, event_visitor,
+ detail::sweep::no_interrupt_policy());
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SWEEP_HPP
diff --git a/boost/geometry/algorithms/detail/thomas_inverse.hpp b/boost/geometry/algorithms/detail/thomas_inverse.hpp
new file mode 100644
index 0000000000..96b237e054
--- /dev/null
+++ b/boost/geometry/algorithms/detail/thomas_inverse.hpp
@@ -0,0 +1,191 @@
+// Boost.Geometry
+
+// Copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_ALGORITHMS_DETAIL_THOMAS_INVERSE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_THOMAS_INVERSE_HPP
+
+
+#include <boost/math/constants/constants.hpp>
+
+#include <boost/geometry/core/radius.hpp>
+#include <boost/geometry/core/srs.hpp>
+
+#include <boost/geometry/util/condition.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/flattening.hpp>
+#include <boost/geometry/algorithms/detail/result_inverse.hpp>
+
+namespace boost { namespace geometry { namespace detail
+{
+
+/*!
+\brief The solution of the inverse problem of geodesics on latlong coordinates,
+ Forsyth-Andoyer-Lambert type approximation with second order terms.
+\author See
+ - Technical Report: PAUL D. THOMAS, MATHEMATICAL MODELS FOR NAVIGATION SYSTEMS, 1965
+ http://www.dtic.mil/docs/citations/AD0627893
+ - Technical Report: PAUL D. THOMAS, SPHEROIDAL GEODESICS, REFERENCE SYSTEMS, AND LOCAL GEOMETRY, 1970
+ http://www.dtic.mil/docs/citations/AD703541
+*/
+template <typename CT, bool EnableDistance, bool EnableAzimuth>
+struct thomas_inverse
+{
+ typedef result_inverse<CT> result_type;
+
+ template <typename T1, typename T2, typename Spheroid>
+ static inline result_type apply(T1 const& lon1,
+ T1 const& lat1,
+ T2 const& lon2,
+ T2 const& lat2,
+ Spheroid const& spheroid)
+ {
+ result_type result;
+
+ // coordinates in radians
+
+ if ( math::equals(lon1, lon2)
+ && math::equals(lat1, lat2) )
+ {
+ result.set(CT(0), CT(0));
+ return result;
+ }
+
+ CT const f = detail::flattening<CT>(spheroid);
+ CT const one_minus_f = CT(1) - f;
+
+// CT const tan_theta1 = one_minus_f * tan(lat1);
+// CT const tan_theta2 = one_minus_f * tan(lat2);
+// CT const theta1 = atan(tan_theta1);
+// CT const theta2 = atan(tan_theta2);
+
+ CT const pi_half = math::pi<CT>() / CT(2);
+ CT const theta1 = math::equals(lat1, pi_half) ? lat1 :
+ math::equals(lat1, -pi_half) ? lat1 :
+ atan(one_minus_f * tan(lat1));
+ CT const theta2 = math::equals(lat2, pi_half) ? lat2 :
+ math::equals(lat2, -pi_half) ? lat2 :
+ atan(one_minus_f * tan(lat2));
+
+ CT const theta_m = (theta1 + theta2) / CT(2);
+ CT const d_theta_m = (theta2 - theta1) / CT(2);
+ CT const d_lambda = lon2 - lon1;
+ CT const d_lambda_m = d_lambda / CT(2);
+
+ CT const sin_theta_m = sin(theta_m);
+ CT const cos_theta_m = cos(theta_m);
+ CT const sin_d_theta_m = sin(d_theta_m);
+ CT const cos_d_theta_m = cos(d_theta_m);
+ CT const sin2_theta_m = math::sqr(sin_theta_m);
+ CT const cos2_theta_m = math::sqr(cos_theta_m);
+ CT const sin2_d_theta_m = math::sqr(sin_d_theta_m);
+ CT const cos2_d_theta_m = math::sqr(cos_d_theta_m);
+ CT const sin_d_lambda_m = sin(d_lambda_m);
+ CT const sin2_d_lambda_m = math::sqr(sin_d_lambda_m);
+
+ CT const H = cos2_theta_m - sin2_d_theta_m;
+ CT const L = sin2_d_theta_m + H * sin2_d_lambda_m;
+ CT const cos_d = CT(1) - CT(2) * L;
+ CT const d = acos(cos_d);
+ CT const sin_d = sin(d);
+
+ CT const one_minus_L = CT(1) - L;
+
+ if ( math::equals(sin_d, CT(0))
+ || math::equals(L, CT(0))
+ || math::equals(one_minus_L, CT(0)) )
+ {
+ result.set(CT(0), CT(0));
+ return result;
+ }
+
+ CT const U = CT(2) * sin2_theta_m * cos2_d_theta_m / one_minus_L;
+ CT const V = CT(2) * sin2_d_theta_m * cos2_theta_m / L;
+ CT const X = U + V;
+ CT const Y = U - V;
+ CT const T = d / sin_d;
+ //CT const D = CT(4) * math::sqr(T);
+ //CT const E = CT(2) * cos_d;
+ //CT const A = D * E;
+ //CT const B = CT(2) * D;
+ //CT const C = T - (A - E) / CT(2);
+
+ if ( BOOST_GEOMETRY_CONDITION(EnableDistance) )
+ {
+ //CT const n1 = X * (A + C*X);
+ //CT const n2 = Y * (B + E*Y);
+ //CT const n3 = D*X*Y;
+
+ //CT const f_sqr = math::sqr(f);
+ //CT const f_sqr_per_64 = f_sqr / CT(64);
+
+ CT const delta1d = f * (T*X-Y) / CT(4);
+ //CT const delta2d = f_sqr_per_64 * (n1 - n2 + n3);
+
+ CT const a = get_radius<0>(spheroid);
+
+ result.distance = a * sin_d * (T - delta1d);
+ //double S2 = a * sin_d * (T - delta1d + delta2d);
+ }
+ else
+ {
+ result.distance = CT(0);
+ }
+
+ if ( BOOST_GEOMETRY_CONDITION(EnableAzimuth) )
+ {
+ // NOTE: if both cos_latX == 0 then below we'd have 0 * INF
+ // it's a situation when the endpoints are on the poles +-90 deg
+ // in this case the azimuth could either be 0 or +-pi
+ // but above always 0 is returned
+
+ // may also be used to calculate distance21
+ //CT const D = CT(4) * math::sqr(T);
+ CT const E = CT(2) * cos_d;
+ //CT const A = D * E;
+ //CT const B = CT(2) * D;
+ // may also be used to calculate distance21
+ CT const f_sqr = math::sqr(f);
+ CT const f_sqr_per_64 = f_sqr / CT(64);
+
+ CT const F = CT(2)*Y-E*(CT(4)-X);
+ //CT const M = CT(32)*T-(CT(20)*T-A)*X-(B+CT(4))*Y;
+ CT const G = f*T/CT(2) + f_sqr_per_64;
+ CT const tan_d_lambda = tan(d_lambda);
+ CT const Q = -(F*G*tan_d_lambda) / CT(4);
+
+ CT const d_lambda_p = (d_lambda + Q) / CT(2);
+ CT const tan_d_lambda_p = tan(d_lambda_p);
+
+ CT const v = atan2(cos_d_theta_m, sin_theta_m * tan_d_lambda_p);
+ CT const u = atan2(-sin_d_theta_m, cos_theta_m * tan_d_lambda_p);
+
+ CT const pi = math::pi<CT>();
+ CT alpha1 = v + u;
+ if ( alpha1 > pi )
+ {
+ alpha1 -= CT(2) * pi;
+ }
+
+ result.azimuth = alpha1;
+ }
+ else
+ {
+ result.azimuth = CT(0);
+ }
+
+ return result;
+ }
+};
+
+}}} // namespace boost::geometry::detail
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_THOMAS_INVERSE_HPP
diff --git a/boost/geometry/algorithms/detail/throw_on_empty_input.hpp b/boost/geometry/algorithms/detail/throw_on_empty_input.hpp
index 21f5fe40b7..2f82e1a8bd 100644
--- a/boost/geometry/algorithms/detail/throw_on_empty_input.hpp
+++ b/boost/geometry/algorithms/detail/throw_on_empty_input.hpp
@@ -1,8 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -12,7 +17,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_THROW_ON_EMPTY_INPUT_HPP
#include <boost/geometry/core/exception.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
// BSG 2012-02-06: we use this currently only for distance.
// For other scalar results area,length,perimeter it is commented on purpose.
@@ -39,7 +44,7 @@ template <typename Geometry>
inline void throw_on_empty_input(Geometry const& geometry)
{
#if ! defined(BOOST_GEOMETRY_EMPTY_INPUT_NO_THROW)
- if (geometry::num_points(geometry) == 0)
+ if (geometry::is_empty(geometry))
{
throw empty_input_exception();
}
diff --git a/boost/geometry/algorithms/detail/turns/compare_turns.hpp b/boost/geometry/algorithms/detail/turns/compare_turns.hpp
index c29d5863b7..ec383bf103 100644
--- a/boost/geometry/algorithms/detail/turns/compare_turns.hpp
+++ b/boost/geometry/algorithms/detail/turns/compare_turns.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -30,7 +30,7 @@ namespace detail { namespace turns
// seg_id -> fraction -> other_id -> operation
template
<
- typename IdLess = std::less<signed_index_type>,
+ typename IdLess = std::less<signed_size_type>,
int N = 0, int U = 1, int I = 2, int B = 3, int C = 4, int O = 0,
std::size_t OpId = 0
>
@@ -85,10 +85,14 @@ struct less_seg_fraction_other_op
template <typename Turn>
static inline bool use_fraction(Turn const& left, Turn const& right)
{
- return left.operations[OpId].fraction < right.operations[OpId].fraction
- || ( geometry::math::equals(left.operations[OpId].fraction, right.operations[OpId].fraction)
- && use_other_id(left, right)
- );
+ return
+ geometry::math::equals(left.operations[OpId].fraction,
+ right.operations[OpId].fraction)
+ ?
+ use_other_id(left, right)
+ :
+ (left.operations[OpId].fraction < right.operations[OpId].fraction)
+ ;
}
template <typename Turn>
diff --git a/boost/geometry/algorithms/detail/turns/print_turns.hpp b/boost/geometry/algorithms/detail/turns/print_turns.hpp
index 9d4e45c41f..1e9b9df409 100644
--- a/boost/geometry/algorithms/detail/turns/print_turns.hpp
+++ b/boost/geometry/algorithms/detail/turns/print_turns.hpp
@@ -56,7 +56,7 @@ struct turn_printer
<<": seg: " << turn.operations[0].seg_id.source_index
<< ", m: " << turn.operations[0].seg_id.multi_index
<< ", r: " << turn.operations[0].seg_id.ring_index
- << ", s: " << turn.operations[0].seg_id.segment_index << ", ";
+ << ", s: " << turn.operations[0].seg_id.segment_index;
out << ", fr: " << fraction[0];
out << ", col?: " << turn.operations[0].is_collinear;
out << ' ' << geometry::dsv(turn.point) << ' ';
@@ -70,7 +70,7 @@ struct turn_printer
<< ": seg: " << turn.operations[1].seg_id.source_index
<< ", m: " << turn.operations[1].seg_id.multi_index
<< ", r: " << turn.operations[1].seg_id.ring_index
- << ", s: " << turn.operations[1].seg_id.segment_index << ", ";
+ << ", s: " << turn.operations[1].seg_id.segment_index;
out << ", fr: " << fraction[1];
out << ", col?: " << turn.operations[1].is_collinear;
out << ' ' << geometry::dsv(turn.point) << ' ';
diff --git a/boost/geometry/algorithms/detail/vincenty_direct.hpp b/boost/geometry/algorithms/detail/vincenty_direct.hpp
index 775687cfdb..1c47a0f68d 100644
--- a/boost/geometry/algorithms/detail/vincenty_direct.hpp
+++ b/boost/geometry/algorithms/detail/vincenty_direct.hpp
@@ -33,6 +33,18 @@
namespace boost { namespace geometry { namespace detail
{
+template <typename T>
+struct result_direct
+{
+ void set(T const& lo2, T const& la2)
+ {
+ lon2 = lo2;
+ lat2 = la2;
+ }
+ T lon2;
+ T lat2;
+};
+
/*!
\brief The solution of the direct problem of geodesics on latlong coordinates, after Vincenty, 1975
\author See
@@ -45,45 +57,49 @@ namespace boost { namespace geometry { namespace detail
*/
template <typename CT>
-class vincenty_direct
+struct vincenty_direct
{
+ typedef result_direct<CT> result_type;
+
public:
template <typename T, typename Dist, typename Azi, typename Spheroid>
- vincenty_direct(T const& lo1,
- T const& la1,
- Dist const& distance,
- Azi const& azimuth12,
- Spheroid const& spheroid)
- : lon1(lo1)
- , lat1(la1)
- , is_distance_zero(false)
+ static inline result_type apply(T const& lo1,
+ T const& la1,
+ Dist const& distance,
+ Azi const& azimuth12,
+ Spheroid const& spheroid)
{
+ result_type result;
+
+ CT const lon1 = lo1;
+ CT const lat1 = la1;
+
if ( math::equals(distance, Dist(0)) || distance < Dist(0) )
{
- is_distance_zero = true;
- return;
+ result.set(lon1, lat1);
+ return result;
}
CT const radius_a = CT(get_radius<0>(spheroid));
CT const radius_b = CT(get_radius<2>(spheroid));
- flattening = geometry::detail::flattening<CT>(spheroid);
+ CT const flattening = geometry::detail::flattening<CT>(spheroid);
- sin_azimuth12 = sin(azimuth12);
- cos_azimuth12 = cos(azimuth12);
+ CT const sin_azimuth12 = sin(azimuth12);
+ CT const cos_azimuth12 = cos(azimuth12);
// U: reduced latitude, defined by tan U = (1-f) tan phi
- one_min_f = CT(1) - flattening;
+ CT const one_min_f = CT(1) - flattening;
CT const tan_U1 = one_min_f * tan(lat1);
CT const sigma1 = atan2(tan_U1, cos_azimuth12); // (1)
// may be calculated from tan using 1 sqrt()
CT const U1 = atan(tan_U1);
- sin_U1 = sin(U1);
- cos_U1 = cos(U1);
+ CT const sin_U1 = sin(U1);
+ CT const cos_U1 = cos(U1);
- sin_alpha = cos_U1 * sin_azimuth12; // (2)
- sin_alpha_sqr = math::sqr(sin_alpha);
- cos_alpha_sqr = CT(1) - sin_alpha_sqr;
+ CT const sin_alpha = cos_U1 * sin_azimuth12; // (2)
+ CT const sin_alpha_sqr = math::sqr(sin_alpha);
+ CT const cos_alpha_sqr = CT(1) - sin_alpha_sqr;
CT const b_sqr = radius_b * radius_b;
CT const u_sqr = cos_alpha_sqr * (radius_a * radius_a - b_sqr) / b_sqr;
@@ -91,9 +107,13 @@ public:
CT const B = (u_sqr/CT(1024))*(CT(256) + u_sqr*(CT(-128) + u_sqr*(CT(74) - u_sqr*CT(47)))); // (4)
CT s_div_bA = distance / (radius_b * A);
- sigma = s_div_bA; // (7)
+ CT sigma = s_div_bA; // (7)
CT previous_sigma;
+ CT sin_sigma;
+ CT cos_sigma;
+ CT cos_2sigma_m;
+ CT cos_2sigma_m_sqr;
int counter = 0; // robustness
@@ -120,35 +140,27 @@ public:
} while ( geometry::math::abs(previous_sigma - sigma) > CT(1e-12)
//&& geometry::math::abs(sigma) < pi
&& counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness
- }
- inline CT lat2() const
- {
- if ( is_distance_zero )
{
- return lat1;
+ result.lat2
+ = atan2( sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_azimuth12,
+ one_min_f * math::sqrt(sin_alpha_sqr + math::sqr(sin_U1 * sin_sigma - cos_U1 * cos_sigma * cos_azimuth12))); // (8)
}
- return atan2( sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_azimuth12,
- one_min_f * math::sqrt(sin_alpha_sqr + math::sqr(sin_U1 * sin_sigma - cos_U1 * cos_sigma * cos_azimuth12))); // (8)
- }
-
- inline CT lon2() const
- {
- if ( is_distance_zero )
{
- return lon1;
- }
+ CT const lambda = atan2( sin_sigma * sin_azimuth12,
+ cos_U1 * cos_sigma - sin_U1 * sin_sigma * cos_azimuth12); // (9)
+ CT const C = (flattening/CT(16)) * cos_alpha_sqr * ( CT(4) + flattening * ( CT(4) - CT(3) * cos_alpha_sqr ) ); // (10)
+ CT const L = lambda - (CT(1) - C) * flattening * sin_alpha
+ * ( sigma + C * sin_sigma * ( cos_2sigma_m + C * cos_sigma * ( CT(-1) + CT(2) * cos_2sigma_m_sqr ) ) ); // (11)
- CT const lambda = atan2( sin_sigma * sin_azimuth12,
- cos_U1 * cos_sigma - sin_U1 * sin_sigma * cos_azimuth12); // (9)
- CT const C = (flattening/CT(16)) * cos_alpha_sqr * ( CT(4) + flattening * ( CT(4) - CT(3) * cos_alpha_sqr ) ); // (10)
- CT const L = lambda - (CT(1) - C) * flattening * sin_alpha
- * ( sigma + C * sin_sigma * ( cos_2sigma_m + C * cos_sigma * ( CT(-1) + CT(2) * cos_2sigma_m_sqr ) ) ); // (11)
+ result.lon2 = lon1 + L;
+ }
- return lon1 + L;
+ return result;
}
+ /*
inline CT azimuth21() const
{
// NOTE: signs of X and Y are different than in the original paper
@@ -156,32 +168,7 @@ public:
CT(0) :
atan2(-sin_alpha, sin_U1 * sin_sigma - cos_U1 * cos_sigma * cos_azimuth12); // (12)
}
-
-private:
- CT sigma;
- CT sin_sigma;
- CT cos_sigma;
-
- CT cos_2sigma_m;
- CT cos_2sigma_m_sqr;
-
- CT sin_alpha;
- CT sin_alpha_sqr;
- CT cos_alpha_sqr;
-
- CT sin_azimuth12;
- CT cos_azimuth12;
-
- CT sin_U1;
- CT cos_U1;
-
- CT flattening;
- CT one_min_f;
-
- CT const lon1;
- CT const lat1;
-
- bool is_distance_zero;
+ */
};
}}} // namespace boost::geometry::detail
diff --git a/boost/geometry/algorithms/detail/vincenty_inverse.hpp b/boost/geometry/algorithms/detail/vincenty_inverse.hpp
index 861452af00..fe05e95932 100644
--- a/boost/geometry/algorithms/detail/vincenty_inverse.hpp
+++ b/boost/geometry/algorithms/detail/vincenty_inverse.hpp
@@ -20,9 +20,11 @@
#include <boost/geometry/core/radius.hpp>
#include <boost/geometry/core/srs.hpp>
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/algorithms/detail/flattening.hpp>
+#include <boost/geometry/algorithms/detail/result_inverse.hpp>
#ifndef BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS
@@ -44,22 +46,25 @@ namespace boost { namespace geometry { namespace detail
- http://futureboy.homeip.net/fsp/colorize.fsp?fileName=navigation.frink
*/
-template <typename CT>
-class vincenty_inverse
+template <typename CT, bool EnableDistance, bool EnableAzimuth>
+struct vincenty_inverse
{
+ typedef result_inverse<CT> result_type;
+
public:
template <typename T1, typename T2, typename Spheroid>
- vincenty_inverse(T1 const& lon1,
- T1 const& lat1,
- T2 const& lon2,
- T2 const& lat2,
- Spheroid const& spheroid)
- : is_result_zero(false)
+ static inline result_type apply(T1 const& lon1,
+ T1 const& lat1,
+ T2 const& lon2,
+ T2 const& lat2,
+ Spheroid const& spheroid)
{
+ result_type result;
+
if (math::equals(lat1, lat2) && math::equals(lon1, lon2))
{
- is_result_zero = true;
- return;
+ result.set(CT(0), CT(0));
+ return result;
}
CT const c1 = 1;
@@ -79,8 +84,8 @@ public:
if (L < -pi) L += two_pi;
if (L > pi) L -= two_pi;
- radius_a = CT(get_radius<0>(spheroid));
- radius_b = CT(get_radius<2>(spheroid));
+ CT const radius_a = CT(get_radius<0>(spheroid));
+ CT const radius_b = CT(get_radius<2>(spheroid));
CT const flattening = geometry::detail::flattening<CT>(spheroid);
// U: reduced latitude, defined by tan U = (1-f) tan phi
@@ -92,11 +97,11 @@ public:
CT const temp_den_U1 = math::sqrt(c1 + math::sqr(tan_U1));
CT const temp_den_U2 = math::sqrt(c1 + math::sqr(tan_U2));
// cos = 1 / sqrt(1 + tan^2)
- cos_U1 = c1 / temp_den_U1;
- cos_U2 = c1 / temp_den_U2;
+ CT const cos_U1 = c1 / temp_den_U1;
+ CT const cos_U2 = c1 / temp_den_U2;
// sin = tan / sqrt(1 + tan^2)
- sin_U1 = tan_U1 / temp_den_U1;
- sin_U2 = tan_U2 / temp_den_U2;
+ CT const sin_U1 = tan_U1 / temp_den_U1;
+ CT const sin_U2 = tan_U2 / temp_den_U2;
// calculate sin U and cos U directly
//CT const U1 = atan(tan_U1);
@@ -107,6 +112,13 @@ public:
//sin_U2 = tan_U2 * cos_U2; // sin(U2);
CT previous_lambda;
+ CT sin_lambda;
+ CT cos_lambda;
+ CT sin_sigma;
+ CT sin_alpha;
+ CT cos2_alpha;
+ CT cos2_sigma_m;
+ CT sigma;
int counter = 0; // robustness
@@ -131,85 +143,59 @@ public:
} while ( geometry::math::abs(previous_lambda - lambda) > c_e_12
&& geometry::math::abs(lambda) < pi
&& counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness
- }
-
- inline CT distance() const
- {
- if ( is_result_zero )
+
+ if ( BOOST_GEOMETRY_CONDITION(EnableDistance) )
{
- return CT(0);
+ // Oops getting hard here
+ // (again, problem is that ttmath cannot divide by doubles, which is OK)
+ CT const c1 = 1;
+ CT const c2 = 2;
+ CT const c3 = 3;
+ CT const c4 = 4;
+ CT const c6 = 6;
+ CT const c47 = 47;
+ CT const c74 = 74;
+ CT const c128 = 128;
+ CT const c256 = 256;
+ CT const c175 = 175;
+ CT const c320 = 320;
+ CT const c768 = 768;
+ CT const c1024 = 1024;
+ CT const c4096 = 4096;
+ CT const c16384 = 16384;
+
+ //CT sqr_u = cos2_alpha * (math::sqr(radius_a) - math::sqr(radius_b)) / math::sqr(radius_b); // above (1)
+ CT sqr_u = cos2_alpha * ( math::sqr(radius_a / radius_b) - c1 ); // above (1)
+
+ CT A = c1 + sqr_u/c16384 * (c4096 + sqr_u * (-c768 + sqr_u * (c320 - c175 * sqr_u))); // (3)
+ CT B = sqr_u/c1024 * (c256 + sqr_u * ( -c128 + sqr_u * (c74 - c47 * sqr_u))); // (4)
+ CT delta_sigma = B * sin_sigma * ( cos2_sigma_m + (B/c4) * (cos(sigma)* (-c1 + c2 * cos2_sigma_m)
+ - (B/c6) * cos2_sigma_m * (-c3 + c4 * math::sqr(sin_sigma)) * (-c3 + c4 * cos2_sigma_m))); // (6)
+
+ result.distance = radius_b * A * (sigma - delta_sigma); // (19)
+ }
+ else
+ {
+ result.distance = CT(0);
+ }
+
+ if ( BOOST_GEOMETRY_CONDITION(EnableAzimuth) )
+ {
+ result.azimuth = atan2(cos_U2 * sin_lambda, cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda); // (20)
+ }
+ else
+ {
+ result.azimuth = CT(0);
}
- // Oops getting hard here
- // (again, problem is that ttmath cannot divide by doubles, which is OK)
- CT const c1 = 1;
- CT const c2 = 2;
- CT const c3 = 3;
- CT const c4 = 4;
- CT const c6 = 6;
- CT const c47 = 47;
- CT const c74 = 74;
- CT const c128 = 128;
- CT const c256 = 256;
- CT const c175 = 175;
- CT const c320 = 320;
- CT const c768 = 768;
- CT const c1024 = 1024;
- CT const c4096 = 4096;
- CT const c16384 = 16384;
-
- //CT sqr_u = cos2_alpha * (math::sqr(radius_a) - math::sqr(radius_b)) / math::sqr(radius_b); // above (1)
- CT sqr_u = cos2_alpha * ( math::sqr(radius_a / radius_b) - c1 ); // above (1)
-
- CT A = c1 + sqr_u/c16384 * (c4096 + sqr_u * (-c768 + sqr_u * (c320 - c175 * sqr_u))); // (3)
- CT B = sqr_u/c1024 * (c256 + sqr_u * ( -c128 + sqr_u * (c74 - c47 * sqr_u))); // (4)
- CT delta_sigma = B * sin_sigma * ( cos2_sigma_m + (B/c4) * (cos(sigma)* (-c1 + c2 * cos2_sigma_m)
- - (B/c6) * cos2_sigma_m * (-c3 + c4 * math::sqr(sin_sigma)) * (-c3 + c4 * cos2_sigma_m))); // (6)
-
- return radius_b * A * (sigma - delta_sigma); // (19)
- }
-
- inline CT azimuth12() const
- {
- return is_result_zero ?
- CT(0) :
- atan2(cos_U2 * sin_lambda, cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda); // (20)
- }
-
- inline CT azimuth21() const
- {
- // NOTE: signs of X and Y are different than in the original paper
- return is_result_zero ?
- CT(0) :
- atan2(-cos_U1 * sin_lambda, sin_U1 * cos_U2 - cos_U1 * sin_U2 * cos_lambda); // (21)
+ return result;
}
-private:
- // alpha: azimuth of the geodesic at the equator
- CT cos2_alpha;
- CT sin_alpha;
-
- // sigma: angular distance p1,p2 on the sphere
- // sigma1: angular distance on the sphere from the equator to p1
- // sigma_m: angular distance on the sphere from the equator to the midpoint of the line
- CT sigma;
- CT sin_sigma;
- CT cos2_sigma_m;
-
- CT sin_lambda;
- CT cos_lambda;
-
- // set only once
- CT cos_U1;
- CT cos_U2;
- CT sin_U1;
- CT sin_U2;
-
- // set only once
- CT radius_a;
- CT radius_b;
-
- bool is_result_zero;
+// inline CT azimuth21() const
+// {
+// // NOTE: signs of X and Y are different than in the original paper
+// atan2(-cos_U1 * sin_lambda, sin_U1 * cos_U2 - cos_U1 * sin_U2 * cos_lambda); // (21)
+// }
};
}}} // namespace boost::geometry::detail
diff --git a/boost/geometry/algorithms/detail/within/point_in_geometry.hpp b/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
index e7486f0e45..68e74a8c5c 100644
--- a/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
+++ b/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
@@ -20,13 +20,15 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP
-#include <boost/assert.hpp>
+
#include <boost/core/ignore_unused.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_reference.hpp>
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
@@ -53,7 +55,7 @@ inline int check_result_type(int result)
template <typename T>
inline T check_result_type(T result)
{
- BOOST_ASSERT(false);
+ BOOST_GEOMETRY_ASSERT(false);
return result;
}
@@ -291,7 +293,7 @@ struct point_in_geometry<Geometry, multi_point_tag>
{
int pip = point_in_geometry<point_type>::apply(point, *it, strategy);
- //BOOST_ASSERT(pip != 0);
+ //BOOST_GEOMETRY_ASSERT(pip != 0);
if ( pip > 0 ) // inside
return 1;
}
diff --git a/boost/geometry/algorithms/dispatch/envelope.hpp b/boost/geometry/algorithms/dispatch/envelope.hpp
new file mode 100644
index 0000000000..bb8a99f5a8
--- /dev/null
+++ b/boost/geometry/algorithms/dispatch/envelope.hpp
@@ -0,0 +1,49 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DISPATCH_ENVELOPE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DISPATCH_ENVELOPE_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tag.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Geometry,
+ typename Tag = typename tag<Geometry>::type,
+ typename CS_Tag = typename cs_tag<Geometry>::type
+>
+struct envelope : not_implemented<Tag>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DISPATCH_ENVELOPE_HPP
diff --git a/boost/geometry/algorithms/dispatch/expand.hpp b/boost/geometry/algorithms/dispatch/expand.hpp
new file mode 100644
index 0000000000..2c23d6a1ce
--- /dev/null
+++ b/boost/geometry/algorithms/dispatch/expand.hpp
@@ -0,0 +1,58 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under the 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_GEOMETRY_ALGORITHMS_DISPATCH_EXPAND_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DISPATCH_EXPAND_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tag.hpp>
+
+#include <boost/geometry/strategies/compare.hpp>
+#include <boost/geometry/policies/compare.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename GeometryOut, typename Geometry,
+ typename StrategyLess = strategy::compare::default_strategy,
+ typename StrategyGreater = strategy::compare::default_strategy,
+ typename TagOut = typename tag<GeometryOut>::type,
+ typename Tag = typename tag<Geometry>::type,
+ typename CSTagOut = typename cs_tag<GeometryOut>::type,
+ typename CSTag = typename cs_tag<Geometry>::type
+>
+struct expand : not_implemented<TagOut, Tag>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DISPATCH_EXPAND_HPP
diff --git a/boost/geometry/algorithms/envelope.hpp b/boost/geometry/algorithms/envelope.hpp
index bd1ea9cb7a..00981224b2 100644
--- a/boost/geometry/algorithms/envelope.hpp
+++ b/boost/geometry/algorithms/envelope.hpp
@@ -1,295 +1,25 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
-// Use, modification and distribution is subject to the Boost Software License,
-// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// Distributed under the 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_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
-#include <vector>
-
-#include <boost/numeric/conversion/cast.hpp>
-#include <boost/range.hpp>
-
-#include <boost/variant/apply_visitor.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/variant/variant_fwd.hpp>
-
-#include <boost/geometry/algorithms/assign.hpp>
-#include <boost/geometry/algorithms/expand.hpp>
-#include <boost/geometry/algorithms/not_implemented.hpp>
-#include <boost/geometry/core/cs.hpp>
-#include <boost/geometry/core/exterior_ring.hpp>
-#include <boost/geometry/core/point_type.hpp>
-#include <boost/geometry/core/tags.hpp>
-
-#include <boost/geometry/geometries/concepts/check.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace envelope
-{
-
-
-/// Calculate envelope of an 2D or 3D segment
-struct envelope_expand_one
-{
- template<typename Geometry, typename Box>
- static inline void apply(Geometry const& geometry, Box& mbr)
- {
- assign_inverse(mbr);
- geometry::expand(mbr, geometry);
- }
-};
-
-
-/// Iterate through range (also used in multi*)
-template<typename Range, typename Box>
-inline void envelope_range_additional(Range const& range, Box& mbr)
-{
- typedef typename boost::range_iterator<Range const>::type iterator_type;
-
- for (iterator_type it = boost::begin(range);
- it != boost::end(range);
- ++it)
- {
- geometry::expand(mbr, *it);
- }
-}
-
-
-
-/// Generic range dispatching struct
-struct envelope_range
-{
- /// Calculate envelope of range using a strategy
- template <typename Range, typename Box>
- static inline void apply(Range const& range, Box& mbr)
- {
- assign_inverse(mbr);
- envelope_range_additional(range, mbr);
- }
-};
-
-
-struct envelope_multi_linestring
-{
- template<typename MultiLinestring, typename Box>
- static inline void apply(MultiLinestring const& mp, Box& mbr)
- {
- assign_inverse(mbr);
- for (typename boost::range_iterator<MultiLinestring const>::type
- it = mp.begin();
- it != mp.end();
- ++it)
- {
- envelope_range_additional(*it, mbr);
- }
- }
-};
-
-
-// version for multi_polygon: outer ring's of all polygons
-struct envelope_multi_polygon
-{
- template<typename MultiPolygon, typename Box>
- static inline void apply(MultiPolygon const& mp, Box& mbr)
- {
- assign_inverse(mbr);
- for (typename boost::range_const_iterator<MultiPolygon>::type
- it = mp.begin();
- it != mp.end();
- ++it)
- {
- envelope_range_additional(exterior_ring(*it), mbr);
- }
- }
-};
-
-
-}} // namespace detail::envelope
-#endif // DOXYGEN_NO_DETAIL
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-
-template
-<
- typename Geometry,
- typename Tag = typename tag<Geometry>::type
->
-struct envelope: not_implemented<Tag>
-{};
-
-
-template <typename Point>
-struct envelope<Point, point_tag>
- : detail::envelope::envelope_expand_one
-{};
-
-
-template <typename Box>
-struct envelope<Box, box_tag>
- : detail::envelope::envelope_expand_one
-{};
-
-
-template <typename Segment>
-struct envelope<Segment, segment_tag>
- : detail::envelope::envelope_expand_one
-{};
-
-
-template <typename Linestring>
-struct envelope<Linestring, linestring_tag>
- : detail::envelope::envelope_range
-{};
-
-
-template <typename Ring>
-struct envelope<Ring, ring_tag>
- : detail::envelope::envelope_range
-{};
-
-
-template <typename Polygon>
-struct envelope<Polygon, polygon_tag>
- : detail::envelope::envelope_range
-{
- template <typename Box>
- static inline void apply(Polygon const& poly, Box& mbr)
- {
- // For polygon, inspecting outer ring is sufficient
- detail::envelope::envelope_range::apply(exterior_ring(poly), mbr);
- }
-
-};
-
-
-template <typename Multi>
-struct envelope<Multi, multi_point_tag>
- : detail::envelope::envelope_range
-{};
-
-
-template <typename Multi>
-struct envelope<Multi, multi_linestring_tag>
- : detail::envelope::envelope_multi_linestring
-{};
-
-
-template <typename Multi>
-struct envelope<Multi, multi_polygon_tag>
- : detail::envelope::envelope_multi_polygon
-{};
-
-
-} // namespace dispatch
-#endif
-
-
-namespace resolve_variant {
-
-template <typename Geometry>
-struct envelope
-{
- template <typename Box>
- static inline void apply(Geometry const& geometry, Box& box)
- {
- concept::check<Geometry const>();
- concept::check<Box>();
-
- dispatch::envelope<Geometry>::apply(geometry, box);
- }
-};
-
-template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
-struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
-{
- template <typename Box>
- struct visitor: boost::static_visitor<void>
- {
- Box& m_box;
-
- visitor(Box& box): m_box(box) {}
-
- template <typename Geometry>
- void operator()(Geometry const& geometry) const
- {
- envelope<Geometry>::apply(geometry, m_box);
- }
- };
-
- template <typename Box>
- static inline void
- apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
- Box& box)
- {
- boost::apply_visitor(visitor<Box>(box), geometry);
- }
-};
-
-} // namespace resolve_variant
-
-
-/*!
-\brief \brief_calc{envelope}
-\ingroup envelope
-\details \details_calc{envelope,\det_envelope}.
-\tparam Geometry \tparam_geometry
-\tparam Box \tparam_box
-\param geometry \param_geometry
-\param mbr \param_box \param_set{envelope}
-
-\qbk{[include reference/algorithms/envelope.qbk]}
-\qbk{
-[heading Example]
-[envelope] [envelope_output]
-}
-*/
-template<typename Geometry, typename Box>
-inline void envelope(Geometry const& geometry, Box& mbr)
-{
- resolve_variant::envelope<Geometry>::apply(geometry, mbr);
-}
-
-
-/*!
-\brief \brief_calc{envelope}
-\ingroup envelope
-\details \details_calc{return_envelope,\det_envelope}. \details_return{envelope}
-\tparam Box \tparam_box
-\tparam Geometry \tparam_geometry
-\param geometry \param_geometry
-\return \return_calc{envelope}
-
-\qbk{[include reference/algorithms/envelope.qbk]}
-\qbk{
-[heading Example]
-[return_envelope] [return_envelope_output]
-}
-*/
-template<typename Box, typename Geometry>
-inline Box return_envelope(Geometry const& geometry)
-{
- Box mbr;
- resolve_variant::envelope<Geometry>::apply(geometry, mbr);
- return mbr;
-}
-
-}} // namespace boost::geometry
+#include <boost/geometry/algorithms/detail/envelope/interface.hpp>
+#include <boost/geometry/algorithms/detail/envelope/implementation.hpp>
#endif // BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
diff --git a/boost/geometry/algorithms/equals.hpp b/boost/geometry/algorithms/equals.hpp
index 7c709c808d..0f0bdde584 100644
--- a/boost/geometry/algorithms/equals.hpp
+++ b/boost/geometry/algorithms/equals.hpp
@@ -51,7 +51,8 @@
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/geometry/algorithms/detail/equals/collect_vectors.hpp>
-#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
#include <boost/geometry/views/detail/indexed_point_view.hpp>
@@ -181,9 +182,9 @@ struct equals_by_collection
template<typename Geometry1, typename Geometry2>
struct equals_by_relate
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_equals_type,
+ detail::de9im::static_mask_equals_type,
Geometry1,
Geometry2
>
@@ -371,7 +372,7 @@ struct equals<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Geometry2 const& geometry2
)
{
- return apply_visitor(visitor(geometry2), geometry1);
+ return boost::apply_visitor(visitor(geometry2), geometry1);
}
};
@@ -400,7 +401,7 @@ struct equals<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2
)
{
- return apply_visitor(visitor(geometry1), geometry2);
+ return boost::apply_visitor(visitor(geometry1), geometry2);
}
};
@@ -430,7 +431,7 @@ struct equals<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2
)
{
- return apply_visitor(visitor(), geometry1, geometry2);
+ return boost::apply_visitor(visitor(), geometry1, geometry2);
}
};
diff --git a/boost/geometry/algorithms/expand.hpp b/boost/geometry/algorithms/expand.hpp
index 9dc0a48e06..f41df53801 100644
--- a/boost/geometry/algorithms/expand.hpp
+++ b/boost/geometry/algorithms/expand.hpp
@@ -1,348 +1,26 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
-// Use, modification and distribution is subject to the Boost Software License,
-// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// Distributed under the 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_GEOMETRY_ALGORITHMS_EXPAND_HPP
#define BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
-
-#include <cstddef>
-
-#include <boost/numeric/conversion/cast.hpp>
-
-#include <boost/variant/apply_visitor.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/variant/variant_fwd.hpp>
-
-#include <boost/geometry/algorithms/not_implemented.hpp>
-#include <boost/geometry/core/coordinate_dimension.hpp>
-#include <boost/geometry/geometries/concepts/check.hpp>
-
-#include <boost/geometry/util/select_coordinate_type.hpp>
-
-#include <boost/geometry/strategies/compare.hpp>
-#include <boost/geometry/policies/compare.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace expand
-{
-
-
-template
-<
- typename StrategyLess, typename StrategyGreater,
- std::size_t Dimension, std::size_t DimensionCount
->
-struct point_loop
-{
- template <typename Box, typename Point>
- static inline void apply(Box& box, Point const& source)
- {
- typedef typename strategy::compare::detail::select_strategy
- <
- StrategyLess, 1, Point, Dimension
- >::type less_type;
-
- typedef typename strategy::compare::detail::select_strategy
- <
- StrategyGreater, -1, Point, Dimension
- >::type greater_type;
-
- typedef typename select_coordinate_type<Point, Box>::type coordinate_type;
-
- less_type less;
- greater_type greater;
-
- coordinate_type const coord = get<Dimension>(source);
-
- if (less(coord, get<min_corner, Dimension>(box)))
- {
- set<min_corner, Dimension>(box, coord);
- }
-
- if (greater(coord, get<max_corner, Dimension>(box)))
- {
- set<max_corner, Dimension>(box, coord);
- }
-
- point_loop
- <
- StrategyLess, StrategyGreater,
- Dimension + 1, DimensionCount
- >::apply(box, source);
- }
-};
-
-
-template
-<
- typename StrategyLess, typename StrategyGreater,
- std::size_t DimensionCount
->
-struct point_loop
- <
- StrategyLess, StrategyGreater,
- DimensionCount, DimensionCount
- >
-{
- template <typename Box, typename Point>
- static inline void apply(Box&, Point const&) {}
-};
-
-
-template
-<
- typename StrategyLess, typename StrategyGreater,
- std::size_t Index,
- std::size_t Dimension, std::size_t DimensionCount
->
-struct indexed_loop
-{
- template <typename Box, typename Geometry>
- static inline void apply(Box& box, Geometry const& source)
- {
- typedef typename strategy::compare::detail::select_strategy
- <
- StrategyLess, 1, Box, Dimension
- >::type less_type;
-
- typedef typename strategy::compare::detail::select_strategy
- <
- StrategyGreater, -1, Box, Dimension
- >::type greater_type;
-
- typedef typename select_coordinate_type
- <
- Box,
- Geometry
- >::type coordinate_type;
-
- less_type less;
- greater_type greater;
-
- coordinate_type const coord = get<Index, Dimension>(source);
-
- if (less(coord, get<min_corner, Dimension>(box)))
- {
- set<min_corner, Dimension>(box, coord);
- }
-
- if (greater(coord, get<max_corner, Dimension>(box)))
- {
- set<max_corner, Dimension>(box, coord);
- }
-
- indexed_loop
- <
- StrategyLess, StrategyGreater,
- Index, Dimension + 1, DimensionCount
- >::apply(box, source);
- }
-};
-
-
-template
-<
- typename StrategyLess, typename StrategyGreater,
- std::size_t Index, std::size_t DimensionCount
->
-struct indexed_loop
- <
- StrategyLess, StrategyGreater,
- Index, DimensionCount, DimensionCount
- >
-{
- template <typename Box, typename Geometry>
- static inline void apply(Box&, Geometry const&) {}
-};
-
-
-
-// Changes a box such that the other box is also contained by the box
-template
-<
- typename StrategyLess, typename StrategyGreater
->
-struct expand_indexed
-{
- template <typename Box, typename Geometry>
- static inline void apply(Box& box, Geometry const& geometry)
- {
- indexed_loop
- <
- StrategyLess, StrategyGreater,
- 0, 0, dimension<Geometry>::type::value
- >::apply(box, geometry);
-
- indexed_loop
- <
- StrategyLess, StrategyGreater,
- 1, 0, dimension<Geometry>::type::value
- >::apply(box, geometry);
- }
-};
-
-}} // namespace detail::expand
-#endif // DOXYGEN_NO_DETAIL
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-template
-<
- typename GeometryOut, typename Geometry,
- typename StrategyLess = strategy::compare::default_strategy,
- typename StrategyGreater = strategy::compare::default_strategy,
- typename TagOut = typename tag<GeometryOut>::type,
- typename Tag = typename tag<Geometry>::type
->
-struct expand: not_implemented<TagOut, Tag>
-{};
-
-
-// Box + point -> new box containing also point
-template
-<
- typename BoxOut, typename Point,
- typename StrategyLess, typename StrategyGreater
->
-struct expand<BoxOut, Point, StrategyLess, StrategyGreater, box_tag, point_tag>
- : detail::expand::point_loop
- <
- StrategyLess, StrategyGreater,
- 0, dimension<Point>::type::value
- >
-{};
-
-
-// Box + box -> new box containing two input boxes
-template
-<
- typename BoxOut, typename BoxIn,
- typename StrategyLess, typename StrategyGreater
->
-struct expand<BoxOut, BoxIn, StrategyLess, StrategyGreater, box_tag, box_tag>
- : detail::expand::expand_indexed<StrategyLess, StrategyGreater>
-{};
-
-template
-<
- typename Box, typename Segment,
- typename StrategyLess, typename StrategyGreater
->
-struct expand<Box, Segment, StrategyLess, StrategyGreater, box_tag, segment_tag>
- : detail::expand::expand_indexed<StrategyLess, StrategyGreater>
-{};
-
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-namespace resolve_variant {
-
-template <typename Geometry>
-struct expand
-{
- template <typename Box>
- static inline void apply(Box& box, Geometry const& geometry)
- {
- concept::check<Box>();
- concept::check<Geometry const>();
- concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
-
- dispatch::expand<Box, Geometry>::apply(box, geometry);
- }
-};
-
-template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
-struct expand<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
-{
- template <typename Box>
- struct visitor: boost::static_visitor<void>
- {
- Box& m_box;
-
- visitor(Box& box) : m_box(box) {}
-
- template <typename Geometry>
- void operator()(Geometry const& geometry) const
- {
- return expand<Geometry>::apply(m_box, geometry);
- }
- };
-
- template <class Box>
- static inline void
- apply(Box& box,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
- {
- return boost::apply_visitor(visitor<Box>(box), geometry);
- }
-};
-
-} // namespace resolve_variant
-
-
-/***
-*!
-\brief Expands a box using the extend (envelope) of another geometry (box, point)
-\ingroup expand
-\tparam Box type of the box
-\tparam Geometry of second geometry, to be expanded with the box
-\param box box to expand another geometry with, might be changed
-\param geometry other geometry
-\param strategy_less
-\param strategy_greater
-\note Strategy is currently ignored
- *
-template
-<
- typename Box, typename Geometry,
- typename StrategyLess, typename StrategyGreater
->
-inline void expand(Box& box, Geometry const& geometry,
- StrategyLess const& strategy_less,
- StrategyGreater const& strategy_greater)
-{
- concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
-
- dispatch::expand<Box, Geometry>::apply(box, geometry);
-}
-***/
-
-
-/*!
-\brief Expands a box using the bounding box (envelope) of another geometry (box, point)
-\ingroup expand
-\tparam Box type of the box
-\tparam Geometry \tparam_geometry
-\param box box to be expanded using another geometry, mutable
-\param geometry \param_geometry geometry which envelope (bounding box) will be added to the box
-
-\qbk{[include reference/algorithms/expand.qbk]}
- */
-template <typename Box, typename Geometry>
-inline void expand(Box& box, Geometry const& geometry)
-{
- resolve_variant::expand<Geometry>::apply(box, geometry);
-}
-
-}} // namespace boost::geometry
+#include <boost/geometry/algorithms/detail/expand/interface.hpp>
+#include <boost/geometry/algorithms/detail/expand/implementation.hpp>
#endif // BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
diff --git a/boost/geometry/algorithms/is_convex.hpp b/boost/geometry/algorithms/is_convex.hpp
new file mode 100644
index 0000000000..8feb48db6a
--- /dev/null
+++ b/boost/geometry/algorithms/is_convex.hpp
@@ -0,0 +1,160 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// 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_GEOMETRY_ALGORITHMS_IS_CONVEX_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_IS_CONVEX_HPP
+
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+#include <boost/geometry/iterators/ever_circling_iterator.hpp>
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
+#include <boost/geometry/views/detail/normalized_view.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace is_convex
+{
+
+struct ring_is_convex
+{
+ template <typename Ring>
+ static inline bool apply(Ring const& ring)
+ {
+ typedef typename geometry::point_type<Ring>::type point_type;
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<point_type>::type
+ >::type side_strategy_type;
+
+ std::size_t n = boost::size(ring);
+ if (boost::size(ring) < core_detail::closure::minimum_ring_size
+ <
+ geometry::closure<Ring>::value
+ >::value)
+ {
+ // (Too) small rings are considered as non-concave, is convex
+ return true;
+ }
+
+ // Walk in clockwise direction, consider ring as closed
+ // (though closure is not important in this algorithm - any dupped
+ // point is skipped)
+ typedef detail::normalized_view<Ring const> view_type;
+ view_type view(ring);
+
+ typedef geometry::ever_circling_range_iterator<view_type const> it_type;
+ it_type previous(view);
+ it_type current(view);
+ current++;
+
+ std::size_t index = 1;
+ while (equals::equals_point_point(*current, *previous) && index < n)
+ {
+ current++;
+ index++;
+ }
+
+ if (index == n)
+ {
+ // All points are apparently equal
+ return true;
+ }
+
+ it_type next = current;
+ next++;
+ while (equals::equals_point_point(*current, *next))
+ {
+ next++;
+ }
+
+ // We have now three different points on the ring
+ // Walk through all points, use a counter because of the ever-circling
+ // iterator
+ for (std::size_t i = 0; i < n; i++)
+ {
+ int const side = side_strategy_type::apply(*previous, *current, *next);
+ if (side == 1)
+ {
+ // Next is on the left side of clockwise ring:
+ // the piece is not convex
+ return false;
+ }
+
+ previous = current;
+ current = next;
+
+ // Advance next to next different point
+ // (because there are non-equal points, this loop is not infinite)
+ next++;
+ while (equals::equals_point_point(*current, *next))
+ {
+ next++;
+ }
+ }
+ return true;
+ }
+};
+
+
+}} // namespace detail::is_convex
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Geometry,
+ typename Tag = typename tag<Geometry>::type
+>
+struct is_convex : not_implemented<Tag>
+{};
+
+template <typename Box>
+struct is_convex<Box, box_tag>
+{
+ static inline bool apply(Box const& )
+ {
+ // Any box is convex (TODO: consider spherical boxes)
+ return true;
+ }
+};
+
+template <typename Box>
+struct is_convex<Box, ring_tag> : detail::is_convex::ring_is_convex
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+// TODO: variants
+
+// TODO: documentation / qbk
+template<typename Geometry>
+inline bool is_convex(Geometry const& geometry)
+{
+ return dispatch::is_convex<Geometry>::apply(geometry);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_IS_CONVEX_HPP
diff --git a/boost/geometry/algorithms/is_empty.hpp b/boost/geometry/algorithms/is_empty.hpp
new file mode 100644
index 0000000000..02c295eaba
--- /dev/null
+++ b/boost/geometry/algorithms/is_empty.hpp
@@ -0,0 +1,207 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_IS_EMPTY_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_IS_EMPTY_HPP
+
+#include <boost/range.hpp>
+
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace is_empty
+{
+
+struct always_not_empty
+{
+ template <typename Geometry>
+ static inline bool apply(Geometry const&)
+ {
+ return false;
+ }
+};
+
+struct range_is_empty
+{
+ template <typename Range>
+ static inline bool apply(Range const& range)
+ {
+ return boost::empty(range);
+ }
+};
+
+class polygon_is_empty
+{
+ template <typename InteriorRings>
+ static inline bool check_interior_rings(InteriorRings const& interior_rings)
+ {
+ return check_iterator_range
+ <
+ range_is_empty, true // allow empty range
+ >::apply(boost::begin(interior_rings), boost::end(interior_rings));
+ }
+
+public:
+ template <typename Polygon>
+ static inline bool apply(Polygon const& polygon)
+ {
+ return boost::empty(exterior_ring(polygon))
+ && check_interior_rings(interior_rings(polygon));
+ }
+};
+
+template <typename Policy = range_is_empty>
+struct multi_is_empty
+{
+ template <typename MultiGeometry>
+ static inline bool apply(MultiGeometry const& multigeometry)
+ {
+ return check_iterator_range
+ <
+ Policy, true // allow empty range
+ >::apply(boost::begin(multigeometry), boost::end(multigeometry));
+ }
+
+};
+
+}} // namespace detail::is_empty
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Geometry, typename Tag = typename tag<Geometry>::type>
+struct is_empty : not_implemented<Tag>
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, point_tag>
+ : detail::is_empty::always_not_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, box_tag>
+ : detail::is_empty::always_not_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, segment_tag>
+ : detail::is_empty::always_not_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, linestring_tag>
+ : detail::is_empty::range_is_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, ring_tag>
+ : detail::is_empty::range_is_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, polygon_tag>
+ : detail::is_empty::polygon_is_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, multi_point_tag>
+ : detail::is_empty::range_is_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, multi_linestring_tag>
+ : detail::is_empty::multi_is_empty<>
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, multi_polygon_tag>
+ : detail::is_empty::multi_is_empty<detail::is_empty::polygon_is_empty>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry>
+struct is_empty
+{
+ static inline bool apply(Geometry const& geometry)
+ {
+ concept::check<Geometry const>();
+
+ return dispatch::is_empty<Geometry>::apply(geometry);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct is_empty<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ struct visitor : boost::static_visitor<bool>
+ {
+ template <typename Geometry>
+ inline bool operator()(Geometry const& geometry) const
+ {
+ return is_empty<Geometry>::apply(geometry);
+ }
+ };
+
+ static bool
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
+ {
+ return boost::apply_visitor(visitor(), geometry);
+ }
+};
+
+} // namespace resolve_variant
+
+
+/*!
+\brief \brief_check{is the empty set}
+\ingroup is_empty
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\return \return_check{is the empty set}
+
+\qbk{[include reference/algorithms/is_empty.qbk]}
+*/
+template <typename Geometry>
+inline bool is_empty(Geometry const& geometry)
+{
+ return resolve_variant::is_empty<Geometry>::apply(geometry);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_IS_EMPTY_HPP
diff --git a/boost/geometry/algorithms/length.hpp b/boost/geometry/algorithms/length.hpp
index fad17ade46..58324bcc80 100644
--- a/boost/geometry/algorithms/length.hpp
+++ b/boost/geometry/algorithms/length.hpp
@@ -229,7 +229,7 @@ struct length<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
Strategy const& strategy
)
{
- return apply_visitor(visitor<Strategy>(strategy), geometry);
+ return boost::apply_visitor(visitor<Strategy>(strategy), geometry);
}
};
diff --git a/boost/geometry/algorithms/overlaps.hpp b/boost/geometry/algorithms/overlaps.hpp
index f724a544fd..96310d6cb5 100644
--- a/boost/geometry/algorithms/overlaps.hpp
+++ b/boost/geometry/algorithms/overlaps.hpp
@@ -28,7 +28,8 @@
#include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
namespace boost { namespace geometry
{
@@ -149,9 +150,9 @@ template
typename Tag2 = typename tag<Geometry2>::type
>
struct overlaps
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_overlaps_type,
+ detail::de9im::static_mask_overlaps_type,
Geometry1,
Geometry2
>
diff --git a/boost/geometry/algorithms/relate.hpp b/boost/geometry/algorithms/relate.hpp
new file mode 100644
index 0000000000..34733ec596
--- /dev/null
+++ b/boost/geometry/algorithms/relate.hpp
@@ -0,0 +1,17 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_ALGORITHMS_RELATE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_RELATE_HPP
+
+#include <boost/geometry/algorithms/detail/relate/interface.hpp>
+#include <boost/geometry/algorithms/detail/relate/implementation.hpp>
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_RELATE_HPP
diff --git a/boost/geometry/algorithms/relation.hpp b/boost/geometry/algorithms/relation.hpp
new file mode 100644
index 0000000000..c3cf2f99f8
--- /dev/null
+++ b/boost/geometry/algorithms/relation.hpp
@@ -0,0 +1,17 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_ALGORITHMS_RELATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_RELATION_HPP
+
+#include <boost/geometry/algorithms/detail/relation/interface.hpp>
+#include <boost/geometry/algorithms/detail/relation/implementation.hpp>
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_RELATION_HPP
diff --git a/boost/geometry/algorithms/simplify.hpp b/boost/geometry/algorithms/simplify.hpp
index 0047546718..9dd87f61a9 100644
--- a/boost/geometry/algorithms/simplify.hpp
+++ b/boost/geometry/algorithms/simplify.hpp
@@ -491,7 +491,7 @@ inline void simplify(Geometry const& geometry, Geometry& out,
{
concept::check<Geometry>();
- simplify(geometry, out, max_distance, default_strategy());
+ geometry::simplify(geometry, out, max_distance, default_strategy());
}
diff --git a/boost/geometry/algorithms/sym_difference.hpp b/boost/geometry/algorithms/sym_difference.hpp
index de34c9c7b0..6c49ca634c 100644
--- a/boost/geometry/algorithms/sym_difference.hpp
+++ b/boost/geometry/algorithms/sym_difference.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -10,9 +15,12 @@
#define BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
#include <algorithm>
-
+#include <iterator>
+#include <vector>
#include <boost/geometry/algorithms/intersection.hpp>
+#include <boost/geometry/algorithms/union.hpp>
+#include <boost/geometry/geometries/multi_polygon.hpp>
namespace boost { namespace geometry
@@ -23,6 +31,177 @@ namespace detail { namespace sym_difference
{
+template <typename GeometryOut>
+struct compute_difference
+{
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename RobustPolicy,
+ typename OutputIterator,
+ typename Strategy
+ >
+ static inline OutputIterator apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ return geometry::dispatch::intersection_insert
+ <
+ Geometry1,
+ Geometry2,
+ GeometryOut,
+ overlay_difference,
+ geometry::detail::overlay::do_reverse
+ <
+ geometry::point_order<Geometry1>::value
+ >::value,
+ geometry::detail::overlay::do_reverse
+ <
+ geometry::point_order<Geometry2>::value, true
+ >::value
+ >::apply(geometry1, geometry2, robust_policy, out, strategy);
+ }
+};
+
+
+
+template <typename GeometryOut, typename Geometry1, typename Geometry2>
+struct sym_difference_generic
+{
+ template
+ <
+ typename RobustPolicy,
+ typename OutputIterator,
+ typename Strategy
+ >
+ static inline OutputIterator apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ out = compute_difference
+ <
+ GeometryOut
+ >::apply(geometry1, geometry2, robust_policy, out, strategy);
+
+ return compute_difference
+ <
+ GeometryOut
+ >::apply(geometry2, geometry1, robust_policy, out, strategy);
+ }
+};
+
+
+template <typename GeometryOut, typename Areal1, typename Areal2>
+struct sym_difference_areal_areal
+{
+ template
+ <
+ typename RobustPolicy,
+ typename OutputIterator,
+ typename Strategy
+ >
+ static inline OutputIterator apply(Areal1 const& areal1,
+ Areal2 const& areal2,
+ RobustPolicy const& robust_policy,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ typedef geometry::model::multi_polygon
+ <
+ GeometryOut
+ > helper_geometry_type;
+
+ helper_geometry_type diff12, diff21;
+
+ std::back_insert_iterator<helper_geometry_type> oit12(diff12);
+ std::back_insert_iterator<helper_geometry_type> oit21(diff21);
+
+ compute_difference
+ <
+ GeometryOut
+ >::apply(areal1, areal2, robust_policy, oit12, strategy);
+
+ compute_difference
+ <
+ GeometryOut
+ >::apply(areal2, areal1, robust_policy, oit21, strategy);
+
+ return geometry::dispatch::union_insert
+ <
+ helper_geometry_type,
+ helper_geometry_type,
+ GeometryOut
+ >::apply(diff12, diff21, robust_policy, out, strategy);
+ }
+};
+
+
+}} // namespace detail::sym_difference
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename GeometryOut,
+ typename TagIn1 = typename geometry::tag_cast
+ <
+ typename tag<Geometry1>::type, areal_tag
+ >::type,
+ typename TagIn2 = typename geometry::tag_cast
+ <
+ typename tag<Geometry2>::type, areal_tag
+ >::type,
+ typename TagOut = typename geometry::tag<GeometryOut>::type
+>
+struct sym_difference_insert
+ : detail::sym_difference::sym_difference_generic
+ <
+ GeometryOut, Geometry1, Geometry2
+ >
+{};
+
+
+template
+<
+ typename Areal1,
+ typename Areal2,
+ typename GeometryOut,
+ typename TagOut
+>
+struct sym_difference_insert
+ <
+ Areal1, Areal2, GeometryOut,
+ areal_tag, areal_tag, TagOut
+ > : detail::sym_difference::sym_difference_areal_areal
+ <
+ GeometryOut, Areal1, Areal2
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace sym_difference
+{
+
+
/*!
\brief \brief_calc2{symmetric difference} \brief_strategy
@@ -60,24 +239,10 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
concept::check<Geometry2 const>();
concept::check<GeometryOut>();
- out = geometry::dispatch::intersection_insert
+ return dispatch::sym_difference_insert
<
- Geometry1, Geometry2,
- GeometryOut,
- overlay_difference,
- geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
- geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value
+ Geometry1, Geometry2, GeometryOut
>::apply(geometry1, geometry2, robust_policy, out, strategy);
- out = geometry::dispatch::intersection_insert
- <
- Geometry2, Geometry1,
- GeometryOut,
- overlay_difference,
- geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
- geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value, true>::value,
- geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value
- >::apply(geometry2, geometry1, robust_policy, out, strategy);
- return out;
}
diff --git a/boost/geometry/algorithms/touches.hpp b/boost/geometry/algorithms/touches.hpp
index 48334d7255..d6f0df3c74 100644
--- a/boost/geometry/algorithms/touches.hpp
+++ b/boost/geometry/algorithms/touches.hpp
@@ -37,7 +37,8 @@
#include <boost/geometry/algorithms/detail/sub_range.hpp>
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
-#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
namespace boost { namespace geometry
{
@@ -67,7 +68,7 @@ struct box_box_loop
coordinate_type2 const& max2 = get<max_corner, Dimension>(b2);
// TODO assert or exception?
- //BOOST_ASSERT(min1 <= max1 && min2 <= max2);
+ //BOOST_GEOMETRY_ASSERT(min1 <= max1 && min2 <= max2);
if ( max1 < min2 || max2 < min1 )
{
@@ -349,9 +350,9 @@ struct touches<Box1, Box2, box_tag, box_tag, areal_tag, areal_tag, false>
template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
struct touches<Linear1, Linear2, Tag1, Tag2, linear_tag, linear_tag, false>
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_touches_type,
+ detail::de9im::static_mask_touches_type,
Linear1,
Linear2
>
@@ -361,9 +362,9 @@ struct touches<Linear1, Linear2, Tag1, Tag2, linear_tag, linear_tag, false>
template <typename Linear, typename Areal, typename Tag1, typename Tag2>
struct touches<Linear, Areal, Tag1, Tag2, linear_tag, areal_tag, false>
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_touches_type,
+ detail::de9im::static_mask_touches_type,
Linear,
Areal
>
@@ -372,9 +373,9 @@ struct touches<Linear, Areal, Tag1, Tag2, linear_tag, areal_tag, false>
// A/L
template <typename Linear, typename Areal, typename Tag1, typename Tag2>
struct touches<Linear, Areal, Tag1, Tag2, linear_tag, areal_tag, true>
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_touches_type,
+ detail::de9im::static_mask_touches_type,
Areal,
Linear
>
diff --git a/boost/geometry/algorithms/transform.hpp b/boost/geometry/algorithms/transform.hpp
index 357263a4ea..c7f3bd6cbb 100644
--- a/boost/geometry/algorithms/transform.hpp
+++ b/boost/geometry/algorithms/transform.hpp
@@ -70,9 +70,9 @@ struct transform_box
typedef typename point_type<Box2>::type point_type2;
point_type1 lower_left, upper_right;
- detail::assign::assign_box_2d_corner<min_corner, min_corner>(
+ geometry::detail::assign::assign_box_2d_corner<min_corner, min_corner>(
b1, lower_left);
- detail::assign::assign_box_2d_corner<max_corner, max_corner>(
+ geometry::detail::assign::assign_box_2d_corner<max_corner, max_corner>(
b1, upper_right);
point_type2 p1, p2;
@@ -88,10 +88,10 @@ struct transform_box
if (x1 > x2) { std::swap(x1, x2); }
if (y1 > y2) { std::swap(y1, y2); }
- set<min_corner, 0>(b2, x1);
- set<min_corner, 1>(b2, y1);
- set<max_corner, 0>(b2, x2);
- set<max_corner, 1>(b2, y2);
+ geometry::set<min_corner, 0>(b2, x1);
+ geometry::set<min_corner, 1>(b2, y1);
+ geometry::set<max_corner, 0>(b2, x2);
+ geometry::set<max_corner, 1>(b2, y2);
return true;
}
@@ -161,8 +161,8 @@ struct transform_polygon
geometry::clear(poly2);
- if (!transform_range_out<point2_type>(exterior_ring(poly1),
- std::back_inserter(exterior_ring(poly2)), strategy))
+ if (!transform_range_out<point2_type>(geometry::exterior_ring(poly1),
+ std::back_inserter(geometry::exterior_ring(poly2)), strategy))
{
return false;
}
@@ -174,12 +174,13 @@ struct transform_polygon
<
typename traits::interior_mutable_type<Polygon2>::type
>::type
- >::apply(interior_rings(poly2), num_interior_rings(poly1));
+ >::apply(geometry::interior_rings(poly2),
+ geometry::num_interior_rings(poly1));
- typename interior_return_type<Polygon1 const>::type
- rings1 = interior_rings(poly1);
- typename interior_return_type<Polygon2>::type
- rings2 = interior_rings(poly2);
+ typename geometry::interior_return_type<Polygon1 const>::type
+ rings1 = geometry::interior_rings(poly1);
+ typename geometry::interior_return_type<Polygon2>::type
+ rings2 = geometry::interior_rings(poly2);
typename detail::interior_iterator<Polygon1 const>::type
it1 = boost::begin(rings1);
@@ -424,7 +425,7 @@ struct transform<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Strategy const& strategy
)
{
- return apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
+ return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
}
};
@@ -469,7 +470,7 @@ inline bool transform(Geometry1 const& geometry1, Geometry2& geometry2,
template <typename Geometry1, typename Geometry2>
inline bool transform(Geometry1 const& geometry1, Geometry2& geometry2)
{
- return transform(geometry1, geometry2, default_strategy());
+ return geometry::transform(geometry1, geometry2, default_strategy());
}
diff --git a/boost/geometry/algorithms/within.hpp b/boost/geometry/algorithms/within.hpp
index 9f2b6fedf7..35f9396ba6 100644
--- a/boost/geometry/algorithms/within.hpp
+++ b/boost/geometry/algorithms/within.hpp
@@ -358,9 +358,9 @@ struct within<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Geometry2 const& m_geometry2;
Strategy const& m_strategy;
- visitor(Geometry2 const& geometry2, Strategy const& strategy):
- m_geometry2(geometry2),
- m_strategy(strategy)
+ visitor(Geometry2 const& geometry2, Strategy const& strategy)
+ : m_geometry2(geometry2)
+ , m_strategy(strategy)
{}
template <typename Geometry1>
@@ -378,10 +378,8 @@ struct within<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Geometry2 const& geometry2,
Strategy const& strategy)
{
- return boost::apply_visitor(
- visitor<Strategy>(geometry2, strategy),
- geometry1
- );
+ return boost::apply_visitor(visitor<Strategy>(geometry2, strategy),
+ geometry1);
}
};
@@ -394,9 +392,9 @@ struct within<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
Geometry1 const& m_geometry1;
Strategy const& m_strategy;
- visitor(Geometry1 const& geometry1, Strategy const& strategy):
- m_geometry1(geometry1),
- m_strategy(strategy)
+ visitor(Geometry1 const& geometry1, Strategy const& strategy)
+ : m_geometry1(geometry1)
+ , m_strategy(strategy)
{}
template <typename Geometry2>
@@ -414,9 +412,8 @@ struct within<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
Strategy const& strategy)
{
- return boost::apply_visitor(
- visitor<Strategy>(geometry1, strategy),
- geometry2
+ return boost::apply_visitor(visitor<Strategy>(geometry1, strategy),
+ geometry2
);
}
};
@@ -453,10 +450,9 @@ struct within<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
Strategy const& strategy)
{
- return boost::apply_visitor(
- visitor<Strategy>(strategy),
- geometry1, geometry2
- );
+ return boost::apply_visitor(visitor<Strategy>(strategy),
+ geometry1,
+ geometry2);
}
};
diff --git a/boost/geometry/arithmetic/arithmetic.hpp b/boost/geometry/arithmetic/arithmetic.hpp
index 6eb31f488e..fbc3ca443e 100644
--- a/boost/geometry/arithmetic/arithmetic.hpp
+++ b/boost/geometry/arithmetic/arithmetic.hpp
@@ -22,6 +22,7 @@
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/util/for_each_coordinate.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry
@@ -32,80 +33,94 @@ namespace detail
{
-template <typename P>
+template <typename Point>
struct param
{
typedef typename boost::call_traits
<
- typename coordinate_type<P>::type
+ typename coordinate_type<Point>::type
>::param_type type;
};
-template <typename C, template <typename> class Function>
+template <typename Value, template <typename> class Function>
struct value_operation
{
- C m_value;
+ Value m_value;
- inline value_operation(C const &value)
+ inline value_operation(Value const &value)
: m_value(value)
{}
- template <typename P, int I>
- inline void apply(P& point) const
+ template <typename PointDst, std::size_t Index>
+ inline void apply(PointDst& point_dst) const
{
- set<I>(point, Function<C>()(get<I>(point), m_value));
+ set<Index>(point_dst,
+ Function
+ <
+ typename geometry::select_most_precise
+ <
+ Value,
+ typename geometry::coordinate_type<PointDst>::type
+ >::type
+ >()(get<Index>(point_dst), m_value));
}
};
template <typename PointSrc, template <typename> class Function>
struct point_operation
{
- typedef typename coordinate_type<PointSrc>::type coordinate_type;
- PointSrc const& m_source_point;
+ PointSrc const& m_point_src;
inline point_operation(PointSrc const& point)
- : m_source_point(point)
+ : m_point_src(point)
{}
- template <typename PointDst, int I>
- inline void apply(PointDst& dest_point) const
+ template <typename PointDst, std::size_t Index>
+ inline void apply(PointDst& point_dst) const
{
- set<I>(dest_point,
- Function<coordinate_type>()(get<I>(dest_point), get<I>(m_source_point)));
+ set<Index>(point_dst,
+ Function
+ <
+ typename geometry::select_most_precise
+ <
+ typename geometry::coordinate_type<PointSrc>::type,
+ typename geometry::coordinate_type<PointDst>::type
+ >::type
+ >()(get<Index>(point_dst), get<Index>(m_point_src)));
}
};
-template <typename C>
+template <typename Value>
struct value_assignment
{
- C m_value;
+ Value m_value;
- inline value_assignment(C const &value)
+ inline value_assignment(Value const &value)
: m_value(value)
{}
- template <typename P, int I>
- inline void apply(P& point) const
+ template <typename PointDst, std::size_t Index>
+ inline void apply(PointDst& point_dst) const
{
- set<I>(point, m_value);
+ set<Index>(point_dst, m_value);
}
};
template <typename PointSrc>
struct point_assignment
{
- PointSrc const& m_source_point;
+ PointSrc const& m_point_src;
inline point_assignment(PointSrc const& point)
- : m_source_point(point)
+ : m_point_src(point)
{}
- template <typename PointDst, int I>
- inline void apply(PointDst& dest_point) const
+ template <typename PointDst, std::size_t Index>
+ inline void apply(PointDst& point_dst) const
{
- set<I>(dest_point, get<I>(m_source_point));
+ set<Index>(point_dst, get<Index>(m_point_src));
}
};
@@ -126,7 +141,12 @@ inline void add_value(Point& p, typename detail::param<Point>::type value)
{
BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
- for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::plus>(value));
+ for_each_coordinate(p,
+ detail::value_operation
+ <
+ typename coordinate_type<Point>::type,
+ std::plus
+ >(value));
}
/*!
@@ -161,7 +181,12 @@ inline void subtract_value(Point& p, typename detail::param<Point>::type value)
{
BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
- for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::minus>(value));
+ for_each_coordinate(p,
+ detail::value_operation
+ <
+ typename coordinate_type<Point>::type,
+ std::minus
+ >(value));
}
/*!
@@ -196,7 +221,12 @@ inline void multiply_value(Point& p, typename detail::param<Point>::type value)
{
BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
- for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::multiplies>(value));
+ for_each_coordinate(p,
+ detail::value_operation
+ <
+ typename coordinate_type<Point>::type,
+ std::multiplies
+ >(value));
}
/*!
@@ -232,7 +262,12 @@ inline void divide_value(Point& p, typename detail::param<Point>::type value)
{
BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
- for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::divides>(value));
+ for_each_coordinate(p,
+ detail::value_operation
+ <
+ typename coordinate_type<Point>::type,
+ std::divides
+ >(value));
}
/*!
@@ -267,7 +302,11 @@ inline void assign_value(Point& p, typename detail::param<Point>::type value)
{
BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
- for_each_coordinate(p, detail::value_assignment<typename coordinate_type<Point>::type>(value));
+ for_each_coordinate(p,
+ detail::value_assignment
+ <
+ typename coordinate_type<Point>::type
+ >(value));
}
/*!
diff --git a/boost/geometry/core/assert.hpp b/boost/geometry/core/assert.hpp
new file mode 100644
index 0000000000..0f3ae6baea
--- /dev/null
+++ b/boost/geometry/core/assert.hpp
@@ -0,0 +1,43 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
+// Copyright (c) 2007, 2014 Peter Dimov
+// Copyright (c) Beman Dawes 2011
+// Copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_CORE_ASSERT_HPP
+#define BOOST_GEOMETRY_CORE_ASSERT_HPP
+
+#include <boost/assert.hpp>
+
+#undef BOOST_GEOMETRY_ASSERT
+#undef BOOST_GEOMETRY_ASSERT_MSG
+
+#if defined(BOOST_GEOMETRY_ENABLE_ASSERT_HANDLER) || ( defined(BOOST_GEOMETRY_ENABLE_ASSERT_DEBUG_HANDLER) && !defined(NDEBUG) )
+
+#include <boost/config.hpp> // for BOOST_LIKELY
+#include <boost/current_function.hpp>
+
+namespace boost { namespace geometry
+{
+ 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::geometry
+
+#define BOOST_GEOMETRY_ASSERT(expr) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::geometry::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
+#define BOOST_GEOMETRY_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::geometry::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
+
+#else
+
+#define BOOST_GEOMETRY_ASSERT(expr) BOOST_ASSERT(expr)
+#define BOOST_GEOMETRY_ASSERT_MSG(expr, msg) BOOST_ASSERT_MSG(expr, msg)
+
+#endif
+
+#endif // BOOST_GEOMETRY_CORE_EXCEPTION_HPP
diff --git a/boost/geometry/core/exception.hpp b/boost/geometry/core/exception.hpp
index 97d249e938..6868ca775a 100644
--- a/boost/geometry/core/exception.hpp
+++ b/boost/geometry/core/exception.hpp
@@ -1,8 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -26,8 +31,31 @@ namespace boost { namespace geometry
are derived from exception, so it might be convenient to catch it.
*/
class exception : public std::exception
-{};
+{
+ virtual char const* what() const throw()
+ {
+ return "Boost.Geometry exception";
+ }
+};
+
+/*!
+\brief Invalid Input Exception
+\ingroup core
+\details The invalid_input_exception is thrown if an invalid attribute
+ is passed into a function, e.g. a DE-9IM mask string code containing
+ invalid characters passed into a de9im::mask constructor.
+ */
+class invalid_input_exception : public geometry::exception
+{
+public:
+
+ inline invalid_input_exception() {}
+ virtual char const* what() const throw()
+ {
+ return "Boost.Geometry Invalid-Input exception";
+ }
+};
/*!
\brief Empty Input Exception
@@ -42,7 +70,7 @@ class exception : public std::exception
\* [link geometry.reference.algorithms.length the length function]
}
*/
-class empty_input_exception : public geometry::exception
+class empty_input_exception : public geometry::invalid_input_exception
{
public:
diff --git a/boost/geometry/core/radian_access.hpp b/boost/geometry/core/radian_access.hpp
index bac77d7bc7..374c2954a2 100644
--- a/boost/geometry/core/radian_access.hpp
+++ b/boost/geometry/core/radian_access.hpp
@@ -1,8 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -47,7 +52,8 @@ struct degree_radian_converter
return boost::numeric_cast
<
coordinate_type
- >(geometry::get<Dimension>(geometry) * geometry::math::d2r);
+ >(geometry::get<Dimension>(geometry)
+ * math::d2r<coordinate_type>());
}
static inline void set(Geometry& geometry, coordinate_type const& radians)
@@ -55,7 +61,7 @@ struct degree_radian_converter
geometry::set<Dimension>(geometry, boost::numeric_cast
<
coordinate_type
- >(radians * geometry::math::r2d));
+ >(radians * math::r2d<coordinate_type>()));
}
};
diff --git a/boost/geometry/geometries/box.hpp b/boost/geometry/geometries/box.hpp
index a2e3d4fd79..97a4ba06da 100644
--- a/boost/geometry/geometries/box.hpp
+++ b/boost/geometry/geometries/box.hpp
@@ -17,10 +17,14 @@
#include <cstddef>
#include <boost/concept/assert.hpp>
+#include <boost/config.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+#include <boost/geometry/core/assert.hpp>
+#endif
namespace boost { namespace geometry
@@ -29,18 +33,21 @@ namespace boost { namespace geometry
namespace model
{
-
/*!
- \brief Class box: defines a box made of two describing points
- \ingroup geometries
- \details Box is always described by a min_corner() and a max_corner() point. If another
- rectangle is used, use linear_ring or polygon.
- \note Boxes are for selections and for calculating the envelope of geometries. Not all algorithms
- are implemented for box. Boxes are also used in Spatial Indexes.
- \tparam Point point type. The box takes a point type as template parameter.
- The point type can be any point type.
- It can be 2D but can also be 3D or more dimensional.
- The box can also take a latlong point type as template parameter.
+\brief Class box: defines a box made of two describing points
+\ingroup geometries
+\details Box is always described by a min_corner() and a max_corner() point. If another
+ rectangle is used, use linear_ring or polygon.
+\note Boxes are for selections and for calculating the envelope of geometries. Not all algorithms
+are implemented for box. Boxes are also used in Spatial Indexes.
+\tparam Point point type. The box takes a point type as template parameter.
+The point type can be any point type.
+It can be 2D but can also be 3D or more dimensional.
+The box can also take a latlong point type as template parameter.
+
+\qbk{[include reference/geometries/box.qbk]}
+\qbk{before.synopsis, [heading Model of]}
+\qbk{before.synopsis, [link geometry.reference.concepts.concept_box Box Concept]}
*/
template<typename Point>
@@ -50,7 +57,25 @@ class box
public:
- inline box() {}
+#if !defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
+ /// \constructor_default_no_init
+ box() = default;
+#else
+ /// \constructor_default_no_init
+ inline box()
+ {}
+#endif
+#else // defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ inline box()
+ {
+ m_created = 1;
+ }
+ ~box()
+ {
+ m_created = 0;
+ }
+#endif
/*!
\brief Constructor taking the minimum corner point and the maximum corner point
@@ -59,18 +84,50 @@ public:
{
geometry::convert(min_corner, m_min_corner);
geometry::convert(max_corner, m_max_corner);
+
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ m_created = 1;
+#endif
}
- inline Point const& min_corner() const { return m_min_corner; }
- inline Point const& max_corner() const { return m_max_corner; }
+ inline Point const& min_corner() const
+ {
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ BOOST_GEOMETRY_ASSERT(m_created == 1);
+#endif
+ return m_min_corner;
+ }
+ inline Point const& max_corner() const
+ {
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ BOOST_GEOMETRY_ASSERT(m_created == 1);
+#endif
+ return m_max_corner;
+ }
- inline Point& min_corner() { return m_min_corner; }
- inline Point& max_corner() { return m_max_corner; }
+ inline Point& min_corner()
+ {
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ BOOST_GEOMETRY_ASSERT(m_created == 1);
+#endif
+ return m_min_corner;
+ }
+ inline Point& max_corner()
+ {
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ BOOST_GEOMETRY_ASSERT(m_created == 1);
+#endif
+ return m_max_corner;
+ }
private:
Point m_min_corner;
Point m_max_corner;
+
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ int m_created;
+#endif
};
diff --git a/boost/geometry/geometries/concepts/point_concept.hpp b/boost/geometry/geometries/concepts/point_concept.hpp
index db49771129..52f8d038ea 100644
--- a/boost/geometry/geometries/concepts/point_concept.hpp
+++ b/boost/geometry/geometries/concepts/point_concept.hpp
@@ -165,7 +165,7 @@ class ConstPoint
{
const P* p = 0;
ctype coord(geometry::get<Dimension>(*p));
- boost::ignore_unused(coord);
+ boost::ignore_unused(p, coord);
dimension_checker<P, Dimension+1, DimensionCount>::apply();
}
};
diff --git a/boost/geometry/geometries/helper_geometry.hpp b/boost/geometry/geometries/helper_geometry.hpp
new file mode 100644
index 0000000000..9cf14a9117
--- /dev/null
+++ b/boost/geometry/geometries/helper_geometry.hpp
@@ -0,0 +1,162 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_HELPER_GEOMETRY_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_HELPER_GEOMETRY_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/box.hpp>
+#include <boost/geometry/geometries/point.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace detail { namespace helper_geometries
+{
+
+template <typename Geometry, typename CS_Tag = typename cs_tag<Geometry>::type>
+struct default_units
+{
+ typedef typename coordinate_system<Geometry>::type::units type;
+};
+
+// The Cartesian coordinate system does not define the type units.
+// For that reason the generic implementation for default_units cannot be used
+// and specialization needs to be defined.
+// Moreover, it makes sense to define the units for the Cartesian
+// coordinate system to be radians, as this way a Cartesian point can
+// potentially be used in algorithms taking non-Cartesian strategies
+// and work as if it was as point in the non-Cartesian coordinate
+// system with radian units.
+template <typename Geometry>
+struct default_units<Geometry, cartesian_tag>
+{
+ typedef radian type;
+};
+
+
+template <typename Units, typename CS_Tag>
+struct cs_tag_to_coordinate_system
+{
+ typedef cs::cartesian type;
+};
+
+template <typename Units>
+struct cs_tag_to_coordinate_system<Units, spherical_equatorial_tag>
+{
+ typedef cs::spherical_equatorial<Units> type;
+};
+
+template <typename Units>
+struct cs_tag_to_coordinate_system<Units, spherical_tag>
+{
+ typedef cs::spherical<Units> type;
+};
+
+template <typename Units>
+struct cs_tag_to_coordinate_system<Units, geographic_tag>
+{
+ typedef cs::geographic<Units> type;
+};
+
+
+template
+<
+ typename Point,
+ typename NewCoordinateType,
+ typename NewUnits,
+ typename CS_Tag = typename cs_tag<Point>::type
+>
+struct helper_point
+{
+ typedef model::point
+ <
+ NewCoordinateType,
+ dimension<Point>::value,
+ typename cs_tag_to_coordinate_system<NewUnits, CS_Tag>::type
+ > type;
+};
+
+
+}} // detail::helper_geometries
+
+
+namespace detail_dispatch
+{
+
+
+template
+<
+ typename Geometry,
+ typename NewCoordinateType,
+ typename NewUnits,
+ typename Tag = typename tag<Geometry>::type>
+struct helper_geometry : not_implemented<Geometry>
+{};
+
+
+template <typename Point, typename NewCoordinateType, typename NewUnits>
+struct helper_geometry<Point, NewCoordinateType, NewUnits, point_tag>
+{
+ typedef typename detail::helper_geometries::helper_point
+ <
+ Point, NewCoordinateType, NewUnits
+ >::type type;
+};
+
+
+template <typename Box, typename NewCoordinateType, typename NewUnits>
+struct helper_geometry<Box, NewCoordinateType, NewUnits, box_tag>
+{
+ typedef model::box
+ <
+ typename helper_geometry
+ <
+ typename point_type<Box>::type, NewCoordinateType, NewUnits
+ >::type
+ > type;
+};
+
+
+} // detail_dispatch
+
+
+// Meta-function that provides a new helper geometry of the same kind as
+// the input geometry and the same coordinate system type,
+// but with a possibly different coordinate type and coordinate system units
+template
+<
+ typename Geometry,
+ typename NewCoordinateType = typename coordinate_type<Geometry>::type,
+ typename NewUnits = typename detail::helper_geometries::default_units
+ <
+ Geometry
+ >::type
+>
+struct helper_geometry
+{
+ typedef typename detail_dispatch::helper_geometry
+ <
+ Geometry, NewCoordinateType, NewUnits
+ >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_HELPER_GEOMETRY_HPP
diff --git a/boost/geometry/geometries/linestring.hpp b/boost/geometry/geometries/linestring.hpp
index 68dc87a3cf..22c9c99de9 100644
--- a/boost/geometry/geometries/linestring.hpp
+++ b/boost/geometry/geometries/linestring.hpp
@@ -26,12 +26,10 @@
#include <boost/geometry/geometries/concepts/point_concept.hpp>
-#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
-#endif
namespace boost { namespace geometry
{
@@ -46,6 +44,7 @@ namespace model
\tparam Container \tparam_container
\tparam Allocator \tparam_allocator
+\qbk{[include reference/geometries/linestring.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_linestring Linestring Concept]
@@ -76,7 +75,6 @@ public :
: base_type(begin, end)
{}
-#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/// \constructor_initializer_list{linestring}
@@ -98,7 +96,6 @@ public :
//#endif
#endif
-#endif
};
} // namespace model
diff --git a/boost/geometry/geometries/multi_linestring.hpp b/boost/geometry/geometries/multi_linestring.hpp
index 195a58139c..cd08fdbe14 100644
--- a/boost/geometry/geometries/multi_linestring.hpp
+++ b/boost/geometry/geometries/multi_linestring.hpp
@@ -23,12 +23,10 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/linestring_concept.hpp>
-#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
-#endif
namespace boost { namespace geometry
{
@@ -43,6 +41,7 @@ namespace model
e.g. a highway (with interruptions)
\ingroup geometries
+\qbk{[include reference/geometries/multi_linestring.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_multi_linestring MultiLineString Concept]
@@ -58,7 +57,10 @@ class multi_linestring : public Container<LineString, Allocator<LineString> >
{
BOOST_CONCEPT_ASSERT( (concept::Linestring<LineString>) );
-#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+
+ // default constructor and base_type definitions are required only
+ // if the constructor taking std::initializer_list is defined
typedef Container<LineString, Allocator<LineString> > base_type;
@@ -68,8 +70,6 @@ public:
: base_type()
{}
-#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
-
/// \constructor_initializer_list{multi_linestring}
inline multi_linestring(std::initializer_list<LineString> l)
: base_type(l.begin(), l.end())
@@ -89,7 +89,6 @@ public:
//#endif
#endif
-#endif
};
diff --git a/boost/geometry/geometries/multi_point.hpp b/boost/geometry/geometries/multi_point.hpp
index a5e64bb91c..ab4cd88177 100644
--- a/boost/geometry/geometries/multi_point.hpp
+++ b/boost/geometry/geometries/multi_point.hpp
@@ -23,12 +23,10 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
-#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
-#endif
namespace boost { namespace geometry
{
@@ -45,6 +43,8 @@ namespace model
\tparam Allocator \tparam_allocator
\details Multipoint can be used to group points belonging to each other,
e.g. a constellation, or the result set of an intersection
+
+\qbk{[include reference/geometries/multi_point.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_multi_point MultiPoint Concept]
@@ -74,7 +74,6 @@ public :
: base_type(begin, end)
{}
-#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/// \constructor_initializer_list{multi_point}
@@ -96,7 +95,6 @@ public :
//#endif
#endif
-#endif
};
} // namespace model
diff --git a/boost/geometry/geometries/multi_polygon.hpp b/boost/geometry/geometries/multi_polygon.hpp
index 51fcf235f8..9db74b4ec4 100644
--- a/boost/geometry/geometries/multi_polygon.hpp
+++ b/boost/geometry/geometries/multi_polygon.hpp
@@ -23,12 +23,10 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/polygon_concept.hpp>
-#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
-#endif
namespace boost { namespace geometry
{
@@ -42,6 +40,7 @@ namespace model
e.g. Hawaii
\ingroup geometries
+\qbk{[include reference/geometries/multi_polygon.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_multi_polygon MultiPolygon Concept]
@@ -57,7 +56,10 @@ class multi_polygon : public Container<Polygon, Allocator<Polygon> >
{
BOOST_CONCEPT_ASSERT( (concept::Polygon<Polygon>) );
-#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+
+ // default constructor and base_type definitions are required only
+ // if the constructor taking std::initializer_list is defined
typedef Container<Polygon, Allocator<Polygon> > base_type;
@@ -67,8 +69,6 @@ public:
: base_type()
{}
-#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
-
/// \constructor_initializer_list{multi_polygon}
inline multi_polygon(std::initializer_list<Polygon> l)
: base_type(l.begin(), l.end())
@@ -88,7 +88,6 @@ public:
//#endif
#endif
-#endif
};
diff --git a/boost/geometry/geometries/point.hpp b/boost/geometry/geometries/point.hpp
index 056c7d5d02..70bfeed447 100644
--- a/boost/geometry/geometries/point.hpp
+++ b/boost/geometry/geometries/point.hpp
@@ -22,14 +22,21 @@
#include <cstddef>
+#include <boost/config.hpp>
+#include <boost/mpl/assert.hpp>
#include <boost/mpl/int.hpp>
-#include <boost/static_assert.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+#include <algorithm>
+#include <boost/geometry/core/assert.hpp>
+#endif
+
namespace boost { namespace geometry
{
@@ -100,7 +107,10 @@ template
>
class point
{
-private:
+ BOOST_MPL_ASSERT_MSG((DimensionCount >= 1),
+ DIMENSION_GREATER_THAN_ZERO_EXPECTED,
+ (boost::mpl::int_<DimensionCount>));
+
// The following enum is used to fully instantiate the
// CoordinateSystem class and check the correctness of the units
// passed for non-Cartesian coordinate systems.
@@ -108,11 +118,27 @@ private:
public:
- /// @brief Default constructor, no initialization
+#if !defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
+ /// \constructor_default_no_init
+ point() = default;
+#else
+ /// \constructor_default_no_init
inline point()
+ {}
+#endif
+#else // defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ point()
{
- BOOST_STATIC_ASSERT(DimensionCount >= 1);
+ m_created = 1;
+ std::fill_n(m_values_initialized, DimensionCount, 0);
}
+ ~point()
+ {
+ m_created = 0;
+ std::fill_n(m_values_initialized, DimensionCount, 0);
+ }
+#endif
/// @brief Constructor to set one value
explicit inline point(CoordinateType const& v0)
@@ -120,6 +146,11 @@ public:
detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
detail::array_assign<DimensionCount, 1>::apply(m_values, CoordinateType());
detail::array_assign<DimensionCount, 2>::apply(m_values, CoordinateType());
+
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ m_created = 1;
+ std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
+#endif
}
/// @brief Constructor to set two values
@@ -128,6 +159,11 @@ public:
detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
detail::array_assign<DimensionCount, 1>::apply(m_values, v1);
detail::array_assign<DimensionCount, 2>::apply(m_values, CoordinateType());
+
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ m_created = 1;
+ std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
+#endif
}
/// @brief Constructor to set three values
@@ -137,6 +173,11 @@ public:
detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
detail::array_assign<DimensionCount, 1>::apply(m_values, v1);
detail::array_assign<DimensionCount, 2>::apply(m_values, v2);
+
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ m_created = 1;
+ std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
+#endif
}
/// @brief Get a coordinate
@@ -145,6 +186,10 @@ public:
template <std::size_t K>
inline CoordinateType const& get() const
{
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ BOOST_GEOMETRY_ASSERT(m_created == 1);
+ BOOST_GEOMETRY_ASSERT(m_values_initialized[K] == 1);
+#endif
BOOST_STATIC_ASSERT(K < DimensionCount);
return m_values[K];
}
@@ -155,6 +200,10 @@ public:
template <std::size_t K>
inline void set(CoordinateType const& value)
{
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ BOOST_GEOMETRY_ASSERT(m_created == 1);
+ m_values_initialized[K] = 1;
+#endif
BOOST_STATIC_ASSERT(K < DimensionCount);
m_values[K] = value;
}
@@ -162,6 +211,11 @@ public:
private:
CoordinateType m_values[DimensionCount];
+
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ int m_created;
+ int m_values_initialized[DimensionCount];
+#endif
};
diff --git a/boost/geometry/geometries/point_xy.hpp b/boost/geometry/geometries/point_xy.hpp
index 652930666f..bbc35d5cec 100644
--- a/boost/geometry/geometries/point_xy.hpp
+++ b/boost/geometry/geometries/point_xy.hpp
@@ -16,6 +16,7 @@
#include <cstddef>
+#include <boost/config.hpp>
#include <boost/mpl/int.hpp>
#include <boost/geometry/core/cs.hpp>
@@ -32,6 +33,7 @@ namespace model { namespace d2
\tparam CoordinateType numeric type, for example, double, float, int
\tparam CoordinateSystem coordinate system, defaults to cs::cartesian
+\qbk{[include reference/geometries/point_xy.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_point Point Concept]
@@ -45,10 +47,14 @@ class point_xy : public model::point<CoordinateType, 2, CoordinateSystem>
{
public:
- /// Default constructor, does not initialize anything
+#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
+ /// \constructor_default_no_init
+ point_xy() = default;
+#else
+ /// \constructor_default_no_init
inline point_xy()
- : model::point<CoordinateType, 2, CoordinateSystem>()
{}
+#endif
/// Constructor with x/y values
inline point_xy(CoordinateType const& x, CoordinateType const& y)
diff --git a/boost/geometry/geometries/pointing_segment.hpp b/boost/geometry/geometries/pointing_segment.hpp
index 681752ef2d..2c4284d10a 100644
--- a/boost/geometry/geometries/pointing_segment.hpp
+++ b/boost/geometry/geometries/pointing_segment.hpp
@@ -12,17 +12,16 @@
#include <cstddef>
-#include <boost/assert.hpp>
#include <boost/concept/assert.hpp>
#include <boost/core/addressof.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_const.hpp>
-#include <boost/geometry/geometries/concepts/point_concept.hpp>
-
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
namespace boost { namespace geometry
{
@@ -99,13 +98,13 @@ struct indexed_access<model::pointing_segment<Point>, 0, Dimension>
static inline coordinate_type get(segment_type const& s)
{
- BOOST_ASSERT( s.first != NULL );
+ BOOST_GEOMETRY_ASSERT( s.first != NULL );
return geometry::get<Dimension>(*s.first);
}
static inline void set(segment_type& s, coordinate_type const& value)
{
- BOOST_ASSERT( s.first != NULL );
+ BOOST_GEOMETRY_ASSERT( s.first != NULL );
geometry::set<Dimension>(*s.first, value);
}
};
@@ -122,13 +121,13 @@ struct indexed_access<model::pointing_segment<Point>, 1, Dimension>
static inline coordinate_type get(segment_type const& s)
{
- BOOST_ASSERT( s.second != NULL );
+ BOOST_GEOMETRY_ASSERT( s.second != NULL );
return geometry::get<Dimension>(*s.second);
}
static inline void set(segment_type& s, coordinate_type const& value)
{
- BOOST_ASSERT( s.second != NULL );
+ BOOST_GEOMETRY_ASSERT( s.second != NULL );
geometry::set<Dimension>(*s.second, value);
}
};
diff --git a/boost/geometry/geometries/polygon.hpp b/boost/geometry/geometries/polygon.hpp
index 5f2e87a11d..5e6064e893 100644
--- a/boost/geometry/geometries/polygon.hpp
+++ b/boost/geometry/geometries/polygon.hpp
@@ -27,12 +27,10 @@
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/geometries/ring.hpp>
-#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
-#endif
namespace boost { namespace geometry
{
@@ -57,6 +55,7 @@ namespace model
\note The container collecting the points in the rings can be different
from the container collecting the inner rings. They all default to vector.
+\qbk{[include reference/geometries/polygon.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_polygon Polygon Concept]
@@ -91,7 +90,10 @@ public:
inline ring_type& outer() { return m_outer; }
inline inner_container_type & inners() { return m_inners; }
-#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+
+ // default constructor definition is required only
+ // if the constructor taking std::initializer_list is defined
/// \constructor_default{polygon}
inline polygon()
@@ -99,7 +101,6 @@ public:
, m_inners()
{}
-#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/// \constructor_initializer_list{polygon}
inline polygon(std::initializer_list<ring_type> l)
: m_outer(l.size() > 0 ? *l.begin() : ring_type())
@@ -129,7 +130,6 @@ public:
//#endif
#endif
-#endif
/// Utility method, clears outer and inner rings
inline void clear()
diff --git a/boost/geometry/geometries/ring.hpp b/boost/geometry/geometries/ring.hpp
index 502c95d759..01bcf58cf5 100644
--- a/boost/geometry/geometries/ring.hpp
+++ b/boost/geometry/geometries/ring.hpp
@@ -27,12 +27,10 @@
#include <boost/geometry/geometries/concepts/point_concept.hpp>
-#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
-#endif
namespace boost { namespace geometry
{
@@ -50,6 +48,7 @@ namespace model
\tparam Container container type, for example std::vector, std::deque
\tparam Allocator container-allocator-type
+\qbk{[include reference/geometries/ring.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_ring Ring Concept]
@@ -80,7 +79,6 @@ public :
: base_type(begin, end)
{}
-#ifdef BOOST_GEOMETRY_EXPERIMENTAL_ENABLE_INITIALIZER_LIST
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/// \constructor_initializer_list{ring}
@@ -102,7 +100,6 @@ public :
//#endif
#endif
-#endif
};
} // namespace model
diff --git a/boost/geometry/geometries/segment.hpp b/boost/geometry/geometries/segment.hpp
index 3f47f79ec4..af406aa09f 100644
--- a/boost/geometry/geometries/segment.hpp
+++ b/boost/geometry/geometries/segment.hpp
@@ -35,14 +35,32 @@ namespace model
by two distinct end points, and contains every point on the line between its end points.
\note There is also a point-referring-segment, class referring_segment,
containing point references, where points are NOT copied
+
+\qbk{[include reference/geometries/segment.qbk]}
+\qbk{before.synopsis,
+[heading Model of]
+[link geometry.reference.concepts.concept_segment Segment Concept]
+}
*/
template<typename Point>
class segment : public std::pair<Point, Point>
{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
public :
+
+#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
+ /// \constructor_default_no_init
+ segment() = default;
+#else
+ /// \constructor_default_no_init
inline segment()
{}
+#endif
+ /*!
+ \brief Constructor taking the first and the second point
+ */
inline segment(Point const& p1, Point const& p2)
{
this->first = p1;
@@ -83,6 +101,9 @@ public:
point_type& first;
point_type& second;
+ /*!
+ \brief Constructor taking the first and the second point
+ */
inline referring_segment(point_type& p1, point_type& p2)
: first(p1)
, second(p2)
diff --git a/boost/geometry/geometry.hpp b/boost/geometry/geometry.hpp
index 8d34a0e4ef..d96facb340 100644
--- a/boost/geometry/geometry.hpp
+++ b/boost/geometry/geometry.hpp
@@ -70,6 +70,7 @@
#include <boost/geometry/algorithms/for_each.hpp>
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/algorithms/intersects.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/is_simple.hpp>
#include <boost/geometry/algorithms/is_valid.hpp>
#include <boost/geometry/algorithms/length.hpp>
@@ -80,6 +81,8 @@
#include <boost/geometry/algorithms/num_segments.hpp>
#include <boost/geometry/algorithms/overlaps.hpp>
#include <boost/geometry/algorithms/perimeter.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/relation.hpp>
#include <boost/geometry/algorithms/remove_spikes.hpp>
#include <boost/geometry/algorithms/reverse.hpp>
#include <boost/geometry/algorithms/simplify.hpp>
@@ -90,10 +93,6 @@
#include <boost/geometry/algorithms/unique.hpp>
#include <boost/geometry/algorithms/within.hpp>
-// Include multi a.o. because it can give weird effects
-// if you don't (e.g. area=0 of a multipolygon)
-#include <boost/geometry/multi/multi.hpp>
-
// check includes all concepts
#include <boost/geometry/geometries/concepts/check.hpp>
diff --git a/boost/geometry/index/detail/assert.hpp b/boost/geometry/index/detail/assert.hpp
index 311f37f640..08889df478 100644
--- a/boost/geometry/index/detail/assert.hpp
+++ b/boost/geometry/index/detail/assert.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry Index
//
-// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 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
@@ -9,13 +9,11 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ASSERT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ASSERT_HPP
-#include <boost/assert.hpp>
+#include <boost/geometry/core/assert.hpp>
-#ifndef BOOST_GEOMETRY_INDEX_ASSERT
+#undef BOOST_GEOMETRY_INDEX_ASSERT
#define BOOST_GEOMETRY_INDEX_ASSERT(CONDITION, TEXT_MSG) \
- BOOST_ASSERT_MSG(CONDITION, TEXT_MSG)
-
-#endif // BOOST_GEOMETRY_INDEX_ASSERT
+ BOOST_GEOMETRY_ASSERT_MSG(CONDITION, TEXT_MSG)
#endif // BOOST_GEOMETRY_INDEX_DETAIL_ASSERT_HPP
diff --git a/boost/geometry/index/detail/bounded_view.hpp b/boost/geometry/index/detail/bounded_view.hpp
index 0cd882fc94..e5f489d76b 100644
--- a/boost/geometry/index/detail/bounded_view.hpp
+++ b/boost/geometry/index/detail/bounded_view.hpp
@@ -3,7 +3,7 @@
// This view makes possible to treat some simple primitives as its bounding geometry
// e.g. box, nsphere, etc.
//
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2014-2015 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
@@ -12,6 +12,8 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP
+#include <boost/geometry/algorithms/envelope.hpp>
+
namespace boost { namespace geometry {
namespace index { namespace detail {
@@ -19,7 +21,8 @@ namespace index { namespace detail {
template <typename Geometry,
typename BoundingGeometry,
typename Tag = typename geometry::tag<Geometry>::type,
- typename BoundingTag = typename geometry::tag<BoundingGeometry>::type>
+ typename BoundingTag = typename geometry::tag<BoundingGeometry>::type,
+ typename CSystem = typename geometry::coordinate_system<Geometry>::type>
struct bounded_view
{
BOOST_MPL_ASSERT_MSG(
@@ -32,7 +35,7 @@ struct bounded_view
// Segment -> Box
template <typename Segment, typename Box>
-struct bounded_view<Segment, Box, segment_tag, box_tag>
+struct bounded_view<Segment, Box, segment_tag, box_tag, cs::cartesian>
{
public:
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
@@ -61,10 +64,37 @@ private:
Segment const& m_segment;
};
+template <typename Segment, typename Box, typename CSystem>
+struct bounded_view<Segment, Box, segment_tag, box_tag, CSystem>
+{
+public:
+ typedef typename geometry::coordinate_type<Box>::type coordinate_type;
+
+ explicit bounded_view(Segment const& segment)
+ {
+ geometry::envelope(segment, m_box);
+ }
+
+ template <std::size_t Dimension>
+ inline coordinate_type get_min() const
+ {
+ return geometry::get<min_corner, Dimension>(m_box);
+ }
+
+ template <std::size_t Dimension>
+ inline coordinate_type get_max() const
+ {
+ return geometry::get<max_corner, Dimension>(m_box);
+ }
+
+private:
+ Box m_box;
+};
+
// Box -> Box
-template <typename BoxIn, typename Box>
-struct bounded_view<BoxIn, Box, box_tag, box_tag>
+template <typename BoxIn, typename Box, typename CSystem>
+struct bounded_view<BoxIn, Box, box_tag, box_tag, CSystem>
{
public:
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
@@ -93,8 +123,8 @@ private:
// Point -> Box
-template <typename Point, typename Box>
-struct bounded_view<Point, Box, point_tag, box_tag>
+template <typename Point, typename Box, typename CSystem>
+struct bounded_view<Point, Box, point_tag, box_tag, CSystem>
{
public:
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
@@ -129,23 +159,23 @@ private:
namespace traits
{
-template <typename Geometry, typename Box, typename Tag>
-struct tag< index::detail::bounded_view<Geometry, Box, Tag, box_tag> >
+template <typename Geometry, typename Box, typename Tag, typename CSystem>
+struct tag< index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> >
{
typedef box_tag type;
};
-template <typename Segment, typename Box, typename Tag>
-struct point_type< index::detail::bounded_view<Segment, Box, Tag, box_tag> >
+template <typename Geometry, typename Box, typename Tag, typename CSystem>
+struct point_type< index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> >
{
typedef typename point_type<Box>::type type;
};
-template <typename Segment, typename Box, typename Tag, std::size_t Dimension>
-struct indexed_access<index::detail::bounded_view<Segment, Box, Tag, box_tag>,
+template <typename Geometry, typename Box, typename Tag, typename CSystem, std::size_t Dimension>
+struct indexed_access<index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem>,
min_corner, Dimension>
{
- typedef index::detail::bounded_view<Segment, Box, Tag, box_tag> box_type;
+ typedef index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> box_type;
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
static inline coordinate_type get(box_type const& b)
@@ -159,11 +189,11 @@ struct indexed_access<index::detail::bounded_view<Segment, Box, Tag, box_tag>,
//}
};
-template <typename Segment, typename Box, typename Tag, std::size_t Dimension>
-struct indexed_access<index::detail::bounded_view<Segment, Box, Tag, box_tag>,
+template <typename Geometry, typename Box, typename Tag, typename CSystem, std::size_t Dimension>
+struct indexed_access<index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem>,
max_corner, Dimension>
{
- typedef index::detail::bounded_view<Segment, Box, Tag, box_tag> box_type;
+ typedef index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> box_type;
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
static inline coordinate_type get(box_type const& b)
diff --git a/boost/geometry/index/detail/predicates.hpp b/boost/geometry/index/detail/predicates.hpp
index 60f80207d8..01afd16ba6 100644
--- a/boost/geometry/index/detail/predicates.hpp
+++ b/boost/geometry/index/detail/predicates.hpp
@@ -25,6 +25,7 @@ namespace predicates {
template <typename Fun, bool IsFunction>
struct satisfies_impl
{
+ satisfies_impl() : fun(NULL) {}
satisfies_impl(Fun f) : fun(f) {}
Fun * fun;
};
@@ -32,6 +33,7 @@ struct satisfies_impl
template <typename Fun>
struct satisfies_impl<Fun, false>
{
+ satisfies_impl() {}
satisfies_impl(Fun const& f) : fun(f) {}
Fun fun;
};
@@ -42,6 +44,7 @@ struct satisfies
{
typedef satisfies_impl<Fun, ::boost::is_function<Fun>::value> base;
+ satisfies() {}
satisfies(Fun const& f) : base(f) {}
satisfies(base const& b) : base(b) {}
};
@@ -60,6 +63,7 @@ struct within_tag {};
template <typename Geometry, typename Tag, bool Negated>
struct spatial_predicate
{
+ spatial_predicate() {}
spatial_predicate(Geometry const& g) : geometry(g) {}
Geometry geometry;
};
@@ -75,6 +79,9 @@ struct spatial_predicate
template <typename PointOrRelation>
struct nearest
{
+ nearest()
+// : count(0)
+ {}
nearest(PointOrRelation const& por, unsigned k)
: point_or_relation(por)
, count(k)
@@ -86,6 +93,9 @@ struct nearest
template <typename SegmentOrLinestring>
struct path
{
+ path()
+// : count(0)
+ {}
path(SegmentOrLinestring const& g, unsigned k)
: geometry(g)
, count(k)
diff --git a/boost/geometry/index/detail/rtree/iterators.hpp b/boost/geometry/index/detail/rtree/iterators.hpp
new file mode 100644
index 0000000000..a47dd7ea43
--- /dev/null
+++ b/boost/geometry/index/detail/rtree/iterators.hpp
@@ -0,0 +1,122 @@
+// Boost.Geometry Index
+//
+// R-tree iterators
+//
+// Copyright (c) 2011-2015 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_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
+
+namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
+
+template <typename Value, typename Allocators>
+struct end_iterator
+{
+ typedef std::forward_iterator_tag iterator_category;
+ typedef Value value_type;
+ typedef typename Allocators::const_reference reference;
+ typedef typename Allocators::difference_type difference_type;
+ typedef typename Allocators::const_pointer pointer;
+
+ reference operator*() const
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not dereferencable");
+ pointer p(0);
+ return *p;
+ }
+
+ const value_type * operator->() const
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not dereferencable");
+ const value_type * p = 0;
+ return p;
+ }
+
+ end_iterator & operator++()
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not incrementable");
+ return *this;
+ }
+
+ end_iterator operator++(int)
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not incrementable");
+ return *this;
+ }
+
+ friend bool operator==(end_iterator const& /*l*/, end_iterator const& /*r*/)
+ {
+ return true;
+ }
+};
+
+template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
+class iterator
+{
+ typedef visitors::iterator<Value, Options, Translator, Box, Allocators> visitor_type;
+ typedef typename visitor_type::node_pointer node_pointer;
+
+public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef Value value_type;
+ typedef typename Allocators::const_reference reference;
+ typedef typename Allocators::difference_type difference_type;
+ typedef typename Allocators::const_pointer pointer;
+
+ inline iterator()
+ {}
+
+ inline iterator(node_pointer root)
+ {
+ m_visitor.initialize(root);
+ }
+
+ reference operator*() const
+ {
+ return m_visitor.dereference();
+ }
+
+ const value_type * operator->() const
+ {
+ return boost::addressof(m_visitor.dereference());
+ }
+
+ iterator & operator++()
+ {
+ m_visitor.increment();
+ return *this;
+ }
+
+ iterator operator++(int)
+ {
+ iterator temp = *this;
+ this->operator++();
+ return temp;
+ }
+
+ friend bool operator==(iterator const& l, iterator const& r)
+ {
+ return l.m_visitor == r.m_visitor;
+ }
+
+ friend bool operator==(iterator const& l, end_iterator<Value, Allocators> const& /*r*/)
+ {
+ return l.m_visitor.is_end();
+ }
+
+ friend bool operator==(end_iterator<Value, Allocators> const& /*l*/, iterator const& r)
+ {
+ return r.m_visitor.is_end();
+ }
+
+private:
+ visitor_type m_visitor;
+};
+
+}}}}}} // namespace boost::geometry::index::detail::rtree::iterators
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
diff --git a/boost/geometry/index/detail/rtree/node/node.hpp b/boost/geometry/index/detail/rtree/node/node.hpp
index 528d473170..b04744c85a 100644
--- a/boost/geometry/index/detail/rtree/node/node.hpp
+++ b/boost/geometry/index/detail/rtree/node/node.hpp
@@ -46,11 +46,7 @@ inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr)
{
Box result;
- if ( first == last )
- {
- geometry::assign_inverse(result);
- return result;
- }
+ BOOST_GEOMETRY_INDEX_ASSERT(first != last, "non-empty range required");
detail::bounds(element_indexable(*first, tr), result);
++first;
diff --git a/boost/geometry/index/detail/rtree/pack_create.hpp b/boost/geometry/index/detail/rtree/pack_create.hpp
index b7be41ab2b..ce07d293db 100644
--- a/boost/geometry/index/detail/rtree/pack_create.hpp
+++ b/boost/geometry/index/detail/rtree/pack_create.hpp
@@ -11,6 +11,9 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_PACK_CREATE_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_PACK_CREATE_HPP
+#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/index/detail/algorithms/bounds.hpp>
+
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree {
namespace pack_utils {
@@ -157,8 +160,7 @@ public:
values_count = static_cast<size_type>(diff);
entries.reserve(values_count);
- Box hint_box;
- geometry::assign_inverse(hint_box);
+ expandable_box<Box> hint_box;
for ( ; first != last ; ++first )
{
// NOTE: support for iterators not returning true references adapted
@@ -172,7 +174,7 @@ public:
// CONSIDER: alternative - ignore invalid indexable or throw an exception
BOOST_GEOMETRY_INDEX_ASSERT(detail::is_valid(indexable), "Indexable is invalid");
- geometry::expand(hint_box, indexable);
+ hint_box.expand(indexable);
point_type pt;
geometry::centroid(indexable, pt);
@@ -180,13 +182,49 @@ public:
}
subtree_elements_counts subtree_counts = calculate_subtree_elements_counts(values_count, parameters, leafs_level);
- internal_element el = per_level(entries.begin(), entries.end(), hint_box, values_count, subtree_counts,
+ internal_element el = per_level(entries.begin(), entries.end(), hint_box.get(), values_count, subtree_counts,
parameters, translator, allocators);
return el.second;
}
private:
+ template <typename BoxType>
+ class expandable_box
+ {
+ public:
+ expandable_box()
+ : m_initialized(false)
+ {}
+
+ template <typename Indexable>
+ void expand(Indexable const& indexable)
+ {
+ if ( !m_initialized )
+ {
+ // it's guaranteed that the Box will be initialized
+ // only for Points, Boxes and Segments but that's ok
+ // since only those Geometries can be stored
+ detail::bounds(indexable, m_box);
+ m_initialized = true;
+ }
+ else
+ {
+ geometry::expand(m_box, indexable);
+ }
+ }
+
+ BoxType const& get() const
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(m_initialized, "uninitialized envelope accessed");
+ return m_box;
+ }
+
+ private:
+ bool m_initialized;
+ BoxType m_box;
+ };
+
struct subtree_elements_counts
{
subtree_elements_counts(std::size_t ma, std::size_t mi) : maxc(ma), minc(mi) {}
@@ -216,19 +254,18 @@ private:
// reserve space for values
rtree::elements(l).reserve(values_count); // MAY THROW (A)
// calculate values box and copy values
- Box elements_box;
- geometry::assign_inverse(elements_box);
+ expandable_box<Box> elements_box;
for ( ; first != last ; ++first )
{
// NOTE: push_back() must be called at the end in order to support move_iterator.
// The iterator is dereferenced 2x (no temporary reference) to support
// non-true reference types and move_iterator without boost::forward<>.
- geometry::expand(elements_box, translator(*(first->second)));
+ elements_box.expand(translator(*(first->second)));
rtree::elements(l).push_back(*(first->second)); // MAY THROW (A?,C)
}
auto_remover.release();
- return internal_element(elements_box, n);
+ return internal_element(elements_box.get(), n);
}
// calculate next max and min subtree counts
@@ -245,23 +282,22 @@ private:
std::size_t nodes_count = calculate_nodes_count(values_count, subtree_counts);
rtree::elements(in).reserve(nodes_count); // MAY THROW (A)
// calculate values box and copy values
- Box elements_box;
- geometry::assign_inverse(elements_box);
-
+ expandable_box<Box> elements_box;
+
per_level_packets(first, last, hint_box, values_count, subtree_counts, next_subtree_counts,
rtree::elements(in), elements_box,
parameters, translator, allocators);
auto_remover.release();
- return internal_element(elements_box, n);
+ return internal_element(elements_box.get(), n);
}
- template <typename EIt> inline static
+ template <typename EIt, typename ExpandableBox> inline static
void per_level_packets(EIt first, EIt last, Box const& hint_box,
std::size_t values_count,
subtree_elements_counts const& subtree_counts,
subtree_elements_counts const& next_subtree_counts,
- internal_elements & elements, Box & elements_box,
+ internal_elements & elements, ExpandableBox & elements_box,
parameters_type const& parameters, Translator const& translator, Allocators & allocators)
{
BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast<std::size_t>(std::distance(first, last)) == values_count,
@@ -285,7 +321,7 @@ private:
elements.push_back(el); // MAY THROW (A?,C) - however in normal conditions shouldn't
auto_remover.release();
- geometry::expand(elements_box, el.first);
+ elements_box.expand(el.first);
return;
}
diff --git a/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp b/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp
index 634d879864..928ffd47d9 100644
--- a/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp
+++ b/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp
@@ -2,7 +2,7 @@
//
// R-tree quadratic split algorithm implementation
//
-// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 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
@@ -57,7 +57,6 @@ inline void pick_seeds(Elements const& elements,
indexable_type const& ind2 = rtree::element_indexable(elements[j], tr);
box_type enlarged_box;
- //geometry::convert(ind1, enlarged_box);
detail::bounds(ind1, enlarged_box);
geometry::expand(enlarged_box, ind2);
@@ -133,9 +132,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
elements2.push_back(elements_copy[seed2]); // MAY THROW, STRONG (alloc, copy)
// calculate boxes
- //geometry::convert(rtree::element_indexable(elements_copy[seed1], translator), box1);
detail::bounds(rtree::element_indexable(elements_copy[seed1], translator), box1);
- //geometry::convert(rtree::element_indexable(elements_copy[seed2], translator), box2);
detail::bounds(rtree::element_indexable(elements_copy[seed2], translator), box2);
// remove seeds
diff --git a/boost/geometry/index/detail/rtree/query_iterators.hpp b/boost/geometry/index/detail/rtree/query_iterators.hpp
index 74000d03ef..83be106b8b 100644
--- a/boost/geometry/index/detail/rtree/query_iterators.hpp
+++ b/boost/geometry/index/detail/rtree/query_iterators.hpp
@@ -20,7 +20,7 @@ namespace boost { namespace geometry { namespace index { namespace detail { name
template <typename Value, typename Allocators>
struct end_query_iterator
{
- typedef std::input_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
@@ -65,12 +65,15 @@ class spatial_query_iterator
typedef typename visitor_type::node_pointer node_pointer;
public:
- typedef std::input_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
+ inline spatial_query_iterator()
+ {}
+
inline spatial_query_iterator(Translator const& t, Predicates const& p)
: m_visitor(t, p)
{}
@@ -130,12 +133,15 @@ class distance_query_iterator
typedef typename visitor_type::node_pointer node_pointer;
public:
- typedef std::input_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
+ inline distance_query_iterator()
+ {}
+
inline distance_query_iterator(Translator const& t, Predicates const& p)
: m_visitor(t, p)
{}
@@ -188,22 +194,19 @@ private:
visitor_type m_visitor;
};
+
template <typename L, typename R>
inline bool operator!=(L const& l, R const& r)
{
return !(l == r);
}
-}}}}}} // namespace boost::geometry::index::detail::rtree::iterators
-
-
-namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
template <typename Value, typename Allocators>
class query_iterator_base
{
public:
- typedef std::input_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
@@ -226,12 +229,13 @@ class query_iterator_wrapper
typedef query_iterator_base<Value, Allocators> base_t;
public:
- typedef std::input_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
+ query_iterator_wrapper() : m_iterator() {}
explicit query_iterator_wrapper(Iterator const& it) : m_iterator(it) {}
virtual base_t * clone() const { return new query_iterator_wrapper(m_iterator); }
@@ -258,13 +262,14 @@ class query_iterator
typedef boost::scoped_ptr<iterator_base> iterator_ptr;
public:
- typedef std::input_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
- query_iterator() {}
+ query_iterator()
+ {}
template <typename It>
query_iterator(It const& it)
diff --git a/boost/geometry/index/detail/rtree/visitors/distance_query.hpp b/boost/geometry/index/detail/rtree/visitors/distance_query.hpp
index fc0929e9ed..b930714433 100644
--- a/boost/geometry/index/detail/rtree/visitors/distance_query.hpp
+++ b/boost/geometry/index/detail/rtree/visitors/distance_query.hpp
@@ -337,6 +337,13 @@ public:
};
typedef std::vector<internal_stack_element> internal_stack_type;
+ inline distance_query_incremental()
+ : m_translator(NULL)
+// , m_pred()
+ , current_neighbor((std::numeric_limits<size_type>::max)())
+// , next_closest_node_distance((std::numeric_limits<node_distance_type>::max)())
+ {}
+
inline distance_query_incremental(Translator const& translator, Predicates const& pred)
: m_translator(::boost::addressof(translator))
, m_pred(pred)
@@ -428,6 +435,7 @@ public:
{
BOOST_GEOMETRY_INDEX_ASSERT(l.current_neighbor != r.current_neighbor ||
(std::numeric_limits<size_type>::max)() == l.current_neighbor ||
+ (std::numeric_limits<size_type>::max)() == r.current_neighbor ||
l.neighbors[l.current_neighbor].second == r.neighbors[r.current_neighbor].second,
"not corresponding iterators");
return l.current_neighbor == r.current_neighbor;
diff --git a/boost/geometry/index/detail/rtree/visitors/iterator.hpp b/boost/geometry/index/detail/rtree/visitors/iterator.hpp
new file mode 100644
index 0000000000..621231ae9a
--- /dev/null
+++ b/boost/geometry/index/detail/rtree/visitors/iterator.hpp
@@ -0,0 +1,134 @@
+// Boost.Geometry Index
+//
+// R-tree iterator visitor implementation
+//
+// Copyright (c) 2011-2015 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_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
+
+namespace boost { namespace geometry { namespace index {
+
+namespace detail { namespace rtree { namespace visitors {
+
+template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
+class iterator
+ : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
+{
+public:
+ typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
+ typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
+ typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
+
+ typedef typename Allocators::size_type size_type;
+ typedef typename Allocators::const_reference const_reference;
+ typedef typename Allocators::node_pointer node_pointer;
+
+ typedef typename rtree::elements_type<internal_node>::type::const_iterator internal_iterator;
+ typedef typename rtree::elements_type<leaf>::type leaf_elements;
+ typedef typename rtree::elements_type<leaf>::type::const_iterator leaf_iterator;
+
+ inline iterator()
+ : m_values(NULL)
+ , m_current()
+ {}
+
+ inline void operator()(internal_node const& n)
+ {
+ typedef typename rtree::elements_type<internal_node>::type elements_type;
+ elements_type const& elements = rtree::elements(n);
+
+ m_internal_stack.push_back(std::make_pair(elements.begin(), elements.end()));
+ }
+
+ inline void operator()(leaf const& n)
+ {
+ m_values = ::boost::addressof(rtree::elements(n));
+ m_current = rtree::elements(n).begin();
+ }
+
+ const_reference dereference() const
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(m_values, "not dereferencable");
+ return *m_current;
+ }
+
+ void initialize(node_pointer root)
+ {
+ rtree::apply_visitor(*this, *root);
+ search_value();
+ }
+
+ void increment()
+ {
+ ++m_current;
+ search_value();
+ }
+
+ void search_value()
+ {
+ for (;;)
+ {
+ // if leaf is choosen, move to the next value in leaf
+ if ( m_values )
+ {
+ // there are more values in the current leaf
+ if ( m_current != m_values->end() )
+ {
+ return;
+ }
+ // no more values, clear current leaf
+ else
+ {
+ m_values = 0;
+ }
+ }
+ // if leaf isn't choosen, move to the next leaf
+ else
+ {
+ // return if there is no more nodes to traverse
+ if ( m_internal_stack.empty() )
+ return;
+
+ // no more children in current node, remove it from stack
+ if ( m_internal_stack.back().first == m_internal_stack.back().second )
+ {
+ m_internal_stack.pop_back();
+ continue;
+ }
+
+ internal_iterator it = m_internal_stack.back().first;
+ ++m_internal_stack.back().first;
+
+ // push the next node to the stack
+ rtree::apply_visitor(*this, *(it->second));
+ }
+ }
+ }
+
+ bool is_end() const
+ {
+ return 0 == m_values;
+ }
+
+ friend bool operator==(iterator const& l, iterator const& r)
+ {
+ return (l.m_values == r.m_values) && (0 == l.m_values || l.m_current == r.m_current );
+ }
+
+private:
+
+ std::vector< std::pair<internal_iterator, internal_iterator> > m_internal_stack;
+ const leaf_elements * m_values;
+ leaf_iterator m_current;
+};
+
+}}} // namespace detail::rtree::visitors
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
diff --git a/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp b/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp
index f00189fe77..b9cd0ae2c0 100644
--- a/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp
+++ b/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp
@@ -94,10 +94,18 @@ public:
static const unsigned predicates_len = index::detail::predicates_length<Predicates>::value;
+ inline spatial_query_incremental()
+ : m_translator(NULL)
+// , m_pred()
+ , m_values(NULL)
+ , m_current()
+ {}
+
inline spatial_query_incremental(Translator const& t, Predicates const& p)
: m_translator(::boost::addressof(t))
, m_pred(p)
- , m_values(0)
+ , m_values(NULL)
+ , m_current()
{}
inline void operator()(internal_node const& n)
diff --git a/boost/geometry/index/rtree.hpp b/boost/geometry/index/rtree.hpp
index 9d5d57d059..84c4da8a2a 100644
--- a/boost/geometry/index/rtree.hpp
+++ b/boost/geometry/index/rtree.hpp
@@ -59,6 +59,7 @@
#include <boost/geometry/index/detail/algorithms/is_valid.hpp>
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
+#include <boost/geometry/index/detail/rtree/visitors/iterator.hpp>
#include <boost/geometry/index/detail/rtree/visitors/remove.hpp>
#include <boost/geometry/index/detail/rtree/visitors/copy.hpp>
#include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
@@ -78,6 +79,7 @@
#include <boost/geometry/index/detail/rtree/utilities/view.hpp>
+#include <boost/geometry/index/detail/rtree/iterators.hpp>
#include <boost/geometry/index/detail/rtree/query_iterators.hpp>
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
@@ -220,8 +222,17 @@ public:
/*! \brief Unsigned integral type used by the container. */
typedef typename allocators_type::size_type size_type;
- /*! \brief Type of const query iterator. */
- typedef index::detail::rtree::iterators::query_iterator<value_type, allocators_type> const_query_iterator;
+ /*! \brief Type of const iterator, category ForwardIterator. */
+ typedef index::detail::rtree::iterators::iterator
+ <
+ value_type, options_type, translator_type, box_type, allocators_type
+ > const_iterator;
+
+ /*! \brief Type of const query iterator, category ForwardIterator. */
+ typedef index::detail::rtree::iterators::query_iterator
+ <
+ value_type, allocators_type
+ > const_query_iterator;
public:
@@ -766,6 +777,27 @@ public:
tree.query(bgi::overlaps(box) && bgi::satisfies(my_fun), std::back_inserter(result));
// return 5 elements nearest to pt and elements are intersecting box
tree.query(bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
+
+ // For each found value do_something (it is a type of function object)
+ tree.query(bgi::intersects(box),
+ boost::make_function_output_iterator(do_something()));
+
+ // For each value stored in the rtree do_something
+ // always_true is a type of function object always returning true
+ tree.query(bgi::satisfies(always_true()),
+ boost::make_function_output_iterator(do_something()));
+
+ // C++11 (lambda expression)
+ tree.query(bgi::intersects(box),
+ boost::make_function_output_iterator([](value_type const& val){
+ // do something
+ }));
+
+ // C++14 (generic lambda expression)
+ tree.query(bgi::intersects(box),
+ boost::make_function_output_iterator([](auto const& val){
+ // do something
+ }));
\endverbatim
\par Throws
@@ -774,7 +806,7 @@ public:
\warning
Only one \c nearest() perdicate may be passed to the query. Passing more of them results in compile-time error.
-
+
\param predicates Predicates.
\param out_it The output iterator, e.g. generated by std::back_inserter().
@@ -794,11 +826,11 @@ public:
}
/*!
- \brief Returns the query iterator pointing at the begin of the query range.
+ \brief Returns a query iterator pointing at the begin of the query range.
+
+ This method returns an iterator which may be used to perform iterative queries.
+ For the information about predicates which may be passed to this method see query().
- This method returns the iterator which may be used to perform iterative queries. For the information
- about the predicates which may be passed to this method see query().
-
\par Example
\verbatim
for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
@@ -808,12 +840,29 @@ public:
if ( has_enough_nearest_values() )
break;
}
+
+ // C++11 (auto)
+ for ( auto it = tree.qbegin(bgi::nearest(pt, 3)) ; it != tree.qend() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++14 (generic lambda expression)
+ std::for_each(tree.qbegin(bgi::nearest(pt, 3)), tree.qend(), [](auto const& val){
+ // do something with value
+ });
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
If predicates copy throws.
If allocation throws.
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
\param predicates Predicates.
\return The iterator pointing at the begin of the query range.
@@ -825,10 +874,10 @@ public:
}
/*!
- \brief Returns the query iterator pointing at the end of the query range.
+ \brief Returns a query iterator pointing at the end of the query range.
+
+ This method returns an iterator which may be used to check if the query has ended.
- This method returns the iterator which may be used to check if the query has ended.
-
\par Example
\verbatim
for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
@@ -838,10 +887,27 @@ public:
if ( has_enough_nearest_values() )
break;
}
+
+ // C++11 (auto)
+ for ( auto it = tree.qbegin(bgi::nearest(pt, 3)) ; it != tree.qend() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++14 (generic lambda expression)
+ std::for_each(tree.qbegin(bgi::nearest(pt, 3)), tree.qend(), [](auto const& val){
+ // do something with value
+ });
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
Nothing
+
+ \warning
+ The modification of the rtree may invalidate the iterators.
\return The iterator pointing at the end of the query range.
*/
@@ -854,10 +920,10 @@ public:
private:
#endif
/*!
- \brief Returns the query iterator pointing at the begin of the query range.
+ \brief Returns a query iterator pointing at the begin of the query range.
- This method returns the iterator which may be used to perform iterative queries. For the information
- about the predicates which may be passed to this method see query().
+ This method returns an iterator which may be used to perform iterative queries.
+ For the information about predicates which may be passed to this method see query().
The type of the returned iterator depends on the type of passed Predicates but the iterator of this type
may be assigned to the variable of const_query_iterator type. If you'd like to use the type of the iterator
@@ -867,16 +933,24 @@ private:
\par Example
\verbatim
// Store the result in the container using std::copy() - it requires both iterators of the same type
- std::copy(tree.qbegin(bgi::intersects(box)), tree.qend(bgi::intersects(box)), std::back_inserter(result));
+ std::copy(tree.qbegin_(bgi::intersects(box)), tree.qend_(bgi::intersects(box)), std::back_inserter(result));
// Store the result in the container using std::copy() and type-erased iterators
- Rtree::const_query_iterator first = tree.qbegin(bgi::intersects(box));
- Rtree::const_query_iterator last = tree.qend();
+ Rtree::const_query_iterator first = tree.qbegin_(bgi::intersects(box));
+ Rtree::const_query_iterator last = tree.qend_();
std::copy(first, last, std::back_inserter(result));
// Boost.Typeof
typedef BOOST_TYPEOF(tree.qbegin(bgi::nearest(pt, 10000))) Iter;
- for ( Iter it = tree.qbegin(bgi::nearest(pt, 10000)) ; it != tree.qend() ; ++it )
+ for ( Iter it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
+ {
+ // do something with value
+ if ( has_enough_nearest_values() )
+ break;
+ }
+
+ // C++11 (auto)
+ for ( auto it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
{
// do something with value
if ( has_enough_nearest_values() )
@@ -884,10 +958,16 @@ private:
}
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
If predicates copy throws.
If allocation throws.
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
\param predicates Predicates.
\return The iterator pointing at the begin of the query range.
@@ -937,12 +1017,18 @@ private:
\par Example
\verbatim
// Store the result in the container using std::copy() - it requires both iterators of the same type
- std::copy(tree.qbegin(bgi::intersects(box)), tree.qend(bgi::intersects(box)), std::back_inserter(result));
+ std::copy(tree.qbegin_(bgi::intersects(box)), tree.qend_(bgi::intersects(box)), std::back_inserter(result));
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
If predicates copy throws.
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
\param predicates Predicates.
\return The iterator pointing at the end of the query range.
@@ -989,13 +1075,21 @@ private:
\par Example
\verbatim
// Store the result in the container using std::copy() and type-erased iterators
- Rtree::const_query_iterator first = tree.qbegin(bgi::intersects(box));
- Rtree::const_query_iterator last = tree.qend();
+ Rtree::const_query_iterator first = tree.qbegin_(bgi::intersects(box));
+ Rtree::const_query_iterator last = tree.qend_();
std::copy(first, last, std::back_inserter(result));
// Boost.Typeof
typedef BOOST_TYPEOF(tree.qbegin(bgi::nearest(pt, 10000))) Iter;
- for ( Iter it = tree.qbegin(bgi::nearest(pt, 10000)) ; it != tree.qend() ; ++it )
+ for ( Iter it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
+ {
+ // do something with value
+ if ( has_enough_nearest_values() )
+ break;
+ }
+
+ // C++11 (auto)
+ for ( auto it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
{
// do something with value
if ( has_enough_nearest_values() )
@@ -1003,8 +1097,14 @@ private:
}
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
Nothing
+
+ \warning
+ The modification of the rtree may invalidate the iterators.
\return The iterator pointing at the end of the query range.
*/
@@ -1017,6 +1117,88 @@ private:
public:
/*!
+ \brief Returns the iterator pointing at the begin of the rtree values range.
+
+ This method returns the iterator which may be used to iterate over all values
+ stored in the rtree.
+
+ \par Example
+ \verbatim
+ // Copy all values into the vector
+ std::copy(tree.begin(), tree.end(), std::back_inserter(vec));
+
+ for ( Rtree::const_iterator it = tree.begin() ; it != tree.end() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++11 (auto)
+ for ( auto it = tree.begin() ; it != tree.end() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++14 (generic lambda expression)
+ std::for_each(tree.begin(), tree.end(), [](auto const& val){
+ // do something with value
+ })
+ \endverbatim
+
+ \par Iterator category
+ ForwardIterator
+
+ \par Throws
+ If allocation throws.
+
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
+ \return The iterator pointing at the begin of the range.
+ */
+ const_iterator begin() const
+ {
+ if ( !m_members.root )
+ return const_iterator();
+
+ return const_iterator(m_members.root);
+ }
+
+ /*!
+ \brief Returns the iterator pointing at the end of the rtree values range.
+
+ This method returns the iterator which may be compared with the iterator returned by begin()
+ in order to check if the iteration has ended.
+
+ \par Example
+ \verbatim
+ for ( Rtree::const_iterator it = tree.begin() ; it != tree.end() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++11 (lambda expression)
+ std::for_each(tree.begin(), tree.end(), [](value_type const& val){
+ // do something with value
+ })
+ \endverbatim
+
+ \par Iterator category
+ ForwardIterator
+
+ \par Throws
+ Nothing.
+
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
+ \return The iterator pointing at the end of the range.
+ */
+ const_iterator end() const
+ {
+ return const_iterator();
+ }
+
+ /*!
\brief Returns the number of stored values.
\return The number of stored values.
@@ -1763,6 +1945,10 @@ bgi::query(tree, bgi::intersects(poly) && !bgi::within(box), std::back_inserter(
bgi::query(tree, bgi::overlaps(box) && bgi::satisfies(my_fun), std::back_inserter(result));
// return 5 elements nearest to pt and elements are intersecting box
bgi::query(tree, bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
+
+// For each found value do_something (it is a type of function object)
+tree.query(bgi::intersects(box),
+ boost::make_function_output_iterator(do_something()));
\endverbatim
\par Throws
@@ -1797,20 +1983,19 @@ about the predicates which may be passed to this method see query().
\par Example
\verbatim
-
-for ( Rtree::const_query_iterator it = qbegin(tree, bgi::nearest(pt, 10000)) ;
- it != qend(tree) ; ++it )
-{
- // do something with value
- if ( has_enough_nearest_values() )
- break;
-}
+std::for_each(bgi::qbegin(tree, bgi::nearest(pt, 3)), bgi::qend(tree), do_something());
\endverbatim
+\par Iterator category
+ForwardIterator
+
\par Throws
If predicates copy throws.
If allocation throws.
+\warning
+The modification of the rtree may invalidate the iterators.
+
\ingroup rtree_functions
\param tree The rtree.
@@ -1834,19 +2019,18 @@ This method returns the iterator which may be used to check if the query has end
\par Example
\verbatim
-
-for ( Rtree::const_query_iterator it = qbegin(tree, bgi::nearest(pt, 10000)) ;
- it != qend(tree) ; ++it )
-{
- // do something with value
- if ( has_enough_nearest_values() )
- break;
-}
+std::for_each(bgi::qbegin(tree, bgi::nearest(pt, 3)), bgi::qend(tree), do_something());
\endverbatim
+\par Iterator category
+ForwardIterator
+
\par Throws
Nothing
+\warning
+The modification of the rtree may invalidate the iterators.
+
\ingroup rtree_functions
\return The iterator pointing at the end of the query range.
@@ -1859,6 +2043,72 @@ qend(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
}
/*!
+\brief Returns the iterator pointing at the begin of the rtree values range.
+
+This method returns the iterator which may be used to iterate over all values
+stored in the rtree.
+
+\par Example
+\verbatim
+std::for_each(bgi::begin(tree), bgi::end(tree), do_something());
+// the same as
+std::for_each(boost::begin(tree), boost::end(tree), do_something());
+\endverbatim
+
+\par Iterator category
+ForwardIterator
+
+\par Throws
+If allocation throws.
+
+\warning
+The modification of the rtree may invalidate the iterators.
+
+\ingroup rtree_functions
+
+\return The iterator pointing at the begin of the range.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator> inline
+typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_iterator
+begin(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
+{
+ return tree.begin();
+}
+
+/*!
+\brief Returns the iterator pointing at the end of the rtree values range.
+
+This method returns the iterator which may be compared with the iterator returned by begin()
+in order to check if the iteration has ended.
+
+\par Example
+\verbatim
+std::for_each(bgi::begin(tree), bgi::end(tree), do_something());
+// the same as
+std::for_each(boost::begin(tree), boost::end(tree), do_something());
+\endverbatim
+
+\par Iterator category
+ForwardIterator
+
+\par Throws
+Nothing.
+
+\warning
+The modification of the rtree may invalidate the iterators.
+
+\ingroup rtree_functions
+
+\return The iterator pointing at the end of the range.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator> inline
+typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_iterator
+end(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
+{
+ return tree.end();
+}
+
+/*!
\brief Remove all values from the index.
It calls \c rtree::clear().
@@ -1944,6 +2194,23 @@ inline void swap(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> &
}}} // namespace boost::geometry::index
+// Boost.Range adaptation
+namespace boost {
+
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
+struct range_mutable_iterator
+ <
+ boost::geometry::index::rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>
+ >
+{
+ typedef typename boost::geometry::index::rtree
+ <
+ Value, Parameters, IndexableGetter, EqualTo, Allocator
+ >::const_iterator type;
+};
+
+} // namespace boost
+
// TODO: don't include the implementation at the end of the file
#include <boost/geometry/algorithms/detail/comparable_distance/implementation.hpp>
diff --git a/boost/geometry/io/svg/svg_mapper.hpp b/boost/geometry/io/svg/svg_mapper.hpp
index b53fef2ceb..c8e63d5ab7 100644
--- a/boost/geometry/io/svg/svg_mapper.hpp
+++ b/boost/geometry/io/svg/svg_mapper.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -16,6 +21,7 @@
#include <vector>
+#include <boost/config.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
@@ -31,15 +37,11 @@
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/transform.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
-#include <boost/geometry/strategies/transform.hpp>
#include <boost/geometry/strategies/transform/map_transformer.hpp>
#include <boost/geometry/views/segment_view.hpp>
-#include <boost/geometry/multi/algorithms/envelope.hpp>
-#include <boost/geometry/multi/algorithms/num_points.hpp>
-
#include <boost/geometry/io/svg/write_svg.hpp>
// Helper geometries (all points are transformed to integer-points)
@@ -97,6 +99,11 @@ struct svg_map<box_tag, Box>
Box const& box, TransformStrategy const& strategy)
{
model::box<detail::svg::svg_point_type> ibox;
+
+ // Fix bug in gcc compiler warning for possible uninitialation
+#if defined(BOOST_GCC)
+ geometry::assign_zero(ibox);
+#endif
geometry::transform(box, ibox, strategy);
stream << geometry::svg(ibox, style, size) << std::endl;
@@ -307,7 +314,7 @@ public :
template <typename Geometry>
void add(Geometry const& geometry)
{
- if (num_points(geometry) > 0)
+ if (! geometry::is_empty(geometry))
{
expand(m_bounding_box,
return_envelope
diff --git a/boost/geometry/io/wkt/read.hpp b/boost/geometry/io/wkt/read.hpp
index 2415f21a69..a39c8f89d4 100644
--- a/boost/geometry/io/wkt/read.hpp
+++ b/boost/geometry/io/wkt/read.hpp
@@ -4,8 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -64,7 +64,9 @@ struct read_wkt_exception : public geometry::exception
{
template <typename Iterator>
read_wkt_exception(std::string const& msg,
- Iterator const& it, Iterator const& end, std::string const& wkt)
+ Iterator const& it,
+ Iterator const& end,
+ std::string const& wkt)
: message(msg)
, wkt(wkt)
{
@@ -110,8 +112,10 @@ template <typename Point,
std::size_t DimensionCount = geometry::dimension<Point>::value>
struct parsing_assigner
{
- static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
- Point& point, std::string const& wkt)
+ static inline void apply(tokenizer::iterator& it,
+ tokenizer::iterator const& end,
+ Point& point,
+ std::string const& wkt)
{
typedef typename coordinate_type<Point>::type coordinate_type;
@@ -151,8 +155,10 @@ struct parsing_assigner
template <typename Point, std::size_t DimensionCount>
struct parsing_assigner<Point, DimensionCount, DimensionCount>
{
- static inline void apply(tokenizer::iterator&, tokenizer::iterator, Point&,
- std::string const&)
+ static inline void apply(tokenizer::iterator&,
+ tokenizer::iterator const&,
+ Point&,
+ std::string const&)
{
}
};
@@ -161,7 +167,8 @@ struct parsing_assigner<Point, DimensionCount, DimensionCount>
template <typename Iterator>
inline void handle_open_parenthesis(Iterator& it,
- Iterator const& end, std::string const& wkt)
+ Iterator const& end,
+ std::string const& wkt)
{
if (it == end || *it != "(")
{
@@ -173,7 +180,8 @@ inline void handle_open_parenthesis(Iterator& it,
template <typename Iterator>
inline void handle_close_parenthesis(Iterator& it,
- Iterator const& end, std::string const& wkt)
+ Iterator const& end,
+ std::string const& wkt)
{
if (it != end && *it == ")")
{
@@ -187,7 +195,8 @@ inline void handle_close_parenthesis(Iterator& it,
template <typename Iterator>
inline void check_end(Iterator& it,
- Iterator const& end, std::string const& wkt)
+ Iterator const& end,
+ std::string const& wkt)
{
if (it != end)
{
@@ -206,8 +215,10 @@ struct container_inserter
{
// Version with output iterator
template <typename OutputIterator>
- static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
- std::string const& wkt, OutputIterator out)
+ static inline void apply(tokenizer::iterator& it,
+ tokenizer::iterator const& end,
+ std::string const& wkt,
+ OutputIterator out)
{
handle_open_parenthesis(it, end, wkt);
@@ -300,8 +311,10 @@ struct container_appender
{
typedef typename geometry::point_type<Geometry>::type point_type;
- static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
- std::string const& wkt, Geometry out)
+ static inline void apply(tokenizer::iterator& it,
+ tokenizer::iterator const& end,
+ std::string const& wkt,
+ Geometry out)
{
handle_open_parenthesis(it, end, wkt);
@@ -335,8 +348,10 @@ struct container_appender
template <typename P>
struct point_parser
{
- static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
- std::string const& wkt, P& point)
+ static inline void apply(tokenizer::iterator& it,
+ tokenizer::iterator const& end,
+ std::string const& wkt,
+ P& point)
{
handle_open_parenthesis(it, end, wkt);
parsing_assigner<P>::apply(it, end, point, wkt);
@@ -348,8 +363,10 @@ struct point_parser
template <typename Geometry>
struct linestring_parser
{
- static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
- std::string const& wkt, Geometry& geometry)
+ static inline void apply(tokenizer::iterator& it,
+ tokenizer::iterator const& end,
+ std::string const& wkt,
+ Geometry& geometry)
{
container_appender<Geometry&>::apply(it, end, wkt, geometry);
}
@@ -359,8 +376,10 @@ struct linestring_parser
template <typename Ring>
struct ring_parser
{
- static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
- std::string const& wkt, Ring& ring)
+ static inline void apply(tokenizer::iterator& it,
+ tokenizer::iterator const& end,
+ std::string const& wkt,
+ Ring& ring)
{
// A ring should look like polygon((x y,x y,x y...))
// So handle the extra opening/closing parentheses
@@ -382,8 +401,10 @@ struct polygon_parser
typedef typename ring_return_type<Polygon>::type ring_return_type;
typedef container_appender<ring_return_type> appender;
- static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
- std::string const& wkt, Polygon& poly)
+ static inline void apply(tokenizer::iterator& it,
+ tokenizer::iterator const& end,
+ std::string const& wkt,
+ Polygon& poly)
{
handle_open_parenthesis(it, end, wkt);
@@ -423,8 +444,9 @@ struct polygon_parser
};
-inline bool one_of(tokenizer::iterator const& it, std::string const& value,
- bool& is_present)
+inline bool one_of(tokenizer::iterator const& it,
+ std::string const& value,
+ bool& is_present)
{
if (boost::iequals(*it, value))
{
@@ -434,8 +456,10 @@ inline bool one_of(tokenizer::iterator const& it, std::string const& value,
return false;
}
-inline bool one_of(tokenizer::iterator const& it, std::string const& value,
- bool& present1, bool& present2)
+inline bool one_of(tokenizer::iterator const& it,
+ std::string const& value,
+ bool& present1,
+ bool& present2)
{
if (boost::iequals(*it, value))
{
@@ -447,8 +471,11 @@ inline bool one_of(tokenizer::iterator const& it, std::string const& value,
}
-inline void handle_empty_z_m(tokenizer::iterator& it, tokenizer::iterator end,
- bool& has_empty, bool& has_z, bool& has_m)
+inline void handle_empty_z_m(tokenizer::iterator& it,
+ tokenizer::iterator const& end,
+ bool& has_empty,
+ bool& has_z,
+ bool& has_m)
{
has_empty = false;
has_z = false;
@@ -478,15 +505,18 @@ inline void handle_empty_z_m(tokenizer::iterator& it, tokenizer::iterator end,
*/
template <typename Geometry>
inline bool initialize(tokenizer const& tokens,
- std::string const& geometry_name, std::string const& wkt,
- tokenizer::iterator& it)
+ std::string const& geometry_name,
+ std::string const& wkt,
+ tokenizer::iterator& it,
+ tokenizer::iterator& end)
{
it = tokens.begin();
- if (it != tokens.end() && boost::iequals(*it++, geometry_name))
+ end = tokens.end();
+ if (it != end && boost::iequals(*it++, geometry_name))
{
bool has_empty, has_z, has_m;
- handle_empty_z_m(it, tokens.end(), has_empty, has_z, has_m);
+ handle_empty_z_m(it, end, has_empty, has_z, has_m);
// Silence warning C4127: conditional expression is constant
#if defined(_MSC_VER)
@@ -505,7 +535,7 @@ inline bool initialize(tokenizer const& tokens,
if (has_empty)
{
- check_end(it, tokens.end(), wkt);
+ check_end(it, end, wkt);
return false;
}
// M is ignored at all.
@@ -524,11 +554,11 @@ struct geometry_parser
geometry::clear(geometry);
tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
- tokenizer::iterator it;
- if (initialize<Geometry>(tokens, PrefixPolicy::apply(), wkt, it))
+ tokenizer::iterator it, end;
+ if (initialize<Geometry>(tokens, PrefixPolicy::apply(), wkt, it, end))
{
- Parser<Geometry>::apply(it, tokens.end(), wkt, geometry);
- check_end(it, tokens.end(), wkt);
+ Parser<Geometry>::apply(it, end, wkt, geometry);
+ check_end(it, end, wkt);
}
}
};
@@ -542,38 +572,40 @@ struct multi_parser
traits::clear<MultiGeometry>::apply(geometry);
tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
- tokenizer::iterator it;
- if (initialize<MultiGeometry>(tokens, PrefixPolicy::apply(), wkt, it))
+ tokenizer::iterator it, end;
+ if (initialize<MultiGeometry>(tokens, PrefixPolicy::apply(), wkt, it, end))
{
- handle_open_parenthesis(it, tokens.end(), wkt);
+ handle_open_parenthesis(it, end, wkt);
// Parse sub-geometries
- while(it != tokens.end() && *it != ")")
+ while(it != end && *it != ")")
{
traits::resize<MultiGeometry>::apply(geometry, boost::size(geometry) + 1);
Parser
<
typename boost::range_value<MultiGeometry>::type
- >::apply(it, tokens.end(), wkt, *(boost::end(geometry) - 1));
- if (it != tokens.end() && *it == ",")
+ >::apply(it, end, wkt, *(boost::end(geometry) - 1));
+ if (it != end && *it == ",")
{
// Skip "," after multi-element is parsed
++it;
}
}
- handle_close_parenthesis(it, tokens.end(), wkt);
+ handle_close_parenthesis(it, end, wkt);
}
- check_end(it, tokens.end(), wkt);
+ check_end(it, end, wkt);
}
};
template <typename P>
struct noparenthesis_point_parser
{
- static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
- std::string const& wkt, P& point)
+ static inline void apply(tokenizer::iterator& it,
+ tokenizer::iterator const& end,
+ std::string const& wkt,
+ P& point)
{
parsing_assigner<P>::apply(it, end, point, wkt);
}
@@ -587,17 +619,17 @@ struct multi_point_parser
traits::clear<MultiGeometry>::apply(geometry);
tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
- tokenizer::iterator it;
+ tokenizer::iterator it, end;
- if (initialize<MultiGeometry>(tokens, PrefixPolicy::apply(), wkt, it))
+ if (initialize<MultiGeometry>(tokens, PrefixPolicy::apply(), wkt, it, end))
{
- handle_open_parenthesis(it, tokens.end(), wkt);
+ handle_open_parenthesis(it, end, wkt);
// If first point definition starts with "(" then parse points as (x y)
// otherwise as "x y"
- bool using_brackets = (it != tokens.end() && *it == "(");
+ bool using_brackets = (it != end && *it == "(");
- while(it != tokens.end() && *it != ")")
+ while(it != end && *it != ")")
{
traits::resize<MultiGeometry>::apply(geometry, boost::size(geometry) + 1);
@@ -606,27 +638,27 @@ struct multi_point_parser
point_parser
<
typename boost::range_value<MultiGeometry>::type
- >::apply(it, tokens.end(), wkt, *(boost::end(geometry) - 1));
+ >::apply(it, end, wkt, *(boost::end(geometry) - 1));
}
else
{
noparenthesis_point_parser
<
typename boost::range_value<MultiGeometry>::type
- >::apply(it, tokens.end(), wkt, *(boost::end(geometry) - 1));
+ >::apply(it, end, wkt, *(boost::end(geometry) - 1));
}
- if (it != tokens.end() && *it == ",")
+ if (it != end && *it == ",")
{
// Skip "," after point is parsed
++it;
}
}
- handle_close_parenthesis(it, tokens.end(), wkt);
+ handle_close_parenthesis(it, end, wkt);
}
- check_end(it, tokens.end(), wkt);
+ check_end(it, end, wkt);
}
};
diff --git a/boost/geometry/io/wkt/write.hpp b/boost/geometry/io/wkt/write.hpp
index add40e2551..a556aa440f 100644
--- a/boost/geometry/io/wkt/write.hpp
+++ b/boost/geometry/io/wkt/write.hpp
@@ -1,9 +1,14 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -28,7 +33,7 @@
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/convert.hpp>
-#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
@@ -150,7 +155,7 @@ struct wkt_range
// optionally, close range to ring by repeating the first point
if (force_closed
&& boost::size(range) > 1
- && geometry::disjoint(*begin, *(end - 1)))
+ && detail::disjoint::disjoint_point_point(*begin, *(end - 1)))
{
os << ",";
stream_type::apply(os, *begin);
@@ -444,7 +449,7 @@ struct devarianted_wkt<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry
)
{
- apply_visitor(visitor<OutputStream>(os), geometry);
+ boost::apply_visitor(visitor<OutputStream>(os), geometry);
}
};
diff --git a/boost/geometry/iterators/concatenate_iterator.hpp b/boost/geometry/iterators/concatenate_iterator.hpp
index 5c4ae0af1e..ea5728d0bc 100644
--- a/boost/geometry/iterators/concatenate_iterator.hpp
+++ b/boost/geometry/iterators/concatenate_iterator.hpp
@@ -10,7 +10,6 @@
#ifndef BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP
#define BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP
-#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/iterator.hpp>
diff --git a/boost/geometry/iterators/detail/segment_iterator/value_type.hpp b/boost/geometry/iterators/detail/segment_iterator/value_type.hpp
index 0b3c66670c..ff3267c884 100644
--- a/boost/geometry/iterators/detail/segment_iterator/value_type.hpp
+++ b/boost/geometry/iterators/detail/segment_iterator/value_type.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -10,7 +10,14 @@
#ifndef BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_VALUE_TYPE_HPP
#define BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_VALUE_TYPE_HPP
-#include <boost/geometry/iterators/detail/point_iterator/value_type.hpp>
+#include <iterator>
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_reference.hpp>
+
+#include <boost/geometry/iterators/point_iterator.hpp>
+#include <boost/geometry/util/bare_type.hpp>
+#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/geometries/pointing_segment.hpp>
@@ -24,15 +31,36 @@ namespace detail { namespace segment_iterator
template <typename Geometry>
struct value_type
{
+ typedef typename std::iterator_traits
+ <
+ geometry::point_iterator<Geometry>
+ >::reference point_iterator_reference_type;
+
typedef typename detail::point_iterator::value_type
<
Geometry
>::type point_iterator_value_type;
- typedef geometry::model::pointing_segment
+ // If the reference type of the point iterator is not really a
+ // reference, then dereferencing a point iterator would create
+ // a temporary object.
+ // In this case using a pointing_segment to represent the
+ // dereferenced value of the segment iterator cannot be used, as
+ // it would store pointers to temporary objects. Instead we use a
+ // segment, which does a full copy of the temporary objects
+ // returned by the point iterator.
+ typedef typename boost::mpl::if_
<
- point_iterator_value_type
- > type;
+ boost::is_reference<point_iterator_reference_type>,
+ geometry::model::pointing_segment<point_iterator_value_type>,
+ geometry::model::segment
+ <
+ typename geometry::util::bare_type
+ <
+ point_iterator_value_type
+ >::type
+ >
+ >::type type;
};
}} // namespace detail::segment_iterator
diff --git a/boost/geometry/iterators/flatten_iterator.hpp b/boost/geometry/iterators/flatten_iterator.hpp
index 07450afbea..5ba7050220 100644
--- a/boost/geometry/iterators/flatten_iterator.hpp
+++ b/boost/geometry/iterators/flatten_iterator.hpp
@@ -10,13 +10,13 @@
#ifndef BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP
#define BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP
-#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_categories.hpp>
+#include <boost/geometry/core/assert.hpp>
namespace boost { namespace geometry
{
@@ -154,8 +154,8 @@ private:
inline Reference dereference() const
{
- BOOST_ASSERT( m_outer_it != m_outer_end );
- BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
+ BOOST_GEOMETRY_ASSERT( m_outer_it != m_outer_end );
+ BOOST_GEOMETRY_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
return *m_inner_it;
}
@@ -194,8 +194,8 @@ private:
inline void increment()
{
- BOOST_ASSERT( m_outer_it != m_outer_end );
- BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
+ BOOST_GEOMETRY_ASSERT( m_outer_it != m_outer_end );
+ BOOST_GEOMETRY_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
++m_inner_it;
if ( m_inner_it == AccessInnerEnd::apply(*m_outer_it) )
@@ -215,12 +215,9 @@ private:
--m_outer_it;
}
while ( empty(m_outer_it) );
- m_inner_it = --AccessInnerEnd::apply(*m_outer_it);
- }
- else
- {
- --m_inner_it;
- }
+ m_inner_it = AccessInnerEnd::apply(*m_outer_it);
+ }
+ --m_inner_it;
}
};
diff --git a/boost/geometry/iterators/point_iterator.hpp b/boost/geometry/iterators/point_iterator.hpp
index 5971cfcef0..5ee0e54917 100644
--- a/boost/geometry/iterators/point_iterator.hpp
+++ b/boost/geometry/iterators/point_iterator.hpp
@@ -10,7 +10,6 @@
#ifndef BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP
#define BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP
-#include <boost/assert.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
diff --git a/boost/geometry/multi/multi.hpp b/boost/geometry/multi/multi.hpp
index 4b3063e520..85d763ee6e 100644
--- a/boost/geometry/multi/multi.hpp
+++ b/boost/geometry/multi/multi.hpp
@@ -1,11 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2013.
-// Modifications copyright (c) 2013, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2015.
+// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -17,65 +17,8 @@
#ifndef BOOST_GEOMETRY_MULTI_HPP
#define BOOST_GEOMETRY_MULTI_HPP
-
-#include <boost/geometry/core/closure.hpp>
-#include <boost/geometry/core/geometry_id.hpp>
-#include <boost/geometry/core/interior_rings.hpp>
-#include <boost/geometry/core/is_areal.hpp>
-#include <boost/geometry/core/point_order.hpp>
-#include <boost/geometry/core/point_type.hpp>
-#include <boost/geometry/core/ring_type.hpp>
-#include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/core/topological_dimension.hpp>
-
-#include <boost/geometry/algorithms/append.hpp>
-#include <boost/geometry/algorithms/area.hpp>
-#include <boost/geometry/algorithms/centroid.hpp>
-#include <boost/geometry/algorithms/clear.hpp>
-#include <boost/geometry/algorithms/convert.hpp>
-#include <boost/geometry/algorithms/correct.hpp>
-#include <boost/geometry/algorithms/covered_by.hpp>
-#include <boost/geometry/algorithms/disjoint.hpp>
-#include <boost/geometry/algorithms/distance.hpp>
-#include <boost/geometry/algorithms/envelope.hpp>
-#include <boost/geometry/algorithms/equals.hpp>
-#include <boost/geometry/algorithms/for_each.hpp>
-#include <boost/geometry/algorithms/intersection.hpp>
-#include <boost/geometry/algorithms/length.hpp>
-#include <boost/geometry/algorithms/num_geometries.hpp>
-#include <boost/geometry/algorithms/num_interior_rings.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
-#include <boost/geometry/algorithms/perimeter.hpp>
-#include <boost/geometry/algorithms/remove_spikes.hpp>
-#include <boost/geometry/algorithms/reverse.hpp>
-#include <boost/geometry/algorithms/simplify.hpp>
-#include <boost/geometry/algorithms/transform.hpp>
-#include <boost/geometry/algorithms/unique.hpp>
-#include <boost/geometry/algorithms/within.hpp>
-
-#include <boost/geometry/algorithms/detail/point_on_border.hpp>
-
-#include <boost/geometry/algorithms/detail/for_each_range.hpp>
-#include <boost/geometry/algorithms/detail/multi_modify_with_predicate.hpp>
-#include <boost/geometry/algorithms/detail/multi_sum.hpp>
-
-#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
-#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
-
-#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
-#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
-#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
-#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
-#include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
-#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
-
-#include <boost/geometry/geometries/concepts/check.hpp>
-
-#include <boost/geometry/views/detail/range_type.hpp>
-#include <boost/geometry/strategies/cartesian/centroid_average.hpp>
-
-#include <boost/geometry/io/dsv/write.hpp>
-#include <boost/geometry/io/wkt/wkt.hpp>
-
+// keep this file for now, for backward compatibility
+// functionality-wise, make it equivalent to boost/geometry/geometry.hpp
+#include <boost/geometry/geometry.hpp>
#endif // BOOST_GEOMETRY_MULTI_HPP
diff --git a/boost/geometry/policies/is_valid/failing_reason_policy.hpp b/boost/geometry/policies/is_valid/failing_reason_policy.hpp
index b99803bead..d1918adbda 100644
--- a/boost/geometry/policies/is_valid/failing_reason_policy.hpp
+++ b/boost/geometry/policies/is_valid/failing_reason_policy.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -13,6 +14,7 @@
#include <sstream>
#include <boost/geometry/io/dsv/write.hpp>
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
@@ -65,7 +67,8 @@ private:
static inline
validity_failure_type transform_failure_type(validity_failure_type failure)
{
- if (AllowDuplicates && failure == failure_duplicate_points)
+ if (BOOST_GEOMETRY_CONDITION(
+ AllowDuplicates && failure == failure_duplicate_points))
{
return no_failure;
}
@@ -76,7 +79,8 @@ private:
validity_failure_type transform_failure_type(validity_failure_type failure,
bool is_linear)
{
- if (is_linear && AllowSpikes && failure == failure_spikes)
+ if (BOOST_GEOMETRY_CONDITION(
+ is_linear && AllowSpikes && failure == failure_spikes))
{
return no_failure;
}
@@ -117,7 +121,7 @@ private:
bool is_linear,
SpikePoint const& spike_point)
{
- if (is_linear && AllowSpikes)
+ if (BOOST_GEOMETRY_CONDITION(is_linear && AllowSpikes))
{
return;
}
@@ -167,7 +171,7 @@ private:
static inline void apply(std::ostringstream& oss,
Point const& point)
{
- if (AllowDuplicates)
+ if (BOOST_GEOMETRY_CONDITION(AllowDuplicates))
{
return;
}
diff --git a/boost/geometry/policies/relate/de9im.hpp b/boost/geometry/policies/relate/de9im.hpp
deleted file mode 100644
index e2d6b5111c..0000000000
--- a/boost/geometry/policies/relate/de9im.hpp
+++ /dev/null
@@ -1,168 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-
-// 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_GEOMETRY_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
-#define BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
-
-
-#include <boost/geometry/strategies/intersection_result.hpp>
-#include <boost/geometry/util/math.hpp>
-#include <boost/geometry/util/select_coordinate_type.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-namespace policies { namespace relate
-{
-
-
-template <typename S1, typename S2>
-struct segments_de9im
-{
- typedef de9im_segment return_type;
- typedef S1 segment_type1;
- typedef S2 segment_type2;
- typedef typename select_coordinate_type<S1, S2>::type coordinate_type;
-
- static inline return_type rays_intersect(bool on_segment,
- double ra, double rb,
- coordinate_type const& dx1, coordinate_type const& dy1,
- coordinate_type const& dx2, coordinate_type const& dy2,
- coordinate_type const& wx, coordinate_type const& wy,
- S1 const& s1, S2 const& s2)
- {
- if(on_segment)
- {
- // 0 <= ra <= 1 and 0 <= rb <= 1
- // Now check if one of them is 0 or 1, these are "touch" cases
- bool a = math::equals(ra, 0.0) || math::equals(ra, 1.0);
- bool b = math::equals(rb, 0.0) || math::equals(rb, 1.0);
- if (a && b)
- {
- // Touch boundary/boundary: i-i == -1, i-b == -1, b-b == 0
- // Opposite: if both are equal they touch in opposite direction
- return de9im_segment(ra,rb,
- -1, -1, 1,
- -1, 0, 0,
- 1, 0, 2, false, math::equals(ra,rb));
- }
- else if (a || b)
- {
- // Touch boundary/interior: i-i == -1, i-b == -1 or 0, b-b == -1
- int A = a ? 0 : -1;
- int B = b ? 0 : -1;
- return de9im_segment(ra,rb,
- -1, B, 1,
- A, -1, 0,
- 1, 0, 2);
- }
-
- // Intersects: i-i == 0, i-b == -1, i-e == 1
- return de9im_segment(ra,rb,
- 0, -1, 1,
- -1, -1, 0,
- 1, 0, 2);
- }
-
- // Not on segment, disjoint
- return de9im_segment(ra,rb,
- -1, -1, 1,
- -1, -1, 0,
- 1, 0, 2);
- }
-
- static inline return_type collinear_touch(coordinate_type const& x,
- coordinate_type const& y, bool opposite, char)
- {
- return de9im_segment(0,0,
- -1, -1, 1,
- -1, 0, 0,
- 1, 0, 2,
- true, opposite);
- }
-
- template <typename S>
- static inline return_type collinear_interior_boundary_intersect(S const& s,
- bool a_within_b, bool opposite)
- {
- return a_within_b
- ? de9im_segment(0,0,
- 1, -1, -1,
- 0, 0, -1,
- 1, 0, 2,
- true, opposite)
- : de9im_segment(0,0,
- 1, 0, 1,
- -1, 0, 0,
- -1, -1, 2,
- true, opposite);
- }
-
-
-
- static inline return_type collinear_a_in_b(S1 const& s, bool opposite)
- {
- return de9im_segment(0,0,
- 1, -1, -1,
- 0, -1, -1,
- 1, 0, 2,
- true, opposite);
- }
- static inline return_type collinear_b_in_a(S2 const& s, bool opposite)
- {
- return de9im_segment(0,0,
- 1, 0, 1,
- -1, -1, 0,
- -1, -1, 2,
- true, opposite);
- }
-
- static inline return_type collinear_overlaps(
- coordinate_type const& x1, coordinate_type const& y1,
- coordinate_type const& x2, coordinate_type const& y2, bool opposite)
- {
- return de9im_segment(0,0,
- 1, 0, 1,
- 0, -1, 0,
- 1, 0, 2,
- true, opposite);
- }
-
- static inline return_type segment_equal(S1 const& s, bool opposite)
- {
- return de9im_segment(0,0,
- 1, -1, -1,
- -1, 0, -1,
- -1, -1, 2,
- true, opposite);
- }
-
- static inline return_type degenerate(S1 const& segment, bool a_degenerate)
- {
- return a_degenerate
- ? de9im_segment(0,0,
- 0, -1, -1,
- -1, -1, -1,
- 1, 0, 2,
- false, false, false, true)
- : de9im_segment(0,0,
- 0, -1, 1,
- -1, -1, 0,
- -1, -1, 2,
- false, false, false, true);
- }
-
-};
-
-
-}} // namespace policies::relate
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
diff --git a/boost/geometry/policies/relate/intersection_points.hpp b/boost/geometry/policies/relate/intersection_points.hpp
index 082dc4ca7f..50f9b43122 100644
--- a/boost/geometry/policies/relate/intersection_points.hpp
+++ b/boost/geometry/policies/relate/intersection_points.hpp
@@ -18,6 +18,7 @@
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/strategies/side_info.hpp>
#include <boost/geometry/util/promote_integral.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
@@ -60,7 +61,7 @@ struct segments_intersection_points
// Up to now, division was postponed. Here we divide using numerator/
// denominator. In case of integer this results in an integer
// division.
- BOOST_ASSERT(ratio.denominator() != 0);
+ BOOST_GEOMETRY_ASSERT(ratio.denominator() != 0);
typedef typename promote_integral<coordinate_type>::type promoted_type;
@@ -81,7 +82,6 @@ struct segments_intersection_points
>(numerator * dy_promoted / denominator));
}
-
template
<
typename Segment1,
@@ -95,7 +95,33 @@ struct segments_intersection_points
return_type result;
result.count = 1;
- if (sinfo.robust_ra < sinfo.robust_rb)
+ bool use_a = true;
+
+ // Prefer one segment if one is on or near an endpoint
+ bool const a_near_end = sinfo.robust_ra.near_end();
+ bool const b_near_end = sinfo.robust_rb.near_end();
+ if (a_near_end && ! b_near_end)
+ {
+ use_a = true;
+ }
+ else if (b_near_end && ! a_near_end)
+ {
+ use_a = false;
+ }
+ else
+ {
+ // Prefer shorter segment
+ typedef typename SegmentIntersectionInfo::promoted_type ptype;
+ ptype const len_a = sinfo.dx_a * sinfo.dx_a + sinfo.dy_a * sinfo.dy_a;
+ ptype const len_b = sinfo.dx_b * sinfo.dx_b + sinfo.dy_b * sinfo.dy_b;
+ if (len_b < len_a)
+ {
+ use_a = false;
+ }
+ // else use_a is true but was already assigned like that
+ }
+
+ if (use_a)
{
assign(result.intersections[0], s1, sinfo.robust_ra,
sinfo.dx_a, sinfo.dy_a);
diff --git a/boost/geometry/policies/robustness/get_rescale_policy.hpp b/boost/geometry/policies/robustness/get_rescale_policy.hpp
index 52570995f6..e7bef1d2e1 100644
--- a/boost/geometry/policies/robustness/get_rescale_policy.hpp
+++ b/boost/geometry/policies/robustness/get_rescale_policy.hpp
@@ -23,10 +23,12 @@
#include <boost/type_traits.hpp>
#include <boost/mpl/assert.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/detail/recalculate.hpp>
#include <boost/geometry/algorithms/detail/get_max_size.hpp>
#include <boost/geometry/policies/robustness/robust_type.hpp>
@@ -66,11 +68,18 @@ inline void scale_box_to_integer_range(Box const& box,
num_type const diff = boost::numeric_cast<num_type>(detail::get_max_size(box));
num_type const range = 10000000.0; // Define a large range to get precise integer coordinates
num_type const half = 0.5;
- factor = math::equals(diff, num_type()) || diff >= range ? 1
- : boost::numeric_cast<num_type>(
+ if (math::equals(diff, num_type())
+ || diff >= range
+ || ! boost::math::isfinite(diff))
+ {
+ factor = 1;
+ }
+ else
+ {
+ factor = boost::numeric_cast<num_type>(
boost::numeric_cast<boost::long_long_type>(half + range / diff));
-
- BOOST_ASSERT(factor >= 1);
+ BOOST_GEOMETRY_ASSERT(factor >= 1);
+ }
// Assign input/output minimal points
detail::assign_point_from_index<0>(box, min_point);
@@ -86,6 +95,11 @@ static inline void init_rescale_policy(Geometry const& geometry,
RobustPoint& min_robust_point,
Factor& factor)
{
+ if (geometry::is_empty(geometry))
+ {
+ return;
+ }
+
// Get bounding boxes
model::box<Point> env = geometry::return_envelope<model::box<Point> >(geometry);
@@ -99,10 +113,36 @@ static inline void init_rescale_policy(Geometry1 const& geometry1,
RobustPoint& min_robust_point,
Factor& factor)
{
- // Get bounding boxes
- model::box<Point> env = geometry::return_envelope<model::box<Point> >(geometry1);
- model::box<Point> env2 = geometry::return_envelope<model::box<Point> >(geometry2);
- geometry::expand(env, env2);
+ // Get bounding boxes (when at least one of the geometries is not empty)
+ bool const is_empty1 = geometry::is_empty(geometry1);
+ bool const is_empty2 = geometry::is_empty(geometry2);
+ if (is_empty1 && is_empty2)
+ {
+ return;
+ }
+
+ model::box<Point> env;
+ if (is_empty1)
+ {
+ geometry::envelope(geometry2, env);
+ }
+ else if (is_empty2)
+ {
+ geometry::envelope(geometry1, env);
+ }
+ else
+ {
+ // The following approach (envelope + expand) may not give the
+ // optimal MBR when then two geometries are in the spherical
+ // equatorial or geographic coordinate systems.
+ // TODO: implement envelope for two (or possibly more geometries)
+ geometry::envelope(geometry1, env);
+ model::box<Point> env2 = geometry::return_envelope
+ <
+ model::box<Point>
+ >(geometry2);
+ geometry::expand(env, env2);
+ }
scale_box_to_integer_range(env, min_point, min_robust_point, factor);
}
diff --git a/boost/geometry/policies/robustness/rescale_policy.hpp b/boost/geometry/policies/robustness/rescale_policy.hpp
index 5b3b566976..8f34bf3dee 100644
--- a/boost/geometry/policies/robustness/rescale_policy.hpp
+++ b/boost/geometry/policies/robustness/rescale_policy.hpp
@@ -1,9 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2014 Bruno Lalande, Paris, France.
-// Copyright (c) 2014 Mateusz Loskot, London, UK.
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2014-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2014-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2014-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -20,6 +24,8 @@
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
#include <boost/geometry/policies/robustness/robust_point_type.hpp>
+#include <boost/geometry/util/math.hpp>
+
namespace boost { namespace geometry
{
@@ -48,7 +54,8 @@ struct robust_policy
CalculationType const a = static_cast<CalculationType>(get<Dimension>(m_int_min));
CalculationType const b = static_cast<CalculationType>(get<Dimension>(m_fp_min));
CalculationType const result = a + (value - b) * m_multiplier;
- return static_cast<output_ct>(result);
+
+ return geometry::math::rounding_cast<output_ct>(result);
}
FpPoint m_fp_min;
diff --git a/boost/geometry/policies/robustness/segment_ratio.hpp b/boost/geometry/policies/robustness/segment_ratio.hpp
index 8b55605c7f..ec659257a2 100644
--- a/boost/geometry/policies/robustness/segment_ratio.hpp
+++ b/boost/geometry/policies/robustness/segment_ratio.hpp
@@ -9,10 +9,10 @@
#ifndef BOOST_GEOMETRY_POLICIES_ROBUSTNESS_SEGMENT_RATIO_HPP
#define BOOST_GEOMETRY_POLICIES_ROBUSTNESS_SEGMENT_RATIO_HPP
-#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/rational.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
@@ -47,8 +47,8 @@ struct less<Type, false>
template <typename Ratio>
static inline bool apply(Ratio const& lhs, Ratio const& rhs)
{
- BOOST_ASSERT(lhs.denominator() != 0);
- BOOST_ASSERT(rhs.denominator() != 0);
+ BOOST_GEOMETRY_ASSERT(lhs.denominator() != 0);
+ BOOST_GEOMETRY_ASSERT(rhs.denominator() != 0);
return lhs.numerator() * rhs.denominator()
< rhs.numerator() * lhs.denominator();
}
@@ -78,8 +78,8 @@ struct equal<Type, false>
template <typename Ratio>
static inline bool apply(Ratio const& lhs, Ratio const& rhs)
{
- BOOST_ASSERT(lhs.denominator() != 0);
- BOOST_ASSERT(rhs.denominator() != 0);
+ BOOST_GEOMETRY_ASSERT(lhs.denominator() != 0);
+ BOOST_GEOMETRY_ASSERT(rhs.denominator() != 0);
return geometry::math::equals
(
lhs.numerator() * rhs.denominator(),
@@ -139,14 +139,12 @@ public :
m_denominator = -m_denominator;
}
- typedef typename promote_floating_point<Type>::type num_type;
- static const num_type scale = 1000000.0;
m_approximation =
m_denominator == 0 ? 0
: boost::numeric_cast<double>
(
- boost::numeric_cast<num_type>(m_numerator) * scale
- / boost::numeric_cast<num_type>(m_denominator)
+ boost::numeric_cast<fp_type>(m_numerator) * scale()
+ / boost::numeric_cast<fp_type>(m_denominator)
);
}
@@ -178,6 +176,18 @@ public :
return m_numerator > m_denominator;
}
+ inline bool near_end() const
+ {
+ if (left() || right())
+ {
+ return false;
+ }
+
+ static fp_type const small_part_of_scale = scale() / 100.0;
+ return m_approximation < small_part_of_scale
+ || m_approximation > scale() - small_part_of_scale;
+ }
+
inline bool close_to(thistype const& other) const
{
return geometry::math::abs(m_approximation - other.m_approximation) < 2;
@@ -222,6 +232,8 @@ public :
private :
+ typedef typename promote_floating_point<Type>::type fp_type;
+
Type m_numerator;
Type m_denominator;
@@ -230,7 +242,13 @@ private :
// Boost.Rational is used if the approximations are close.
// Reason: performance, Boost.Rational does a GCD by default and also the
// comparisons contain while-loops.
- double m_approximation;
+ fp_type m_approximation;
+
+
+ static inline fp_type scale()
+ {
+ return 1000000.0;
+ }
};
diff --git a/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp b/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp
index 1d59e13cf6..0cd0cdc4db 100644
--- a/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp
+++ b/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp
@@ -24,6 +24,7 @@
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/convex_hull.hpp>
@@ -354,7 +355,7 @@ private:
{
std::copy(boost::begin(first), boost::end(first), out);
- BOOST_ASSERT(closed ? !boost::empty(second) : boost::size(second) > 1);
+ BOOST_GEOMETRY_ASSERT(closed ? !boost::empty(second) : boost::size(second) > 1);
std::copy(++boost::rbegin(second), // skip the first Point
closed ? boost::rend(second) : --boost::rend(second), // skip the last Point if open
out);
diff --git a/boost/geometry/strategies/agnostic/relate.hpp b/boost/geometry/strategies/agnostic/relate.hpp
index 9e8753251d..676207694f 100644
--- a/boost/geometry/strategies/agnostic/relate.hpp
+++ b/boost/geometry/strategies/agnostic/relate.hpp
@@ -1,17 +1,17 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014 Oracle and/or its affiliates.
+// Copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// 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)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_STRATEGY_AGNOSTIC_RELATE_HPP
#define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_RELATE_HPP
-#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
namespace boost { namespace geometry
@@ -25,7 +25,7 @@ struct relate
{
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
- return detail::relate::relate<StaticMask>(geometry1, geometry2);
+ return geometry::relate(geometry1, geometry2, StaticMask());
}
};
@@ -47,7 +47,10 @@ struct default_strategy<AnyTag1, AnyTag2, AnyTag1, AnyTag2, AnyCS, AnyCS, Geomet
<
Geometry1,
Geometry2,
- detail::relate::static_mask_within
+ typename detail::de9im::static_mask_within_type
+ <
+ Geometry1, Geometry2
+ >::type
> type;
};
@@ -58,7 +61,10 @@ struct default_strategy<AnyTag1, AnyTag2, AnyTag1, areal_tag, AnyCS, AnyCS, Geom
<
Geometry1,
Geometry2,
- detail::relate::static_mask_within
+ typename detail::de9im::static_mask_within_type
+ <
+ Geometry1, Geometry2
+ >::type
> type;
};
@@ -84,7 +90,10 @@ struct default_strategy<AnyTag1, AnyTag2, AnyTag1, AnyTag2, AnyCS, AnyCS, Geomet
<
Geometry1,
Geometry2,
- detail::relate::static_mask_covered_by
+ typename detail::de9im::static_mask_covered_by_type
+ <
+ Geometry1, Geometry2
+ >::type
> type;
};
@@ -95,7 +104,10 @@ struct default_strategy<AnyTag1, AnyTag2, AnyTag1, areal_tag, AnyCS, AnyCS, Geom
<
Geometry1,
Geometry2,
- detail::relate::static_mask_covered_by
+ typename detail::de9im::static_mask_covered_by_type
+ <
+ Geometry1, Geometry2
+ >::type
> type;
};
diff --git a/boost/geometry/strategies/agnostic/side_by_azimuth.hpp b/boost/geometry/strategies/agnostic/side_by_azimuth.hpp
deleted file mode 100644
index 14c69a0597..0000000000
--- a/boost/geometry/strategies/agnostic/side_by_azimuth.hpp
+++ /dev/null
@@ -1,87 +0,0 @@
-// Boost.Geometry
-
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014 Oracle and/or its affiliates.
-
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
-// 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_GEOMETRY_STRATEGIES_AGNOSTIC_SIDE_BY_AZIMUTH_HPP
-#define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_SIDE_BY_AZIMUTH_HPP
-
-#include <boost/mpl/if.hpp>
-#include <boost/type_traits.hpp>
-#include <boost/core/ignore_unused.hpp>
-
-#include <boost/geometry/core/cs.hpp>
-#include <boost/geometry/core/access.hpp>
-#include <boost/geometry/core/radian_access.hpp>
-
-#include <boost/geometry/algorithms/detail/azimuth.hpp>
-
-#include <boost/geometry/util/math.hpp>
-#include <boost/geometry/util/promote_floating_point.hpp>
-#include <boost/geometry/util/select_calculation_type.hpp>
-
-#include <boost/geometry/strategies/side.hpp>
-//#include <boost/geometry/strategies/concepts/side_concept.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-
-namespace strategy { namespace side
-{
-
-/*!
-\brief Check at which side of a segment a point lies
- left of segment (> 0), right of segment (< 0), on segment (0)
-\ingroup strategies
-\tparam Model Reference model of coordinate system.
-\tparam CalculationType \tparam_calculation
- */
-template <typename Model, typename CalculationType = void>
-class side_by_azimuth
-{
-public:
- side_by_azimuth(Model const& model = Model())
- : m_model(model)
- {}
-
- template <typename P1, typename P2, typename P>
- inline int apply(P1 const& p1, P2 const& p2, P const& p)
- {
- typedef typename promote_floating_point
- <
- typename select_calculation_type_alt
- <
- CalculationType,
- P1, P2, P
- >::type
- >::type calc_t;
-
- calc_t d1 = 0.001;
- calc_t crs_AD = geometry::detail::azimuth<calc_t>(p1, p, m_model);
- calc_t crs_AB = geometry::detail::azimuth<calc_t>(p1, p2, m_model);
- calc_t XTD = asin(sin(d1) * sin(crs_AD - crs_AB));
-
- return math::equals(XTD, 0) ? 0 : XTD < 0 ? 1 : -1;
- }
-
-private:
- Model m_model;
-};
-
-}} // namespace strategy::side
-
-
-}} // namespace boost::geometry
-
-
-#endif // BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_SIDE_BY_AZIMUTH_HPP
diff --git a/boost/geometry/strategies/buffer.hpp b/boost/geometry/strategies/buffer.hpp
index 7dbe03b4a9..86bdcc37bf 100644
--- a/boost/geometry/strategies/buffer.hpp
+++ b/boost/geometry/strategies/buffer.hpp
@@ -66,7 +66,8 @@ enum piece_type
buffered_round_end,
buffered_flat_end,
buffered_point,
- buffered_concave // always on the inside
+ buffered_concave, // always on the inside
+ piece_type_unknown
};
@@ -82,6 +83,17 @@ enum join_selector
join_spike // collinear, with overlap, next segment goes back
};
+/*!
+\brief Enumerates types of result codes from buffer strategies
+\ingroup enum
+*/
+enum result_code
+{
+ result_normal,
+ result_error_numerical,
+ result_no_output
+};
+
}} // namespace strategy::buffer
diff --git a/boost/geometry/strategies/cartesian/buffer_end_round.hpp b/boost/geometry/strategies/cartesian/buffer_end_round.hpp
index a233f1c4be..3d7d5bb467 100644
--- a/boost/geometry/strategies/cartesian/buffer_end_round.hpp
+++ b/boost/geometry/strategies/cartesian/buffer_end_round.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -62,8 +67,7 @@ private :
DistanceType const& buffer_distance,
RangeOut& range_out) const
{
- PromotedType const two = 2.0;
- PromotedType const two_pi = two * geometry::math::pi<PromotedType>();
+ PromotedType const two_pi = geometry::math::two_pi<PromotedType>();
std::size_t point_buffer_count = m_points_per_circle;
diff --git a/boost/geometry/strategies/cartesian/buffer_join_miter.hpp b/boost/geometry/strategies/cartesian/buffer_join_miter.hpp
index 99ec80527f..5358156f6d 100644
--- a/boost/geometry/strategies/cartesian/buffer_join_miter.hpp
+++ b/boost/geometry/strategies/cartesian/buffer_join_miter.hpp
@@ -9,7 +9,7 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_MITER_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_MITER_HPP
-#include <boost/assert.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/util/math.hpp>
@@ -99,7 +99,7 @@ public:
if (distance > max_distance)
{
- BOOST_ASSERT(distance != 0.0);
+ BOOST_GEOMETRY_ASSERT(distance != 0.0);
promoted_type const proportion = max_distance / distance;
set<0>(p, get<0>(vertex) + dx * proportion);
diff --git a/boost/geometry/strategies/cartesian/buffer_join_round.hpp b/boost/geometry/strategies/cartesian/buffer_join_round.hpp
index 9ec51cd1ec..e1a433e1ee 100644
--- a/boost/geometry/strategies/cartesian/buffer_join_round.hpp
+++ b/boost/geometry/strategies/cartesian/buffer_join_round.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
// 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)
@@ -11,7 +16,6 @@
#include <algorithm>
-#include <boost/assert.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/strategies/buffer.hpp>
@@ -19,6 +23,7 @@
#include <boost/geometry/util/select_most_precise.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_WARN
+#include <iostream>
#include <boost/geometry/io/wkt/wkt.hpp>
#endif
@@ -76,8 +81,7 @@ private :
PromotedType const dx2 = get<0>(perp2) - get<0>(vertex);
PromotedType const dy2 = get<1>(perp2) - get<1>(vertex);
- PromotedType const two = 2.0;
- PromotedType const two_pi = two * geometry::math::pi<PromotedType>();
+ PromotedType const two_pi = geometry::math::two_pi<PromotedType>();
PromotedType const angle1 = atan2(dy1, dx1);
PromotedType angle2 = atan2(dy2, dx2);
@@ -96,14 +100,14 @@ private :
// - generates 1 point in between for an angle of 125 based on 3 points
// - generates 0 points in between for an angle of 90 based on 4 points
- int const n = (std::max)(static_cast<int>(
- ceil(m_points_per_circle * angle_diff / two_pi)), 1);
+ std::size_t const n = (std::max)(static_cast<std::size_t>(
+ ceil(m_points_per_circle * angle_diff / two_pi)), std::size_t(1));
PromotedType const diff = angle_diff / static_cast<PromotedType>(n);
PromotedType a = angle1 - diff;
// Walk to n - 1 to avoid generating the last point
- for (int i = 0; i < n - 1; i++, a -= diff)
+ for (std::size_t i = 0; i < n - 1; i++, a -= diff)
{
Point p;
set<0>(p, get<0>(vertex) + buffer_distance * cos(a));
diff --git a/boost/geometry/strategies/cartesian/buffer_join_round_by_divide.hpp b/boost/geometry/strategies/cartesian/buffer_join_round_by_divide.hpp
index 1444c795af..ed3a010cd5 100644
--- a/boost/geometry/strategies/cartesian/buffer_join_round_by_divide.hpp
+++ b/boost/geometry/strategies/cartesian/buffer_join_round_by_divide.hpp
@@ -9,7 +9,6 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_BY_DIVIDE_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_BY_DIVIDE_HPP
-#include <boost/assert.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/strategies/buffer.hpp>
diff --git a/boost/geometry/strategies/cartesian/buffer_point_circle.hpp b/boost/geometry/strategies/cartesian/buffer_point_circle.hpp
index 86ebc43c9c..f289857177 100644
--- a/boost/geometry/strategies/cartesian/buffer_point_circle.hpp
+++ b/boost/geometry/strategies/cartesian/buffer_point_circle.hpp
@@ -85,8 +85,7 @@ public :
promoted_type const buffer_distance = distance_strategy.apply(point, point,
strategy::buffer::buffer_side_left);
- promoted_type const two = 2.0;
- promoted_type const two_pi = two * geometry::math::pi<promoted_type>();
+ promoted_type const two_pi = geometry::math::two_pi<promoted_type>();
promoted_type const diff = two_pi / promoted_type(m_count);
promoted_type a = 0;
diff --git a/boost/geometry/strategies/cartesian/buffer_side_straight.hpp b/boost/geometry/strategies/cartesian/buffer_side_straight.hpp
index 24655ab3d7..75247377fa 100644
--- a/boost/geometry/strategies/cartesian/buffer_side_straight.hpp
+++ b/boost/geometry/strategies/cartesian/buffer_side_straight.hpp
@@ -9,6 +9,8 @@
#include <cstddef>
+#include <boost/math/special_functions/fpclassify.hpp>
+
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/util/math.hpp>
@@ -51,9 +53,9 @@ public :
typename OutputRange,
typename DistanceStrategy
>
- static inline void apply(
+ static inline result_code apply(
Point const& input_p1, Point const& input_p2,
- strategy::buffer::buffer_side_selector side,
+ buffer_side_selector side,
DistanceStrategy const& distance,
OutputRange& output_range)
{
@@ -73,19 +75,46 @@ public :
// For normalization [0,1] (=dot product d.d, sqrt)
promoted_type const length = geometry::math::sqrt(dx * dx + dy * dy);
+ if (! boost::math::isfinite(length))
+ {
+ // In case of coordinates differences of e.g. 1e300, length
+ // will overflow and we should not generate output
+#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_WARN
+ std::cout << "Error in length calculation for points "
+ << geometry::wkt(input_p1) << " " << geometry::wkt(input_p2)
+ << " length: " << length << std::endl;
+#endif
+ return result_error_numerical;
+ }
+
if (geometry::math::equals(length, 0))
{
// Coordinates are simplified and therefore most often not equal.
// But if simplify is skipped, or for lines with two
// equal points, length is 0 and we cannot generate output.
- return;
+ return result_no_output;
}
+ promoted_type const d = distance.apply(input_p1, input_p2, side);
+
// Generate the normalized perpendicular p, to the left (ccw)
promoted_type const px = -dy / length;
promoted_type const py = dx / length;
- promoted_type const d = distance.apply(input_p1, input_p2, side);
+ if (geometry::math::equals(px, 0)
+ && geometry::math::equals(py, 0))
+ {
+ // This basically should not occur - because of the checks above.
+ // There are no unit tests triggering this condition
+#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_WARN
+ std::cout << "Error in perpendicular calculation for points "
+ << geometry::wkt(input_p1) << " " << geometry::wkt(input_p2)
+ << " length: " << length
+ << " distance: " << d
+ << std::endl;
+#endif
+ return result_no_output;
+ }
output_range.resize(2);
@@ -93,6 +122,8 @@ public :
set<1>(output_range.front(), get<1>(input_p1) + py * d);
set<0>(output_range.back(), get<0>(input_p2) + px * d);
set<1>(output_range.back(), get<1>(input_p2) + py * d);
+
+ return result_normal;
}
#endif // DOXYGEN_SHOULD_SKIP_THIS
};
diff --git a/boost/geometry/strategies/cartesian/cart_intersect.hpp b/boost/geometry/strategies/cartesian/cart_intersect.hpp
index a7bd385226..8a9857376a 100644
--- a/boost/geometry/strategies/cartesian/cart_intersect.hpp
+++ b/boost/geometry/strategies/cartesian/cart_intersect.hpp
@@ -119,15 +119,10 @@ struct relate_cartesian_segments
boost::ignore_unused_variable_warning(robust_policy);
- typedef typename select_calculation_type
- <Segment1, Segment2, CalculationType>::type coordinate_type;
-
using geometry::detail::equals::equals_point_point;
bool const a_is_point = equals_point_point(robust_a1, robust_a2);
bool const b_is_point = equals_point_point(robust_b1, robust_b2);
- typedef side::side_by_triangle<coordinate_type> side;
-
if(a_is_point && b_is_point)
{
return equals_point_point(robust_a1, robust_b2)
@@ -136,20 +131,32 @@ struct relate_cartesian_segments
;
}
+ typedef typename select_calculation_type
+ <Segment1, Segment2, CalculationType>::type coordinate_type;
+
+ typedef side::side_by_triangle<coordinate_type> side;
+
side_info sides;
sides.set<0>(side::apply(robust_b1, robust_b2, robust_a1),
side::apply(robust_b1, robust_b2, robust_a2));
- sides.set<1>(side::apply(robust_a1, robust_a2, robust_b1),
- side::apply(robust_a1, robust_a2, robust_b2));
- bool collinear = sides.collinear();
+ if (sides.same<0>())
+ {
+ // Both points are at same side of other segment, we can leave
+ return Policy::disjoint();
+ }
- if (sides.same<0>() || sides.same<1>())
+ sides.set<1>(side::apply(robust_a1, robust_a2, robust_b1),
+ side::apply(robust_a1, robust_a2, robust_b2));
+
+ if (sides.same<1>())
{
// Both points are at same side of other segment, we can leave
return Policy::disjoint();
}
+ bool collinear = sides.collinear();
+
typedef typename select_most_precise
<
coordinate_type, double
@@ -264,7 +271,7 @@ private:
bool const a_is_point,
bool const b_is_point)
{
- //BOOST_ASSERT_MSG(!(a_is_point && b_is_point), "both segments shouldn't be degenerated");
+ //BOOST_GEOMETRY_ASSERT_MSG(!(a_is_point && b_is_point), "both segments shouldn't be degenerated");
// for degenerated segments the second is always true because this function
// shouldn't be called if both segments were degenerated
diff --git a/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp b/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp
index 0357f17e7a..47763a9f30 100644
--- a/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp
+++ b/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp
@@ -1,8 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015 Oracle and/or its affiliates.
@@ -22,6 +22,7 @@
#include <cstddef>
+#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/mpl/if.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits.hpp>
@@ -206,11 +207,18 @@ public :
Point
>::type coordinate_type;
- set<0>(centroid,
- boost::numeric_cast<coordinate_type>(state.sum_x / a3));
- set<1>(centroid,
- boost::numeric_cast<coordinate_type>(state.sum_y / a3));
- return true;
+ // Prevent NaN centroid coordinates
+ if (boost::math::isfinite(a3))
+ {
+ // NOTE: above calculation_type is checked, not the centroid coordinate_type
+ // which means that the centroid can still be filled with INF
+ // if e.g. calculation_type is double and centroid contains floats
+ set<0>(centroid,
+ boost::numeric_cast<coordinate_type>(state.sum_x / a3));
+ set<1>(centroid,
+ boost::numeric_cast<coordinate_type>(state.sum_y / a3));
+ return true;
+ }
}
return false;
diff --git a/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp b/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp
index b788738d15..0735e925b6 100644
--- a/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp
+++ b/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp
@@ -1,7 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2009-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -13,9 +18,13 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
#include <boost/geometry/algorithms/detail/distance/interface.hpp>
#include <boost/geometry/algorithms/detail/distance/point_to_geometry.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
+#include <boost/geometry/util/for_each_coordinate.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/geometry/strategies/centroid.hpp>
#include <boost/geometry/strategies/default_distance_result.hpp>
@@ -91,17 +100,37 @@ public :
static inline bool result(state_type const& state, Point& centroid)
{
distance_type const zero = distance_type();
- if (! geometry::math::equals(state.length, zero))
+ if (! geometry::math::equals(state.length, zero)
+ && boost::math::isfinite(state.length)) // Prevent NaN centroid coordinates
{
- assign_zero(centroid);
- add_point(centroid, state.average_sum);
- divide_value(centroid, state.length);
+ // NOTE: above distance_type is checked, not the centroid coordinate_type
+ // which means that the centroid can still be filled with INF
+ // if e.g. distance_type is double and centroid contains floats
+ geometry::for_each_coordinate(centroid, set_sum_div_length(state));
return true;
}
return false;
}
+ struct set_sum_div_length
+ {
+ state_type const& m_state;
+ set_sum_div_length(state_type const& state)
+ : m_state(state)
+ {}
+ template <typename Pt, std::size_t Dimension>
+ void apply(Pt & centroid) const
+ {
+ typedef typename geometry::coordinate_type<Pt>::type coordinate_type;
+ geometry::set<Dimension>(
+ centroid,
+ boost::numeric_cast<coordinate_type>(
+ geometry::get<Dimension>(m_state.average_sum) / m_state.length
+ )
+ );
+ }
+ };
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
diff --git a/boost/geometry/strategies/cartesian/side_of_intersection.hpp b/boost/geometry/strategies/cartesian/side_of_intersection.hpp
index 39487676c1..db57644ad5 100644
--- a/boost/geometry/strategies/cartesian/side_of_intersection.hpp
+++ b/boost/geometry/strategies/cartesian/side_of_intersection.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// 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)
@@ -10,11 +15,25 @@
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_OF_INTERSECTION_HPP
+#include <limits>
+
+#include <boost/core/ignore_unused.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+
#include <boost/geometry/arithmetic/determinant.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
+#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/util/math.hpp>
+#ifdef BOOST_GEOMETRY_SIDE_OF_INTERSECTION_DEBUG
+#include <boost/math/common_factor_ct.hpp>
+#include <boost/math/common_factor_rt.hpp>
+#include <boost/multiprecision/cpp_int.hpp>
+#endif
namespace boost { namespace geometry
{
@@ -22,6 +41,94 @@ namespace boost { namespace geometry
namespace strategy { namespace side
{
+namespace detail
+{
+
+// A tool for multiplication of integers avoiding overflow
+// It's a temporary workaround until we can use Multiprecision
+// The algorithm is based on Karatsuba algorithm
+// see: http://en.wikipedia.org/wiki/Karatsuba_algorithm
+template <typename T>
+struct multiplicable_integral
+{
+ // Currently this tool can't be used with non-integral coordinate types.
+ // Also side_of_intersection strategy sign_of_product() and sign_of_compare()
+ // functions would have to be modified to properly support floating-point
+ // types (comparisons and multiplication).
+ BOOST_STATIC_ASSERT(boost::is_integral<T>::value);
+
+ static const std::size_t bits = CHAR_BIT * sizeof(T);
+ static const std::size_t half_bits = bits / 2;
+ typedef typename boost::make_unsigned<T>::type unsigned_type;
+ static const unsigned_type base = unsigned_type(1) << half_bits; // 2^half_bits
+
+ int m_sign;
+ unsigned_type m_ms;
+ unsigned_type m_ls;
+
+ multiplicable_integral(int sign, unsigned_type ms, unsigned_type ls)
+ : m_sign(sign), m_ms(ms), m_ls(ls)
+ {}
+
+ explicit multiplicable_integral(T const& val)
+ {
+ unsigned_type val_u = val > 0 ?
+ unsigned_type(val)
+ : val == (std::numeric_limits<T>::min)() ?
+ unsigned_type((std::numeric_limits<T>::max)()) + 1
+ : unsigned_type(-val);
+ // MMLL -> S 00MM 00LL
+ m_sign = math::sign(val);
+ m_ms = val_u >> half_bits; // val_u / base
+ m_ls = val_u - m_ms * base;
+ }
+
+ friend multiplicable_integral operator*(multiplicable_integral const& a,
+ multiplicable_integral const& b)
+ {
+ // (S 00MM 00LL) * (S 00MM 00LL) -> (S Z2MM 00LL)
+ unsigned_type z2 = a.m_ms * b.m_ms;
+ unsigned_type z0 = a.m_ls * b.m_ls;
+ unsigned_type z1 = (a.m_ms + a.m_ls) * (b.m_ms + b.m_ls) - z2 - z0;
+ // z0 may be >= base so it must be normalized to allow comparison
+ unsigned_type z0_ms = z0 >> half_bits; // z0 / base
+ return multiplicable_integral(a.m_sign * b.m_sign,
+ z2 * base + z1 + z0_ms,
+ z0 - base * z0_ms);
+ }
+
+ friend bool operator<(multiplicable_integral const& a,
+ multiplicable_integral const& b)
+ {
+ if ( a.m_sign == b.m_sign )
+ {
+ bool u_less = a.m_ms < b.m_ms
+ || (a.m_ms == b.m_ms && a.m_ls < b.m_ls);
+ return a.m_sign > 0 ? u_less : (! u_less);
+ }
+ else
+ {
+ return a.m_sign < b.m_sign;
+ }
+ }
+
+ friend bool operator>(multiplicable_integral const& a,
+ multiplicable_integral const& b)
+ {
+ return b < a;
+ }
+
+ template <typename CmpVal>
+ void check_value(CmpVal const& cmp_val) const
+ {
+ unsigned_type b = base; // a workaround for MinGW - undefined reference base
+ CmpVal val = CmpVal(m_sign) * (CmpVal(m_ms) * CmpVal(b) + CmpVal(m_ls));
+ BOOST_GEOMETRY_ASSERT(cmp_val == val);
+ }
+};
+
+} // namespace detail
+
// Calculates the side of the intersection-point (if any) of
// of segment a//b w.r.t. segment c
// This is calculated without (re)calculating the IP itself again and fully
@@ -29,15 +136,93 @@ namespace strategy { namespace side
// It can be used for either integer (rescaled) points, and also for FP
class side_of_intersection
{
+private :
+ template <typename T, typename U>
+ static inline
+ int sign_of_product(T const& a, U const& b)
+ {
+ return a == 0 || b == 0 ? 0
+ : a > 0 && b > 0 ? 1
+ : a < 0 && b < 0 ? 1
+ : -1;
+ }
+
+ template <typename T>
+ static inline
+ int sign_of_compare(T const& a, T const& b, T const& c, T const& d)
+ {
+ // Both a*b and c*d are positive
+ // We have to judge if a*b > c*d
+
+ using side::detail::multiplicable_integral;
+ multiplicable_integral<T> ab = multiplicable_integral<T>(a)
+ * multiplicable_integral<T>(b);
+ multiplicable_integral<T> cd = multiplicable_integral<T>(c)
+ * multiplicable_integral<T>(d);
+
+ int result = ab > cd ? 1
+ : ab < cd ? -1
+ : 0
+ ;
+
+#ifdef BOOST_GEOMETRY_SIDE_OF_INTERSECTION_DEBUG
+ using namespace boost::multiprecision;
+ cpp_int const lab = cpp_int(a) * cpp_int(b);
+ cpp_int const lcd = cpp_int(c) * cpp_int(d);
+
+ ab.check_value(lab);
+ cd.check_value(lcd);
+
+ int result2 = lab > lcd ? 1
+ : lab < lcd ? -1
+ : 0
+ ;
+ BOOST_GEOMETRY_ASSERT(result == result2);
+#endif
+
+ return result;
+ }
+
+ template <typename T>
+ static inline
+ int sign_of_addition_of_two_products(T const& a, T const& b, T const& c, T const& d)
+ {
+ // sign of a*b+c*d, 1 if positive, -1 if negative, else 0
+ int const ab = sign_of_product(a, b);
+ int const cd = sign_of_product(c, d);
+ if (ab == 0)
+ {
+ return cd;
+ }
+ if (cd == 0)
+ {
+ return ab;
+ }
+
+ if (ab == cd)
+ {
+ // Both positive or both negative
+ return ab;
+ }
+
+ // One is positive, one is negative, both are non zero
+ // If ab is positive, we have to judge if a*b > -c*d (then 1 because sum is positive)
+ // If ab is negative, we have to judge if c*d > -a*b (idem)
+ return ab == 1
+ ? sign_of_compare(a, b, -c, d)
+ : sign_of_compare(c, d, -a, b);
+ }
+
+
public :
// Calculates the side of the intersection-point (if any) of
// of segment a//b w.r.t. segment c
// This is calculated without (re)calculating the IP itself again and fully
// based on integer mathematics
- template <typename T, typename Segment>
+ template <typename T, typename Segment, typename Point>
static inline T side_value(Segment const& a, Segment const& b,
- Segment const& c)
+ Segment const& c, Point const& fallback_point)
{
// The first point of the three segments is reused several times
T const ax = get<0, 0>(a);
@@ -67,9 +252,15 @@ public :
if (d == zero)
{
// There is no IP of a//b, they are collinear or parallel
- // We don't have to divide but we can already conclude the side-value
- // is meaningless and the resulting determinant will be 0
- return zero;
+ // Assuming they intersect (this method should be called for
+ // segments known to intersect), they are collinear and overlap.
+ // They have one or two intersection points - we don't know and
+ // have to rely on the fallback intersection point
+
+ Point c1, c2;
+ geometry::detail::assign_point_from_index<0>(c, c1);
+ geometry::detail::assign_point_from_index<1>(c, c2);
+ return side_by_triangle<>::apply(c1, c2, fallback_point);
}
// Cramer's rule: da (see cart_intersect.hpp)
@@ -82,7 +273,9 @@ public :
// IP is at (ax + (da/d) * dx_a, ay + (da/d) * dy_a)
// Side of IP is w.r.t. c is: determinant(dx_c, dy_c, ipx-cx, ipy-cy)
// We replace ipx by expression above and multiply each term by d
- T const result = geometry::detail::determinant<T>
+
+#ifdef BOOST_GEOMETRY_SIDE_OF_INTERSECTION_DEBUG
+ T const result1 = geometry::detail::determinant<T>
(
dx_c * d, dy_c * d,
d * (ax - cx) + dx_a * da, d * (ay - cy) + dy_a * da
@@ -93,15 +286,52 @@ public :
// Therefore, the sign is always the same as that result, and the
// resulting side (left,right,collinear) is the same
+ // The first row we divide again by d because of determinant multiply rule
+ T const result2 = d * geometry::detail::determinant<T>
+ (
+ dx_c, dy_c,
+ d * (ax - cx) + dx_a * da, d * (ay - cy) + dy_a * da
+ );
+ // Write out:
+ T const result3 = d * (dx_c * (d * (ay - cy) + dy_a * da)
+ - dy_c * (d * (ax - cx) + dx_a * da));
+ // Write out in braces:
+ T const result4 = d * (dx_c * d * (ay - cy) + dx_c * dy_a * da
+ - dy_c * d * (ax - cx) - dy_c * dx_a * da);
+ // Write in terms of d * XX + da * YY
+ T const result5 = d * (d * (dx_c * (ay - cy) - dy_c * (ax - cx))
+ + da * (dx_c * dy_a - dy_c * dx_a));
+
+ boost::ignore_unused(result1, result2, result3, result4, result5);
+ //return result;
+#endif
+
+ // We consider the results separately
+ // (in the end we only have to return the side-value 1,0 or -1)
+
+ // To avoid multiplications we judge the product (easy, avoids *d)
+ // and the sign of p*q+r*s (more elaborate)
+ T const result = sign_of_product
+ (
+ d,
+ sign_of_addition_of_two_products
+ (
+ d, dx_c * (ay - cy) - dy_c * (ax - cx),
+ da, dx_c * dy_a - dy_c * dx_a
+ )
+ );
return result;
+
}
- template <typename Segment>
- static inline int apply(Segment const& a, Segment const& b, Segment const& c)
+ template <typename Segment, typename Point>
+ static inline int apply(Segment const& a, Segment const& b,
+ Segment const& c,
+ Point const& fallback_point)
{
typedef typename geometry::coordinate_type<Segment>::type coordinate_type;
- coordinate_type const s = side_value<coordinate_type>(a, b, c);
+ coordinate_type const s = side_value<coordinate_type>(a, b, c, fallback_point);
coordinate_type const zero = coordinate_type();
return math::equals(s, zero) ? 0
: s > zero ? 1
diff --git a/boost/geometry/strategies/geographic/distance_thomas.hpp b/boost/geometry/strategies/geographic/distance_thomas.hpp
new file mode 100644
index 0000000000..7252b723dd
--- /dev/null
+++ b/boost/geometry/strategies/geographic/distance_thomas.hpp
@@ -0,0 +1,156 @@
+// Boost.Geometry
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_STRATEGIES_GEOGRAPHIC_THOMAS_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_THOMAS_HPP
+
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+
+#include <boost/geometry/util/promote_floating_point.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
+#include <boost/geometry/algorithms/detail/thomas_inverse.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace distance
+{
+
+/*!
+\brief The solution of the inverse problem of geodesics on latlong coordinates,
+ Forsyth-Andoyer-Lambert type approximation with second order terms.
+\ingroup distance
+\tparam Spheroid The reference spheroid model
+\tparam CalculationType \tparam_calculation
+\author See
+ - Technical Report: PAUL D. THOMAS, MATHEMATICAL MODELS FOR NAVIGATION SYSTEMS, 1965
+ http://www.dtic.mil/docs/citations/AD0627893
+ - Technical Report: PAUL D. THOMAS, SPHEROIDAL GEODESICS, REFERENCE SYSTEMS, AND LOCAL GEOMETRY, 1970
+ http://www.dtic.mil/docs/citations/AD703541
+*/
+template
+<
+ typename Spheroid,
+ typename CalculationType = void
+>
+class thomas
+{
+public :
+ template <typename Point1, typename Point2>
+ struct calculation_type
+ : promote_floating_point
+ <
+ typename select_calculation_type
+ <
+ Point1,
+ Point2,
+ CalculationType
+ >::type
+ >
+ {};
+
+ typedef Spheroid model_type;
+
+ inline thomas()
+ : m_spheroid()
+ {}
+
+ explicit inline thomas(Spheroid const& spheroid)
+ : m_spheroid(spheroid)
+ {}
+
+ template <typename Point1, typename Point2>
+ inline typename calculation_type<Point1, Point2>::type
+ apply(Point1 const& point1, Point2 const& point2) const
+ {
+ return geometry::detail::thomas_inverse
+ <
+ typename calculation_type<Point1, Point2>::type,
+ true, false
+ >::apply(get_as_radian<0>(point1),
+ get_as_radian<1>(point1),
+ get_as_radian<0>(point2),
+ get_as_radian<1>(point2),
+ m_spheroid).distance;
+ }
+
+ inline Spheroid const& model() const
+ {
+ return m_spheroid;
+ }
+
+private :
+ Spheroid m_spheroid;
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Spheroid, typename CalculationType>
+struct tag<thomas<Spheroid, CalculationType> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template <typename Spheroid, typename CalculationType, typename P1, typename P2>
+struct return_type<thomas<Spheroid, CalculationType>, P1, P2>
+ : thomas<Spheroid, CalculationType>::template calculation_type<P1, P2>
+{};
+
+
+template <typename Spheroid, typename CalculationType>
+struct comparable_type<thomas<Spheroid, CalculationType> >
+{
+ typedef thomas<Spheroid, CalculationType> type;
+};
+
+
+template <typename Spheroid, typename CalculationType>
+struct get_comparable<thomas<Spheroid, CalculationType> >
+{
+ static inline thomas<Spheroid, CalculationType> apply(thomas<Spheroid, CalculationType> const& input)
+ {
+ return input;
+ }
+};
+
+template <typename Spheroid, typename CalculationType, typename P1, typename P2>
+struct result_from_distance<thomas<Spheroid, CalculationType>, P1, P2 >
+{
+ template <typename T>
+ static inline typename return_type<thomas<Spheroid, CalculationType>, P1, P2>::type
+ apply(thomas<Spheroid, CalculationType> const& , T const& value)
+ {
+ return value;
+ }
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::distance
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_THOMAS_HPP
diff --git a/boost/geometry/strategies/geographic/distance_vincenty.hpp b/boost/geometry/strategies/geographic/distance_vincenty.hpp
index 56dd14bbdc..65bfa19939 100644
--- a/boost/geometry/strategies/geographic/distance_vincenty.hpp
+++ b/boost/geometry/strategies/geographic/distance_vincenty.hpp
@@ -82,12 +82,13 @@ public :
{
return geometry::detail::vincenty_inverse
<
- typename calculation_type<Point1, Point2>::type
- >(get_as_radian<0>(point1),
- get_as_radian<1>(point1),
- get_as_radian<0>(point2),
- get_as_radian<1>(point2),
- m_spheroid).distance();
+ typename calculation_type<Point1, Point2>::type,
+ true, false
+ >::apply(get_as_radian<0>(point1),
+ get_as_radian<1>(point1),
+ get_as_radian<0>(point2),
+ get_as_radian<1>(point2),
+ m_spheroid).distance;
}
inline Spheroid const& model() const
diff --git a/boost/geometry/strategies/geographic/side_andoyer.hpp b/boost/geometry/strategies/geographic/side_andoyer.hpp
new file mode 100644
index 0000000000..e0f0c04067
--- /dev/null
+++ b/boost/geometry/strategies/geographic/side_andoyer.hpp
@@ -0,0 +1,55 @@
+// Boost.Geometry
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_ANDOYER_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_ANDOYER_HPP
+
+
+#include <boost/geometry/algorithms/detail/andoyer_inverse.hpp>
+
+#include <boost/geometry/strategies/geographic/side_detail.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace side
+{
+
+/*!
+\brief Check at which side of a segment a point lies
+ left of segment (> 0), right of segment (< 0), on segment (0)
+\ingroup strategies
+\tparam Model Reference model of coordinate system.
+\tparam CalculationType \tparam_calculation
+ */
+template <typename Model, typename CalculationType = void>
+class andoyer
+ : public detail::by_azimuth<geometry::detail::andoyer_inverse, Model, CalculationType>
+{
+ typedef detail::by_azimuth<geometry::detail::andoyer_inverse, Model, CalculationType> base_t;
+
+public:
+ andoyer(Model const& model = Model())
+ : base_t(model)
+ {}
+};
+
+}} // namespace strategy::side
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_ANDOYER_HPP
diff --git a/boost/geometry/strategies/geographic/side_detail.hpp b/boost/geometry/strategies/geographic/side_detail.hpp
new file mode 100644
index 0000000000..c00213d072
--- /dev/null
+++ b/boost/geometry/strategies/geographic/side_detail.hpp
@@ -0,0 +1,139 @@
+// Boost.Geometry
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_DETAIL_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_DETAIL_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/radius.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
+#include <boost/geometry/strategies/side.hpp>
+//#include <boost/geometry/strategies/concepts/side_concept.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace side
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+/*!
+\brief Check at which side of a segment a point lies
+ left of segment (> 0), right of segment (< 0), on segment (0)
+\ingroup strategies
+\tparam InverseFormula Geodesic inverse solution formula.
+\tparam Model Reference model of coordinate system.
+\tparam CalculationType \tparam_calculation
+ */
+template <template<typename, bool, bool> class InverseFormula,
+ typename Model,
+ typename CalculationType = void>
+class by_azimuth
+{
+public:
+ by_azimuth(Model const& model = Model())
+ : m_model(model)
+ {}
+
+ template <typename P1, typename P2, typename P>
+ inline int apply(P1 const& p1, P2 const& p2, P const& p)
+ {
+ typedef typename promote_floating_point
+ <
+ typename select_calculation_type_alt
+ <
+ CalculationType,
+ P1, P2, P
+ >::type
+ >::type calc_t;
+
+ typedef InverseFormula<calc_t, false, true> inverse_formula;
+
+ calc_t a1p = azimuth<calc_t, inverse_formula>(p1, p, m_model);
+ calc_t a12 = azimuth<calc_t, inverse_formula>(p1, p2, m_model);
+
+ calc_t const pi = math::pi<calc_t>();
+
+ // instead of the formula from XTD
+ //calc_t a_diff = asin(sin(a1p - a12));
+
+ calc_t a_diff = a1p - a12;
+ // normalize, angle in [-pi, pi]
+ while ( a_diff > pi )
+ a_diff -= calc_t(2) * pi;
+ while ( a_diff < -pi )
+ a_diff += calc_t(2) * pi;
+
+ // NOTE: in general it shouldn't be required to support the pi/-pi case
+ // because in non-cartesian systems it makes sense to check the side
+ // only "between" the endpoints.
+ // However currently the winding strategy calls the side strategy
+ // for vertical segments to check if the point is "between the endpoints.
+ // This could be avoided since the side strategy is not required for that
+ // because meridian is the shortest path. So a difference of
+ // longitudes would be sufficient (of course normalized to [-pi, pi]).
+
+ // NOTE: with the above said, the pi/-pi check is temporary
+ // however in case if this was required
+ // the geodesics on ellipsoid aren't "symmetrical"
+ // therefore instead of comparing a_diff to pi and -pi
+ // one should probably use inverse azimuths and compare
+ // the difference to 0 as well
+
+ // positive azimuth is on the right side
+ return math::equals(a_diff, 0)
+ || math::equals(a_diff, pi)
+ || math::equals(a_diff, -pi) ? 0
+ : a_diff > 0 ? -1 // right
+ : 1; // left
+ }
+
+private:
+ template <typename ResultType,
+ typename InverseFormulaType,
+ typename Point1,
+ typename Point2,
+ typename ModelT>
+ static inline ResultType azimuth(Point1 const& point1, Point2 const& point2, ModelT const& model)
+ {
+ return InverseFormulaType::apply(get_as_radian<0>(point1),
+ get_as_radian<1>(point1),
+ get_as_radian<0>(point2),
+ get_as_radian<1>(point2),
+ model).azimuth;
+ }
+
+ Model m_model;
+};
+
+} // detail
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace strategy::side
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_DETAIL_HPP
diff --git a/boost/geometry/strategies/geographic/side_thomas.hpp b/boost/geometry/strategies/geographic/side_thomas.hpp
new file mode 100644
index 0000000000..a96cabdaab
--- /dev/null
+++ b/boost/geometry/strategies/geographic/side_thomas.hpp
@@ -0,0 +1,55 @@
+// Boost.Geometry
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_THOMAS_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_THOMAS_HPP
+
+
+#include <boost/geometry/algorithms/detail/thomas_inverse.hpp>
+
+#include <boost/geometry/strategies/geographic/side_detail.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace side
+{
+
+/*!
+\brief Check at which side of a segment a point lies
+ left of segment (> 0), right of segment (< 0), on segment (0)
+\ingroup strategies
+\tparam Model Reference model of coordinate system.
+\tparam CalculationType \tparam_calculation
+ */
+template <typename Model, typename CalculationType = void>
+class thomas
+ : public detail::by_azimuth<geometry::detail::thomas_inverse, Model, CalculationType>
+{
+ typedef detail::by_azimuth<geometry::detail::thomas_inverse, Model, CalculationType> base_t;
+
+public:
+ thomas(Model const& model = Model())
+ : base_t(model)
+ {}
+};
+
+}} // namespace strategy::side
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_THOMAS_HPP
diff --git a/boost/geometry/strategies/geographic/side_vincenty.hpp b/boost/geometry/strategies/geographic/side_vincenty.hpp
new file mode 100644
index 0000000000..a8ef9550d6
--- /dev/null
+++ b/boost/geometry/strategies/geographic/side_vincenty.hpp
@@ -0,0 +1,55 @@
+// Boost.Geometry
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_VINCENTY_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_VINCENTY_HPP
+
+
+#include <boost/geometry/algorithms/detail/vincenty_inverse.hpp>
+
+#include <boost/geometry/strategies/geographic/side_detail.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace side
+{
+
+/*!
+\brief Check at which side of a segment a point lies
+ left of segment (> 0), right of segment (< 0), on segment (0)
+\ingroup strategies
+\tparam Model Reference model of coordinate system.
+\tparam CalculationType \tparam_calculation
+ */
+template <typename Model, typename CalculationType = void>
+class vincenty
+ : public detail::by_azimuth<geometry::detail::vincenty_inverse, Model, CalculationType>
+{
+ typedef detail::by_azimuth<geometry::detail::vincenty_inverse, Model, CalculationType> base_t;
+
+public:
+ vincenty(Model const& model = Model())
+ : base_t(model)
+ {}
+};
+
+}} // namespace strategy::side
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_VINCENTY_HPP
diff --git a/boost/geometry/strategies/intersection_result.hpp b/boost/geometry/strategies/intersection_result.hpp
index b467b92a7f..9c6d17ec5e 100644
--- a/boost/geometry/strategies/intersection_result.hpp
+++ b/boost/geometry/strategies/intersection_result.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -20,140 +25,6 @@
namespace boost { namespace geometry
{
-/*!
- \brief Dimensionally Extended 9 Intersection Matrix
- \details
- \ingroup overlay
- \see http://gis.hsr.ch/wiki/images/3/3d/9dem_springer.pdf
-*/
-struct de9im
-{
- int ii, ib, ie,
- bi, bb, be,
- ei, eb, ee;
-
- inline de9im()
- : ii(-1), ib(-1), ie(-1)
- , bi(-1), bb(-1), be(-1)
- , ei(-1), eb(-1), ee(-1)
- {
- }
-
- inline de9im(int ii0, int ib0, int ie0,
- int bi0, int bb0, int be0,
- int ei0, int eb0, int ee0)
- : ii(ii0), ib(ib0), ie(ie0)
- , bi(bi0), bb(bb0), be(be0)
- , ei(ei0), eb(eb0), ee(ee0)
- {}
-
- inline bool equals() const
- {
- return ii >= 0 && ie < 0 && be < 0 && ei < 0 && eb < 0;
- }
-
- inline bool disjoint() const
- {
- return ii < 0 && ib < 0 && bi < 0 && bb < 0;
- }
-
- inline bool intersects() const
- {
- return ii >= 0 || bb >= 0 || bi >= 0 || ib >= 0;
- }
-
- inline bool touches() const
- {
- return ii < 0 && (bb >= 0 || bi >= 0 || ib >= 0);
- }
-
- inline bool crosses() const
- {
- return (ii >= 0 && ie >= 0) || (ii == 0);
- }
-
- inline bool overlaps() const
- {
- return ii >= 0 && ie >= 0 && ei >= 0;
- }
-
- inline bool within() const
- {
- return ii >= 0 && ie < 0 && be < 0;
- }
-
- inline bool contains() const
- {
- return ii >= 0 && ei < 0 && eb < 0;
- }
-
-
- static inline char as_char(int v)
- {
- return v >= 0 && v < 10 ? static_cast<char>('0' + v) : '-';
- }
-
-#if defined(HAVE_MATRIX_AS_STRING)
- inline std::string matrix_as_string(std::string const& tab, std::string const& nl) const
- {
- std::string ret;
- ret.reserve(9 + tab.length() * 3 + nl.length() * 3);
- ret += tab; ret += as_char(ii); ret += as_char(ib); ret += as_char(ie); ret += nl;
- ret += tab; ret += as_char(bi); ret += as_char(bb); ret += as_char(be); ret += nl;
- ret += tab; ret += as_char(ei); ret += as_char(eb); ret += as_char(ee);
- return ret;
- }
-
- inline std::string matrix_as_string() const
- {
- return matrix_as_string("", "");
- }
-#endif
-
-};
-
-struct de9im_segment : public de9im
-{
- bool collinear; // true if segments are aligned (for equal,overlap,touch)
- bool opposite; // true if direction is reversed (for equal,overlap,touch)
- bool parallel; // true if disjoint but parallel
- bool degenerate; // true for segment(s) of zero length
-
- double ra, rb; // temp
-
- inline de9im_segment()
- : de9im()
- , collinear(false)
- , opposite(false)
- , parallel(false)
- , degenerate(false)
- {}
-
- inline de9im_segment(double a, double b,
- int ii0, int ib0, int ie0,
- int bi0, int bb0, int be0,
- int ei0, int eb0, int ee0,
- bool c = false, bool o = false, bool p = false, bool d = false)
- : de9im(ii0, ib0, ie0, bi0, bb0, be0, ei0, eb0, ee0)
- , collinear(c)
- , opposite(o)
- , parallel(p)
- , degenerate(d)
- , ra(a), rb(b)
- {}
-
-
-#if defined(HAVE_MATRIX_AS_STRING)
- inline std::string as_string() const
- {
- std::string ret = matrix_as_string();
- ret += collinear ? "c" : "-";
- ret += opposite ? "o" : "-";
- return ret;
- }
-#endif
-};
-
template <typename SegmentRatio>
struct fraction_type
{
@@ -209,7 +80,7 @@ struct segment_intersection_info
typedef PromotedType promoted_type;
CoordinateType dx_a, dy_a;
- CoordinateType dx_b, dy_b; // TODO b can be removed
+ CoordinateType dx_b, dy_b;
SegmentRatio robust_ra;
SegmentRatio robust_rb;
};
diff --git a/boost/geometry/strategies/spherical/area_huiller.hpp b/boost/geometry/strategies/spherical/area_huiller.hpp
index e55fdb2b0e..37d8d20124 100644
--- a/boost/geometry/strategies/spherical/area_huiller.hpp
+++ b/boost/geometry/strategies/spherical/area_huiller.hpp
@@ -1,6 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -31,18 +37,22 @@ namespace strategy { namespace area
\tparam PointOfSegment point type of segments of rings/polygons
\tparam CalculationType \tparam_calculation
\author Barend Gehrels. Adapted from:
-- http://www.soe.ucsc.edu/~pang/160/f98/Gems/GemsIV/sph_poly.c
+- http://webdocs.cs.ualberta.ca/~graphics/books/GraphicsGems/gemsiv/sph_poly.c
+- http://tog.acm.org/resources/GraphicsGems/gemsiv/sph_poly.c
- http://williams.best.vwh.net/avform.htm
-\note The version in Gems didn't account for polygons crossing the 180 meridian.
+\note The version in Graphics Gems IV (page 132-137) didn't account for
+polygons crossing the 0 and 180 meridians. The fix for this algorithm
+can be found in Graphics Gems V (pages 45-46). See:
+- http://kysmykseka.net/koti/wizardry/Game%20Development/Programming/Graphics%20Gems%204.pdf
+- http://kysmykseka.net/koti/wizardry/Game%20Development/Programming/Graphics%20Gems%205.pdf
\note This version works for convex and non-convex polygons, for 180 meridian
crossing polygons and for polygons with holes. However, some cases (especially
180 meridian cases) must still be checked.
\note The version which sums angles, which is often seen, doesn't handle non-convex
polygons correctly.
-\note The version which sums longitudes, see
-http://trs-new.jpl.nasa.gov/dspace/bitstream/2014/40409/1/07-03.pdf, is simple
-and works well in most cases but not in 180 meridian crossing cases. This probably
-could be solved.
+\note The version which sums longitudes, see http://hdl.handle.net/2014/40409,
+is simple and works well in most cases but not in 180 meridian crossing cases.
+This probably could be solved.
\note This version is made for spherical equatorial coordinate systems
@@ -113,8 +123,12 @@ public :
calculation_type const half = 0.5;
calculation_type const two = 2.0;
calculation_type const four = 4.0;
- calculation_type const two_pi = two * geometry::math::pi<calculation_type>();
- calculation_type const half_pi = half * geometry::math::pi<calculation_type>();
+ calculation_type const pi
+ = geometry::math::pi<calculation_type>();
+ calculation_type const two_pi
+ = geometry::math::two_pi<calculation_type>();
+ calculation_type const half_pi
+ = geometry::math::half_pi<calculation_type>();
// Distance p1 p2
calculation_type a = state.distance_over_unit_sphere.apply(p1, p2);
@@ -128,33 +142,31 @@ public :
// E: spherical excess, using l'Huiller's formula
// [tg(e / 4)]2 = tg[s / 2] tg[(s-a) / 2] tg[(s-b) / 2] tg[(s-c) / 2]
- calculation_type E = four
+ calculation_type excess = four
* atan(geometry::math::sqrt(geometry::math::abs(tan(s / two)
* tan((s - a) / two)
* tan((s - b) / two)
* tan((s - c) / two))));
- E = geometry::math::abs(E);
+ excess = geometry::math::abs(excess);
// In right direction: positive, add area. In left direction: negative, subtract area.
- // Longitude comparisons are not so obvious. If one is negative, other is positive,
+ // Longitude comparisons are not so obvious. If one is negative and other is positive,
// we have to take the dateline into account.
- // TODO: check this / enhance this, should be more robust. See also the "grow" for ll
- // TODO: use minmax or "smaller"/"compare" strategy for this
- calculation_type lon1 = geometry::get_as_radian<0>(p1) < 0
- ? geometry::get_as_radian<0>(p1) + two_pi
- : geometry::get_as_radian<0>(p1);
- calculation_type lon2 = geometry::get_as_radian<0>(p2) < 0
- ? geometry::get_as_radian<0>(p2) + two_pi
- : geometry::get_as_radian<0>(p2);
+ calculation_type lon_diff = geometry::get_as_radian<0>(p2)
+ - geometry::get_as_radian<0>(p1);
+ if (lon_diff <= 0)
+ {
+ lon_diff += two_pi;
+ }
- if (lon2 < lon1)
+ if (lon_diff > pi)
{
- E = -E;
+ excess = -excess;
}
- state.sum += E;
+ state.sum += excess;
}
}
diff --git a/boost/geometry/strategies/spherical/distance_cross_track.hpp b/boost/geometry/strategies/spherical/distance_cross_track.hpp
index 486c7effbd..31b59e77ff 100644
--- a/boost/geometry/strategies/spherical/distance_cross_track.hpp
+++ b/boost/geometry/strategies/spherical/distance_cross_track.hpp
@@ -340,6 +340,8 @@ public :
>
{};
+ typedef typename Strategy::radius_type radius_type;
+
inline cross_track()
{}
@@ -372,11 +374,16 @@ public :
typedef typename return_type<Point, PointOfSegment>::type return_type;
#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
- std::cout << "Course " << dsv(sp1) << " to " << dsv(p) << " " << crs_AD * geometry::math::r2d << std::endl;
- std::cout << "Course " << dsv(sp1) << " to " << dsv(sp2) << " " << crs_AB * geometry::math::r2d << std::endl;
- std::cout << "Course " << dsv(sp2) << " to " << dsv(p) << " " << crs_BD * geometry::math::r2d << std::endl;
- std::cout << "Projection AD-AB " << projection1 << " : " << d_crs1 * geometry::math::r2d << std::endl;
- std::cout << "Projection BD-BA " << projection2 << " : " << d_crs2 * geometry::math::r2d << std::endl;
+ std::cout << "Course " << dsv(sp1) << " to " << dsv(p) << " "
+ << crs_AD * geometry::math::r2d<return_type>() << std::endl;
+ std::cout << "Course " << dsv(sp1) << " to " << dsv(sp2) << " "
+ << crs_AB * geometry::math::r2d<return_type>() << std::endl;
+ std::cout << "Course " << dsv(sp2) << " to " << dsv(p) << " "
+ << crs_BD * geometry::math::r2d << std::endl;
+ std::cout << "Projection AD-AB " << projection1 << " : "
+ << d_crs1 * geometry::math::r2d<return_type>() << std::endl;
+ std::cout << "Projection BD-BA " << projection2 << " : "
+ << d_crs2 * geometry::math::r2d<return_type>() << std::endl;
#endif
// http://williams.best.vwh.net/avform.htm#XTE
@@ -487,6 +494,8 @@ public :
>
{};
+ typedef typename Strategy::radius_type radius_type;
+
inline cross_track()
{}
diff --git a/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp b/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp
index fe32f77236..14c5bd4eda 100644
--- a/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp
+++ b/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp
@@ -1,13 +1,14 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
-// Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -16,14 +17,23 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_POINT_BOX_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_POINT_BOX_HPP
+#include <boost/config.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_void.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+#include <boost/geometry/strategies/spherical/distance_cross_track.hpp>
#include <boost/geometry/util/math.hpp>
-#include <boost/geometry/util/calculation_type.hpp>
-
+#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
namespace boost { namespace geometry
@@ -32,131 +42,197 @@ namespace boost { namespace geometry
namespace strategy { namespace distance
{
+
+/*!
+\brief Strategy functor for distance point to box calculation
+\ingroup strategies
+\details Class which calculates the distance of a point to a box, for
+points and boxes on a sphere or globe
+\tparam CalculationType \tparam_calculation
+\tparam Strategy underlying point-segment distance strategy, defaults
+to cross track
+
+\qbk{
+[heading See also]
+[link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
+}
+
+*/
template
<
typename CalculationType = void,
- typename Strategy = haversine<double, CalculationType>
+ typename Strategy = cross_track<CalculationType>
>
class cross_track_point_box
{
public:
template <typename Point, typename Box>
struct return_type
- : promote_floating_point
- <
- typename select_calculation_type
- <
- Point,
- typename point_type<Box>::type,
- CalculationType
- >::type
- >
+ : services::return_type<Strategy, Point, typename point_type<Box>::type>
{};
+ typedef typename Strategy::radius_type radius_type;
+
inline cross_track_point_box()
{}
explicit inline cross_track_point_box(typename Strategy::radius_type const& r)
- : m_pp_strategy(r)
+ : m_ps_strategy(r)
{}
inline cross_track_point_box(Strategy const& s)
- : m_pp_strategy(s)
+ : m_ps_strategy(s)
{}
-
+
+
+ // It might be useful in the future
+ // to overload constructor with strategy info.
+ // crosstrack(...) {}
+
template <typename Point, typename Box>
inline typename return_type<Point, Box>::type
apply(Point const& point, Box const& box) const
{
-
#if !defined(BOOST_MSVC)
BOOST_CONCEPT_ASSERT
(
- (concept::PointDistanceStrategy
+ (concept::PointSegmentDistanceStrategy
<
- Strategy, Point,
- typename point_type<Box>::type
+ Strategy, Point, typename point_type<Box>::type
>)
);
#endif
+ // this method assumes that the coordinates of the point and
+ // the box are normalized
+
typedef typename return_type<Point, Box>::type return_type;
- typedef typename point_type<Box>::type box_point_t;
-
- // Create (counterclockwise) array of points, the fifth one closes it
- // If every point is on the LEFT side (=1) or ON the border (=0)
- // the distance should be equal to 0.
+ typedef typename point_type<Box>::type box_point_type;
// TODO: This strategy as well as other cross-track strategies
// and therefore e.g. spherical within(Point, Box) may not work
// properly for a Box degenerated to a Segment or Point
- boost::array<box_point_t, 5> bp;
- geometry::detail::assign_box_corners_oriented<true>(box, bp);
- bp[4] = bp[0];
+ box_point_type bottom_left, bottom_right, top_left, top_right;
+ geometry::detail::assign_box_corners(box,
+ bottom_left, bottom_right,
+ top_left, top_right);
+
+ return_type const plon = geometry::get_as_radian<0>(point);
+ return_type const plat = geometry::get_as_radian<1>(point);
+
+ return_type const lon_min = geometry::get_as_radian<0>(bottom_left);
+ return_type const lat_min = geometry::get_as_radian<1>(bottom_left);
+ return_type const lon_max = geometry::get_as_radian<0>(top_right);
+ return_type const lat_max = geometry::get_as_radian<1>(top_right);
+
+ return_type const pi = math::pi<return_type>();
+ return_type const two_pi = math::two_pi<return_type>();
+
+ // First check if the point is within the band defined by the
+ // minimum and maximum longitude of the box; if yes, determine
+ // if the point is above, below or inside the box and compute
+ // the distance (easy in this case)
+ //
+ // Notice that the point may not be inside the longitude range
+ // of the box, but the shifted point may be inside the
+ // longitude range of the box; in this case the point is still
+ // considered as inside the longitude range band of the box
+ if ((plon >= lon_min && plon <= lon_max) || plon + two_pi <= lon_max)
+ {
+ if (plat > lat_max)
+ {
+ return services::result_from_distance
+ <
+ Strategy, Point, box_point_type
+ >::apply(m_ps_strategy, radius() * (plat - lat_max));
+ }
+ else if (plat < lat_min)
+ {
+ return services::result_from_distance
+ <
+ Strategy, Point, box_point_type
+ >::apply(m_ps_strategy, radius() * (lat_min - plat));
+ }
+ else
+ {
+ BOOST_GEOMETRY_ASSERT(plat >= lat_min && plat <= lat_max);
+ return return_type(0);
+ }
+ }
- for (int i = 1; i < 5; i++)
+ // Otherwise determine which αμονγ the two medirian segments of the
+ // box the point is closest to, and compute the distance of
+ // the point to this closest segment
+
+ // Below lon_midway is the longitude of the meridian that:
+ // (1) is midway between the meridians of the left and right
+ // meridians of the box, and
+ // (2) does not intersect the box
+ return_type const two = 2.0;
+ bool use_left_segment;
+ if (lon_max > pi)
{
- box_point_t const& p1 = bp[i - 1];
- box_point_t const& p2 = bp[i];
+ // the box crosses the antimeridian
- return_type const crs_AD = geometry::detail::course<return_type>(p1, point);
- return_type const crs_AB = geometry::detail::course<return_type>(p1, p2);
- return_type const d_crs1 = crs_AD - crs_AB;
- return_type const sin_d_crs1 = sin(d_crs1);
+ // midway longitude = lon_min - (lon_min + (lon_max - 2 * pi)) / 2;
+ return_type const lon_midway = (lon_min - lon_max) / two + pi;
+ BOOST_GEOMETRY_ASSERT(lon_midway >= -pi && lon_midway <= pi);
- // this constant sin() is here to be consistent with the side strategy
- return_type const sigXTD = asin(sin(0.001) * sin_d_crs1);
+ use_left_segment = plon > lon_midway;
+ }
+ else
+ {
+ // the box does not cross the antimeridian
- // If the point is on the right side of the edge
- if ( sigXTD > 0 )
+ return_type const lon_sum = lon_min + lon_max;
+ if (math::equals(lon_sum, return_type(0)))
{
- return_type const crs_BA = crs_AB - geometry::math::pi<return_type>();
- return_type const crs_BD = geometry::detail::course<return_type>(p2, point);
- return_type const d_crs2 = crs_BD - crs_BA;
+ // special case: the box is symmetric with respect to
+ // the prime meridian; the midway meridian is the antimeridian
- return_type const projection1 = cos( d_crs1 );
- return_type const projection2 = cos( d_crs2 );
+ use_left_segment = plon < lon_min;
+ }
+ else
+ {
+ // midway long. = lon_min - (2 * pi - (lon_max - lon_min)) / 2;
+ return_type lon_midway = (lon_min + lon_max) / two - pi;
- if(projection1 > 0.0 && projection2 > 0.0)
+ // normalize the midway longitude
+ if (lon_midway > pi)
{
- return_type const d1 = m_pp_strategy.apply(p1, point);
- return_type const
- XTD = radius()
- * geometry::math::abs(
- asin( sin( d1 / radius() ) * sin_d_crs1 )
- );
-
- return return_type(XTD);
+ lon_midway -= two_pi;
}
- else
+ else if (lon_midway < -pi)
{
- // OPTIMIZATION
- // Return d1 if projection1 <= 0 and d2 if projection2 <= 0
- // if both == 0 then return d1 or d2
- // both shouldn't be < 0
-
- return_type const d1 = m_pp_strategy.apply(p1, point);
- return_type const d2 = m_pp_strategy.apply(p2, point);
-
- return return_type((std::min)( d1 , d2 ));
+ lon_midway += two_pi;
}
+ BOOST_GEOMETRY_ASSERT(lon_midway >= -pi && lon_midway <= pi);
+
+ // if lon_sum is positive the midway meridian is left
+ // of the box, or right of the box otherwise
+ use_left_segment = lon_sum > 0
+ ? (plon < lon_min && plon >= lon_midway)
+ : (plon <= lon_max || plon > lon_midway);
}
}
- // Return 0 if the point isn't on the right side of any segment
- return return_type(0);
+ return use_left_segment
+ ? m_ps_strategy.apply(point, bottom_left, top_left)
+ : m_ps_strategy.apply(point, bottom_right, top_right);
}
inline typename Strategy::radius_type radius() const
- { return m_pp_strategy.radius(); }
-
-private :
+ {
+ return m_ps_strategy.radius();
+ }
- Strategy m_pp_strategy;
+private:
+ Strategy m_ps_strategy;
};
+
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
@@ -170,67 +246,68 @@ struct tag<cross_track_point_box<CalculationType, Strategy> >
template <typename CalculationType, typename Strategy, typename P, typename Box>
struct return_type<cross_track_point_box<CalculationType, Strategy>, P, Box>
- : cross_track_point_box<CalculationType, Strategy>::template return_type<P, Box>
+ : cross_track_point_box
+ <
+ CalculationType, Strategy
+ >::template return_type<P, Box>
{};
template <typename CalculationType, typename Strategy>
struct comparable_type<cross_track_point_box<CalculationType, Strategy> >
{
- // There is no shortcut, so the strategy itself is its comparable type
- typedef cross_track_point_box<CalculationType, Strategy> type;
+ typedef cross_track_point_box
+ <
+ CalculationType, typename comparable_type<Strategy>::type
+ > type;
};
-template
-<
- typename CalculationType,
- typename Strategy
->
+template <typename CalculationType, typename Strategy>
struct get_comparable<cross_track_point_box<CalculationType, Strategy> >
{
- typedef typename comparable_type
- <
- cross_track_point_box<CalculationType, Strategy>
- >::type comparable_type;
-public :
- static inline comparable_type apply(
- cross_track_point_box<CalculationType, Strategy> const& strategy)
+ typedef cross_track_point_box<CalculationType, Strategy> this_strategy;
+ typedef typename comparable_type<this_strategy>::type comparable_type;
+
+public:
+ static inline comparable_type apply(this_strategy const& strategy)
{
- return cross_track_point_box<CalculationType, Strategy>(strategy.radius());
+ return comparable_type(strategy.radius());
}
};
-template
-<
- typename CalculationType,
- typename Strategy,
- typename P, typename Box
->
+template <typename CalculationType, typename Strategy, typename P, typename Box>
struct result_from_distance
<
- cross_track_point_box<CalculationType, Strategy>,
- P,
- Box
+ cross_track_point_box<CalculationType, Strategy>, P, Box
>
{
-private :
- typedef typename cross_track_point_box
+private:
+ typedef cross_track_point_box<CalculationType, Strategy> this_strategy;
+
+ typedef typename this_strategy::template return_type
<
- CalculationType, Strategy
- >::template return_type<P, Box> return_type;
-public :
+ P, Box
+ >::type return_type;
+
+public:
template <typename T>
- static inline return_type apply(
- cross_track_point_box<CalculationType, Strategy> const& ,
- T const& distance)
+ static inline return_type apply(this_strategy const& strategy,
+ T const& distance)
{
- return distance;
+ Strategy s(strategy.radius());
+
+ return result_from_distance
+ <
+ Strategy, P, typename point_type<Box>::type
+ >::apply(s, distance);
}
};
+// define cross_track_point_box<default_point_segment_strategy> as
+// default point-box strategy for the spherical equatorial coordinate system
template <typename Point, typename Box, typename Strategy>
struct default_strategy
<
@@ -247,7 +324,7 @@ struct default_strategy
boost::is_void<Strategy>,
typename default_strategy
<
- point_tag, point_tag,
+ point_tag, segment_tag,
Point, typename point_type<Box>::type,
spherical_equatorial_tag, spherical_equatorial_tag
>::type,
diff --git a/boost/geometry/strategies/strategies.hpp b/boost/geometry/strategies/strategies.hpp
index bf436dba2b..28850020af 100644
--- a/boost/geometry/strategies/strategies.hpp
+++ b/boost/geometry/strategies/strategies.hpp
@@ -4,8 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -14,8 +16,6 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_STRATEGIES_STRATEGIES_HPP
#define BOOST_GEOMETRY_STRATEGIES_STRATEGIES_HPP
@@ -64,7 +64,11 @@
#include <boost/geometry/strategies/spherical/ssf.hpp>
#include <boost/geometry/strategies/geographic/distance_andoyer.hpp>
+#include <boost/geometry/strategies/geographic/distance_thomas.hpp>
#include <boost/geometry/strategies/geographic/distance_vincenty.hpp>
+//#include <boost/geometry/strategies/geographic/side_andoyer.hpp>
+//#include <boost/geometry/strategies/geographic/side_thomas.hpp>
+//#include <boost/geometry/strategies/geographic/side_vincenty.hpp>
#include <boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp>
#include <boost/geometry/strategies/agnostic/buffer_distance_asymmetric.hpp>
diff --git a/boost/geometry/strategies/strategy_transform.hpp b/boost/geometry/strategies/strategy_transform.hpp
index 9d3b1d910c..99fcb720c6 100644
--- a/boost/geometry/strategies/strategy_transform.hpp
+++ b/boost/geometry/strategies/strategy_transform.hpp
@@ -1,8 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -28,6 +33,7 @@
#include <boost/geometry/strategies/transform.hpp>
#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
namespace boost { namespace geometry
@@ -130,7 +136,15 @@ struct degree_radian_vv
assert_dimension<P1, 2>();
assert_dimension<P2, 2>();
- detail::transform_coordinates<P1, P2, 0, 2, F>::transform(p1, p2, math::d2r);
+ typedef typename promote_floating_point
+ <
+ typename select_coordinate_type<P1, P2>::type
+ >::type calculation_type;
+
+ detail::transform_coordinates
+ <
+ P1, P2, 0, 2, F
+ >::transform(p1, p2, math::d2r<calculation_type>());
return true;
}
};
@@ -143,7 +157,16 @@ struct degree_radian_vv_3
assert_dimension<P1, 3>();
assert_dimension<P2, 3>();
- detail::transform_coordinates<P1, P2, 0, 2, F>::transform(p1, p2, math::d2r);
+ typedef typename promote_floating_point
+ <
+ typename select_coordinate_type<P1, P2>::type
+ >::type calculation_type;
+
+ detail::transform_coordinates
+ <
+ P1, P2, 0, 2, F
+ >::transform(p1, p2, math::d2r<calculation_type>());
+
// Copy height or other third dimension
set<2>(p2, get<2>(p1));
return true;
diff --git a/boost/geometry/strategies/transform/matrix_transformers.hpp b/boost/geometry/strategies/transform/matrix_transformers.hpp
index 27a3a2ae80..699b91b3aa 100644
--- a/boost/geometry/strategies/transform/matrix_transformers.hpp
+++ b/boost/geometry/strategies/transform/matrix_transformers.hpp
@@ -1,8 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -40,6 +45,7 @@
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
@@ -340,7 +346,8 @@ struct as_radian<degree>
template <typename T>
static inline T get(T const& value)
{
- return value * math::d2r;
+ typedef typename promote_floating_point<T>::type promoted_type;
+ return value * math::d2r<promoted_type>();
}
};
diff --git a/boost/geometry/util/math.hpp b/boost/geometry/util/math.hpp
index 4042f4e4cd..d84b11f480 100644
--- a/boost/geometry/util/math.hpp
+++ b/boost/geometry/util/math.hpp
@@ -26,12 +26,11 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/math/constants/constants.hpp>
-#ifdef BOOST_GEOMETRY_SQRT_CHECK_FINITENESS
#include <boost/math/special_functions/fpclassify.hpp>
-#endif // BOOST_GEOMETRY_SQRT_CHECK_FINITENESS
-#include <boost/math/special_functions/round.hpp>
+//#include <boost/math/special_functions/round.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits/is_fundamental.hpp>
+#include <boost/type_traits/is_integral.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
@@ -86,6 +85,9 @@ struct abs<T, true>
{
static inline T apply(T const& value)
{
+ using ::fabs;
+ using std::fabs; // for long double
+
return fabs(value);
}
};
@@ -161,7 +163,17 @@ struct equals<Type, true>
return true;
}
- return abs<Type>::apply(a - b) <= std::numeric_limits<Type>::epsilon() * policy.apply(a, b);
+ if (boost::math::isfinite(a) && boost::math::isfinite(b))
+ {
+ // If a is INF and b is e.g. 0, the expression below returns true
+ // but the values are obviously not equal, hence the condition
+ return abs<Type>::apply(a - b)
+ <= std::numeric_limits<Type>::epsilon() * policy.apply(a, b);
+ }
+ else
+ {
+ return a == b;
+ }
}
};
@@ -295,8 +307,66 @@ struct square_root<T, true>
};
+
+template
+<
+ typename T,
+ bool IsFundemantal = boost::is_fundamental<T>::value /* false */
+>
+struct modulo
+{
+ typedef T return_type;
+
+ static inline T apply(T const& value1, T const& value2)
+ {
+ // for non-fundamental number types assume that a free
+ // function mod() is defined either:
+ // 1) at T's scope, or
+ // 2) at global scope
+ return mod(value1, value2);
+ }
+};
+
+template
+<
+ typename Fundamental,
+ bool IsIntegral = boost::is_integral<Fundamental>::value
+>
+struct modulo_for_fundamental
+{
+ typedef Fundamental return_type;
+
+ static inline Fundamental apply(Fundamental const& value1,
+ Fundamental const& value2)
+ {
+ return value1 % value2;
+ }
+};
+
+// specialization for floating-point numbers
+template <typename Fundamental>
+struct modulo_for_fundamental<Fundamental, false>
+{
+ typedef Fundamental return_type;
+
+ static inline Fundamental apply(Fundamental const& value1,
+ Fundamental const& value2)
+ {
+ return std::fmod(value1, value2);
+ }
+};
+
+// specialization for fundamental number type
+template <typename Fundamental>
+struct modulo<Fundamental, true>
+ : modulo_for_fundamental<Fundamental>
+{};
+
+
+
/*!
-\brief Short construct to enable partial specialization for PI, currently not possible in Math.
+\brief Short constructs to enable partial specialization for PI, 2*PI
+ and PI/2, currently not possible in Math.
*/
template <typename T>
struct define_pi
@@ -309,6 +379,26 @@ struct define_pi
};
template <typename T>
+struct define_two_pi
+{
+ static inline T apply()
+ {
+ // Default calls Boost.Math
+ return boost::math::constants::two_pi<T>();
+ }
+};
+
+template <typename T>
+struct define_half_pi
+{
+ static inline T apply()
+ {
+ // Default calls Boost.Math
+ return boost::math::constants::half_pi<T>();
+ }
+};
+
+template <typename T>
struct relaxed_epsilon
{
static inline T apply(const T& factor)
@@ -321,7 +411,7 @@ struct relaxed_epsilon
template <typename Result, typename Source,
bool ResultIsInteger = std::numeric_limits<Result>::is_integer,
bool SourceIsInteger = std::numeric_limits<Source>::is_integer>
-struct round
+struct rounding_cast
{
static inline Result apply(Source const& v)
{
@@ -329,16 +419,25 @@ struct round
}
};
+// TtoT
+template <typename Source, bool ResultIsInteger, bool SourceIsInteger>
+struct rounding_cast<Source, Source, ResultIsInteger, SourceIsInteger>
+{
+ static inline Source apply(Source const& v)
+ {
+ return v;
+ }
+};
+
// FtoI
template <typename Result, typename Source>
-struct round<Result, Source, true, false>
+struct rounding_cast<Result, Source, true, false>
{
static inline Result apply(Source const& v)
{
- namespace bmp = boost::math::policies;
- // ignore rounding errors for backward compatibility
- typedef bmp::policy< bmp::rounding_error<bmp::ignore_error> > policy;
- return boost::numeric_cast<Result>(boost::math::round(v, policy()));
+ return boost::numeric_cast<Result>(v < Source(0) ?
+ v - Source(0.5) :
+ v + Source(0.5));
}
};
@@ -350,6 +449,12 @@ template <typename T>
inline T pi() { return detail::define_pi<T>::apply(); }
template <typename T>
+inline T two_pi() { return detail::define_two_pi<T>::apply(); }
+
+template <typename T>
+inline T half_pi() { return detail::define_half_pi<T>::apply(); }
+
+template <typename T>
inline T relaxed_epsilon(T const& factor)
{
return detail::relaxed_epsilon<T>::apply(factor);
@@ -408,9 +513,20 @@ inline bool larger(T1 const& a, T2 const& b)
}
+template <typename T>
+inline T d2r()
+{
+ static T const conversion_coefficient = geometry::math::pi<T>() / T(180.0);
+ return conversion_coefficient;
+}
+
+template <typename T>
+inline T r2d()
+{
+ static T const conversion_coefficient = T(180.0) / geometry::math::pi<T>();
+ return conversion_coefficient;
+}
-double const d2r = geometry::math::pi<double>() / 180.0;
-double const r2d = 1.0 / d2r;
/*!
\brief Calculates the haversine of an angle
@@ -455,6 +571,24 @@ sqrt(T const& value)
}
/*!
+\brief Short utility to return the modulo of two values
+\ingroup utility
+\param value1 First value
+\param value2 Second value
+\return The result of the modulo operation on the (ordered) pair
+(value1, value2)
+*/
+template <typename T>
+inline typename detail::modulo<T>::return_type
+mod(T const& value1, T const& value2)
+{
+ return detail::modulo
+ <
+ T, boost::is_fundamental<T>::value
+ >::apply(value1, value2);
+}
+
+/*!
\brief Short utility to workaround gcc/clang problem that abs is converting to integer
and that older versions of MSVC does not support abs of long long...
\ingroup utility
@@ -470,23 +604,24 @@ inline T abs(T const& value)
\ingroup utility
*/
template <typename T>
-static inline int sign(T const& value)
+inline int sign(T const& value)
{
T const zero = T();
return value > zero ? 1 : value < zero ? -1 : 0;
}
/*!
-\brief Short utility to calculate the rounded value of a number.
+\brief Short utility to cast a value possibly rounding it to the nearest
+ integral value.
\ingroup utility
\note If the source T is NOT an integral type and Result is an integral type
the value is rounded towards the closest integral value. Otherwise it's
- casted.
+ casted without rounding.
*/
template <typename Result, typename T>
-inline Result round(T const& v)
+inline Result rounding_cast(T const& v)
{
- return detail::round<Result, T>::apply(v);
+ return detail::rounding_cast<Result, T>::apply(v);
}
} // namespace math
diff --git a/boost/geometry/util/normalize_spheroidal_box_coordinates.hpp b/boost/geometry/util/normalize_spheroidal_box_coordinates.hpp
new file mode 100644
index 0000000000..eb947bb092
--- /dev/null
+++ b/boost/geometry/util/normalize_spheroidal_box_coordinates.hpp
@@ -0,0 +1,160 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
+#define BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace math
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template <typename Units, typename CoordinateType>
+class normalize_spheroidal_box_coordinates
+{
+private:
+ typedef normalize_spheroidal_coordinates<Units, CoordinateType> normalize;
+ typedef constants_on_spheroid<CoordinateType, Units> constants;
+
+ static inline bool is_band(CoordinateType const& longitude1,
+ CoordinateType const& longitude2)
+ {
+ return ! math::smaller(math::abs(longitude1 - longitude2),
+ constants::period());
+ }
+
+public:
+ static inline void apply(CoordinateType& longitude1,
+ CoordinateType& latitude1,
+ CoordinateType& longitude2,
+ CoordinateType& latitude2,
+ bool band)
+ {
+ normalize::apply(longitude1, latitude1, false);
+ normalize::apply(longitude2, latitude2, false);
+
+ if (math::equals(latitude1, constants::min_latitude())
+ && math::equals(latitude2, constants::min_latitude()))
+ {
+ // box degenerates to the south pole
+ longitude1 = longitude2 = CoordinateType(0);
+ }
+ else if (math::equals(latitude1, constants::max_latitude())
+ && math::equals(latitude2, constants::max_latitude()))
+ {
+ // box degenerates to the north pole
+ longitude1 = longitude2 = CoordinateType(0);
+ }
+ else if (band)
+ {
+ // the box is a band between two small circles (parallel
+ // to the equator) on the spheroid
+ longitude1 = constants::min_longitude();
+ longitude2 = constants::max_longitude();
+ }
+ else if (longitude1 > longitude2)
+ {
+ // the box crosses the antimeridian, so we need to adjust
+ // the longitudes
+ longitude2 += constants::period();
+ }
+
+#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
+ BOOST_GEOMETRY_ASSERT(! math::larger(latitude1, latitude2));
+ BOOST_GEOMETRY_ASSERT(! math::smaller(latitude1, constants::min_latitude()));
+ BOOST_GEOMETRY_ASSERT(! math::larger(latitude2, constants::max_latitude()));
+#endif
+
+ BOOST_GEOMETRY_ASSERT(! math::larger(longitude1, longitude2));
+ BOOST_GEOMETRY_ASSERT(! math::smaller(longitude1, constants::min_longitude()));
+ BOOST_GEOMETRY_ASSERT
+ (! math::larger(longitude2 - longitude1, constants::period()));
+ }
+
+ static inline void apply(CoordinateType& longitude1,
+ CoordinateType& latitude1,
+ CoordinateType& longitude2,
+ CoordinateType& latitude2)
+ {
+ bool const band = is_band(longitude1, longitude2);
+
+ apply(longitude1, latitude1, longitude2, latitude2, band);
+ }
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+\brief Short utility to normalize the coordinates of a box on a spheroid
+\tparam Units The units of the coordindate system in the spheroid
+\tparam CoordinateType The type of the coordinates
+\param longitude1 Minimum longitude of the box
+\param latitude1 Minimum latitude of the box
+\param longitude2 Maximum longitude of the box
+\param latitude2 Maximum latitude of the box
+\ingroup utility
+*/
+template <typename Units, typename CoordinateType>
+inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
+ CoordinateType& latitude1,
+ CoordinateType& longitude2,
+ CoordinateType& latitude2)
+{
+ detail::normalize_spheroidal_box_coordinates
+ <
+ Units, CoordinateType
+ >::apply(longitude1, latitude1, longitude2, latitude2);
+}
+
+/*!
+\brief Short utility to normalize the coordinates of a box on a spheroid
+\tparam Units The units of the coordindate system in the spheroid
+\tparam CoordinateType The type of the coordinates
+\param longitude1 Minimum longitude of the box
+\param latitude1 Minimum latitude of the box
+\param longitude2 Maximum longitude of the box
+\param latitude2 Maximum latitude of the box
+\param band Indicates whether the box should be treated as a band or
+ not and avoid the computation done in the other version of the function
+\ingroup utility
+*/
+template <typename Units, typename CoordinateType>
+inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
+ CoordinateType& latitude1,
+ CoordinateType& longitude2,
+ CoordinateType& latitude2,
+ bool band)
+{
+ detail::normalize_spheroidal_box_coordinates
+ <
+ Units, CoordinateType
+ >::apply(longitude1, latitude1, longitude2, latitude2, band);
+}
+
+
+} // namespace math
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
diff --git a/boost/geometry/util/normalize_spheroidal_coordinates.hpp b/boost/geometry/util/normalize_spheroidal_coordinates.hpp
new file mode 100644
index 0000000000..72dfa5a6f1
--- /dev/null
+++ b/boost/geometry/util/normalize_spheroidal_coordinates.hpp
@@ -0,0 +1,218 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_COORDINATES_HPP
+#define BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_COORDINATES_HPP
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace math
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template <typename CoordinateType, typename Units>
+struct constants_on_spheroid
+{
+ static inline CoordinateType period()
+ {
+ return math::two_pi<CoordinateType>();
+ }
+
+ static inline CoordinateType half_period()
+ {
+ return math::pi<CoordinateType>();
+ }
+
+ static inline CoordinateType min_longitude()
+ {
+ static CoordinateType const minus_pi = -math::pi<CoordinateType>();
+ return minus_pi;
+ }
+
+ static inline CoordinateType max_longitude()
+ {
+ return math::pi<CoordinateType>();
+ }
+
+ static inline CoordinateType min_latitude()
+ {
+ static CoordinateType const minus_half_pi
+ = -math::half_pi<CoordinateType>();
+ return minus_half_pi;
+ }
+
+ static inline CoordinateType max_latitude()
+ {
+ return math::half_pi<CoordinateType>();
+ }
+};
+
+template <typename CoordinateType>
+struct constants_on_spheroid<CoordinateType, degree>
+{
+ static inline CoordinateType period()
+ {
+ return CoordinateType(360.0);
+ }
+
+ static inline CoordinateType half_period()
+ {
+ return CoordinateType(180.0);
+ }
+
+ static inline CoordinateType min_longitude()
+ {
+ return CoordinateType(-180.0);
+ }
+
+ static inline CoordinateType max_longitude()
+ {
+ return CoordinateType(180.0);
+ }
+
+ static inline CoordinateType min_latitude()
+ {
+ return CoordinateType(-90.0);
+ }
+
+ static inline CoordinateType max_latitude()
+ {
+ return CoordinateType(90.0);
+ }
+};
+
+
+template <typename Units, typename CoordinateType>
+class normalize_spheroidal_coordinates
+{
+ typedef constants_on_spheroid<CoordinateType, Units> constants;
+
+protected:
+ static inline CoordinateType normalize_up(CoordinateType const& value)
+ {
+ return
+ math::mod(value + constants::half_period(), constants::period())
+ - constants::half_period();
+ }
+
+ static inline CoordinateType normalize_down(CoordinateType const& value)
+ {
+ return
+ math::mod(value - constants::half_period(), constants::period())
+ + constants::half_period();
+ }
+
+public:
+ static inline void apply(CoordinateType& longitude,
+ CoordinateType& latitude,
+ bool normalize_poles = true)
+ {
+#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
+ // normalize latitude
+ if (math::larger(latitude, constants::half_period()))
+ {
+ latitude = normalize_up(latitude);
+ }
+ else if (math::smaller(latitude, -constants::half_period()))
+ {
+ latitude = normalize_down(latitude);
+ }
+
+ // fix latitude range
+ if (latitude < constants::min_latitude())
+ {
+ latitude = -constants::half_period() - latitude;
+ longitude -= constants::half_period();
+ }
+ else if (latitude > constants::max_latitude())
+ {
+ latitude = constants::half_period() - latitude;
+ longitude -= constants::half_period();
+ }
+#endif // BOOST_GEOMETRY_NORMALIZE_LATITUDE
+
+ // normalize longitude
+ if (math::equals(math::abs(longitude), constants::half_period()))
+ {
+ longitude = constants::half_period();
+ }
+ else if (longitude > constants::half_period())
+ {
+ longitude = normalize_up(longitude);
+ if (math::equals(longitude, -constants::half_period()))
+ {
+ longitude = constants::half_period();
+ }
+ }
+ else if (longitude < -constants::half_period())
+ {
+ longitude = normalize_down(longitude);
+ }
+
+ // finally normalize poles
+ if (normalize_poles)
+ {
+ if (math::equals(math::abs(latitude), constants::max_latitude()))
+ {
+ // for the north and south pole we set the longitude to 0
+ // (works for both radians and degrees)
+ longitude = CoordinateType(0);
+ }
+ }
+
+#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
+ BOOST_GEOMETRY_ASSERT(! math::larger(constants::min_latitude(), latitude));
+ BOOST_GEOMETRY_ASSERT(! math::larger(latitude, constants::max_latitude()));
+#endif // BOOST_GEOMETRY_NORMALIZE_LATITUDE
+
+ BOOST_GEOMETRY_ASSERT(math::smaller(constants::min_longitude(), longitude));
+ BOOST_GEOMETRY_ASSERT(! math::larger(longitude, constants::max_longitude()));
+ }
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+\brief Short utility to normalize the coordinates on a spheroid
+\tparam Units The units of the coordindate system in the spheroid
+\tparam CoordinateType The type of the coordinates
+\param longitude Longitude
+\param latitude Latitude
+\ingroup utility
+*/
+template <typename Units, typename CoordinateType>
+inline void normalize_spheroidal_coordinates(CoordinateType& longitude,
+ CoordinateType& latitude)
+{
+ detail::normalize_spheroidal_coordinates
+ <
+ Units, CoordinateType
+ >::apply(longitude, latitude);
+}
+
+
+} // namespace math
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_COORDINATES_HPP
diff --git a/boost/geometry/util/range.hpp b/boost/geometry/util/range.hpp
index cf69413411..0f480df58a 100644
--- a/boost/geometry/util/range.hpp
+++ b/boost/geometry/util/range.hpp
@@ -16,7 +16,6 @@
#include <algorithm>
-#include <boost/assert.hpp>
#include <boost/concept_check.hpp>
#include <boost/config.hpp>
#include <boost/range/concepts.hpp>
@@ -26,6 +25,7 @@
#include <boost/range/size.hpp>
#include <boost/type_traits/is_convertible.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/mutable_range.hpp>
namespace boost { namespace geometry { namespace range {
@@ -59,7 +59,7 @@ inline typename boost::range_iterator<RandomAccessRange const>::type
pos(RandomAccessRange const& rng,
typename boost::range_size<RandomAccessRange const>::type i)
{
- BOOST_ASSERT(i <= boost::size(rng));
+ BOOST_GEOMETRY_ASSERT(i <= boost::size(rng));
return detail::pos<RandomAccessRange const>::apply(rng, i);
}
@@ -72,7 +72,7 @@ inline typename boost::range_iterator<RandomAccessRange>::type
pos(RandomAccessRange & rng,
typename boost::range_size<RandomAccessRange>::type i)
{
- BOOST_ASSERT(i <= boost::size(rng));
+ BOOST_GEOMETRY_ASSERT(i <= boost::size(rng));
return detail::pos<RandomAccessRange>::apply(rng, i);
}
@@ -85,7 +85,7 @@ inline typename boost::range_reference<RandomAccessRange const>::type
at(RandomAccessRange const& rng,
typename boost::range_size<RandomAccessRange const>::type i)
{
- BOOST_ASSERT(i < boost::size(rng));
+ BOOST_GEOMETRY_ASSERT(i < boost::size(rng));
return * detail::pos<RandomAccessRange const>::apply(rng, i);
}
@@ -98,7 +98,7 @@ inline typename boost::range_reference<RandomAccessRange>::type
at(RandomAccessRange & rng,
typename boost::range_size<RandomAccessRange>::type i)
{
- BOOST_ASSERT(i < boost::size(rng));
+ BOOST_GEOMETRY_ASSERT(i < boost::size(rng));
return * detail::pos<RandomAccessRange>::apply(rng, i);
}
@@ -110,7 +110,7 @@ template <typename Range>
inline typename boost::range_reference<Range const>::type
front(Range const& rng)
{
- BOOST_ASSERT(!boost::empty(rng));
+ BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
return *boost::begin(rng);
}
@@ -122,7 +122,7 @@ template <typename Range>
inline typename boost::range_reference<Range>::type
front(Range & rng)
{
- BOOST_ASSERT(!boost::empty(rng));
+ BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
return *boost::begin(rng);
}
@@ -137,7 +137,7 @@ inline typename boost::range_reference<BidirectionalRange const>::type
back(BidirectionalRange const& rng)
{
BOOST_RANGE_CONCEPT_ASSERT(( boost::BidirectionalRangeConcept<BidirectionalRange const> ));
- BOOST_ASSERT(!boost::empty(rng));
+ BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
return *(boost::rbegin(rng));
}
@@ -150,7 +150,7 @@ inline typename boost::range_reference<BidirectionalRange>::type
back(BidirectionalRange & rng)
{
BOOST_RANGE_CONCEPT_ASSERT((boost::BidirectionalRangeConcept<BidirectionalRange>));
- BOOST_ASSERT(!boost::empty(rng));
+ BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
return *(boost::rbegin(rng));
}
@@ -200,7 +200,7 @@ inline void resize(Range & rng,
template <typename Range>
inline void pop_back(Range & rng)
{
- BOOST_ASSERT(!boost::empty(rng));
+ BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
range::resize(rng, boost::size(rng) - 1);
}
@@ -260,8 +260,8 @@ inline typename boost::range_iterator<Range>::type
erase(Range & rng,
typename boost::range_iterator<Range>::type it)
{
- BOOST_ASSERT(!boost::empty(rng));
- BOOST_ASSERT(it != boost::end(rng));
+ BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
+ BOOST_GEOMETRY_ASSERT(it != boost::end(rng));
typename boost::range_difference<Range>::type const
d = std::distance(boost::begin(rng), it);
@@ -314,10 +314,10 @@ erase(Range & rng,
{
typename boost::range_difference<Range>::type const
diff = std::distance(first, last);
- BOOST_ASSERT(diff >= 0);
+ BOOST_GEOMETRY_ASSERT(diff >= 0);
std::size_t const count = static_cast<std::size_t>(diff);
- BOOST_ASSERT(count <= boost::size(rng));
+ BOOST_GEOMETRY_ASSERT(count <= boost::size(rng));
if ( count > 0 )
{
diff --git a/boost/geometry/views/detail/boundary_view.hpp b/boost/geometry/views/detail/boundary_view.hpp
new file mode 100644
index 0000000000..43bd5b202d
--- /dev/null
+++ b/boost/geometry/views/detail/boundary_view.hpp
@@ -0,0 +1,16 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_VIEWS_DETAIL_BOUNDARY_VIEW_HPP
+#define BOOST_GEOMETRY_VIEWS_DETAIL_BOUNDARY_VIEW_HPP
+
+#include <boost/geometry/views/detail/boundary_view/interface.hpp>
+#include <boost/geometry/views/detail/boundary_view/implementation.hpp>
+
+#endif // BOOST_GEOMETRY_VIEWS_DETAIL_BOUNDARY_VIEW_HPP
diff --git a/boost/geometry/views/detail/boundary_view/implementation.hpp b/boost/geometry/views/detail/boundary_view/implementation.hpp
new file mode 100644
index 0000000000..e6a09afd68
--- /dev/null
+++ b/boost/geometry/views/detail/boundary_view/implementation.hpp
@@ -0,0 +1,466 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_VIEWS_DETAIL_BOUNDARY_VIEW_IMPLEMENTATION_HPP
+#define BOOST_GEOMETRY_VIEWS_DETAIL_BOUNDARY_VIEW_IMPLEMENTATION_HPP
+
+#include <cstddef>
+#include <algorithm>
+#include <iterator>
+#include <memory>
+#include <new>
+#include <utility>
+#include <vector>
+
+#include <boost/core/addressof.hpp>
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/range.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/iterators/flatten_iterator.hpp>
+
+#include <boost/geometry/util/range.hpp>
+
+#include <boost/geometry/views/closeable_view.hpp>
+
+#include <boost/geometry/algorithms/num_interior_rings.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace boundary_views
+{
+
+
+template
+<
+ typename Polygon,
+ typename Value = typename ring_type<Polygon>::type,
+ typename Reference = typename ring_return_type<Polygon>::type,
+ typename Difference = typename boost::range_difference
+ <
+ typename boost::remove_reference
+ <
+ typename interior_return_type<Polygon>::type
+ >::type
+ >::type
+>
+class polygon_rings_iterator
+ : public boost::iterator_facade
+ <
+ polygon_rings_iterator<Polygon, Value, Reference, Difference>,
+ Value,
+ boost::random_access_traversal_tag,
+ Reference,
+ Difference
+ >
+{
+ typedef typename boost::range_size
+ <
+ typename boost::remove_reference
+ <
+ typename interior_return_type<Polygon>::type
+ >::type
+ >::type size_type;
+
+public:
+ // default constructor
+ polygon_rings_iterator()
+ : m_polygon(NULL)
+ , m_index(0)
+ {}
+
+ // for begin
+ polygon_rings_iterator(Polygon& polygon)
+ : m_polygon(boost::addressof(polygon))
+ , m_index(0)
+ {}
+
+ // for end
+ polygon_rings_iterator(Polygon& polygon, bool)
+ : m_polygon(boost::addressof(polygon))
+ , m_index(static_cast<size_type>(num_rings(polygon)))
+ {}
+
+ template
+ <
+ typename OtherPolygon,
+ typename OtherValue,
+ typename OtherReference,
+ typename OtherDifference
+ >
+ polygon_rings_iterator(polygon_rings_iterator
+ <
+ OtherPolygon,
+ OtherValue,
+ OtherReference,
+ OtherDifference
+ > const& other)
+ : m_polygon(other.m_polygon)
+ , m_index(other.m_index)
+ {
+ static const bool is_convertible
+ = boost::is_convertible<OtherPolygon, Polygon>::value;
+
+ BOOST_MPL_ASSERT_MSG((is_convertible),
+ NOT_CONVERTIBLE,
+ (types<OtherPolygon>));
+ }
+
+private:
+ friend class boost::iterator_core_access;
+
+ template
+ <
+ typename OtherPolygon,
+ typename OtherValue,
+ typename OtherReference,
+ typename OtherDifference
+ >
+ friend class polygon_rings_iterator;
+
+
+ static inline std::size_t num_rings(Polygon const& polygon)
+ {
+ return geometry::num_interior_rings(polygon) + 1;
+ }
+
+ inline Reference dereference() const
+ {
+ if (m_index == 0)
+ {
+ return exterior_ring(*m_polygon);
+ }
+ return range::at(interior_rings(*m_polygon), m_index - 1);
+ }
+
+ template
+ <
+ typename OtherPolygon,
+ typename OtherValue,
+ typename OtherReference,
+ typename OtherDifference
+ >
+ inline bool equal(polygon_rings_iterator
+ <
+ OtherPolygon,
+ OtherValue,
+ OtherReference,
+ OtherDifference
+ > const& other) const
+ {
+ BOOST_GEOMETRY_ASSERT(m_polygon == other.m_polygon);
+ return m_index == other.m_index;
+ }
+
+ inline void increment()
+ {
+ ++m_index;
+ }
+
+ inline void decrement()
+ {
+ --m_index;
+ }
+
+ template
+ <
+ typename OtherPolygon,
+ typename OtherValue,
+ typename OtherReference,
+ typename OtherDifference
+ >
+ inline Difference distance_to(polygon_rings_iterator
+ <
+ OtherPolygon,
+ OtherValue,
+ OtherReference,
+ OtherDifference
+ > const& other) const
+ {
+ return static_cast<Difference>(other.m_index)
+ - static_cast<Difference>(m_index);
+ }
+
+ inline void advance(Difference n)
+ {
+ m_index += n;
+ }
+
+private:
+ Polygon* m_polygon;
+ size_type m_index;
+};
+
+
+template <typename Ring>
+class ring_boundary : closeable_view<Ring, closure<Ring>::value>::type
+{
+private:
+ typedef typename closeable_view<Ring, closure<Ring>::value>::type base_type;
+
+public:
+ typedef typename base_type::iterator iterator;
+ typedef typename base_type::const_iterator const_iterator;
+
+ typedef linestring_tag tag_type;
+
+ explicit ring_boundary(Ring& ring)
+ : base_type(ring) {}
+
+ iterator begin() { return base_type::begin(); }
+ iterator end() { return base_type::end(); }
+ const_iterator begin() const { return base_type::begin(); }
+ const_iterator end() const { return base_type::end(); }
+};
+
+
+template <typename Geometry, typename Tag = typename tag<Geometry>::type>
+struct num_rings
+{};
+
+template <typename Polygon>
+struct num_rings<Polygon, polygon_tag>
+{
+ static inline std::size_t apply(Polygon const& polygon)
+ {
+ return geometry::num_interior_rings(polygon) + 1;
+ }
+};
+
+template <typename MultiPolygon>
+struct num_rings<MultiPolygon, multi_polygon_tag>
+{
+ static inline std::size_t apply(MultiPolygon const& multipolygon)
+ {
+ return geometry::num_interior_rings(multipolygon)
+ + static_cast<std::size_t>(boost::size(multipolygon));
+ }
+};
+
+
+template <typename Geometry, typename Tag = typename tag<Geometry>::type>
+struct views_container_initializer
+{};
+
+template <typename Polygon>
+struct views_container_initializer<Polygon, polygon_tag>
+{
+ template <typename BoundaryView>
+ static inline void apply(Polygon const& polygon, BoundaryView* views)
+ {
+ typedef polygon_rings_iterator<Polygon> rings_iterator_type;
+
+ std::uninitialized_copy(rings_iterator_type(polygon),
+ rings_iterator_type(polygon, true),
+ views);
+ }
+};
+
+template <typename MultiPolygon>
+class views_container_initializer<MultiPolygon, multi_polygon_tag>
+{
+ typedef typename boost::mpl::if_
+ <
+ boost::is_const<MultiPolygon>,
+ typename boost::range_value<MultiPolygon>::type const,
+ typename boost::range_value<MultiPolygon>::type
+ >::type polygon_type;
+
+ typedef polygon_rings_iterator<polygon_type> inner_iterator_type;
+
+ struct polygon_rings_begin
+ {
+ static inline inner_iterator_type apply(polygon_type& polygon)
+ {
+ return inner_iterator_type(polygon);
+ }
+ };
+
+ struct polygon_rings_end
+ {
+ static inline inner_iterator_type apply(polygon_type& polygon)
+ {
+ return inner_iterator_type(polygon, true);
+ }
+ };
+
+ typedef flatten_iterator
+ <
+ typename boost::range_iterator<MultiPolygon>::type,
+ inner_iterator_type,
+ typename std::iterator_traits<inner_iterator_type>::value_type,
+ polygon_rings_begin,
+ polygon_rings_end,
+ typename std::iterator_traits<inner_iterator_type>::reference
+ > rings_iterator_type;
+
+public:
+ template <typename BoundaryView>
+ static inline void apply(MultiPolygon const& multipolygon,
+ BoundaryView* views)
+ {
+ rings_iterator_type first(boost::begin(multipolygon),
+ boost::end(multipolygon));
+ rings_iterator_type last(boost::end(multipolygon));
+
+ std::uninitialized_copy(first, last, views);
+ }
+};
+
+
+template <typename Areal>
+class areal_boundary
+{
+ typedef boundary_view<typename ring_type<Areal>::type> boundary_view_type;
+ typedef views_container_initializer<Areal> exception_safe_initializer;
+
+ template <typename T>
+ struct automatic_deallocator
+ {
+ automatic_deallocator(T* ptr) : m_ptr(ptr) {}
+
+ ~automatic_deallocator()
+ {
+ operator delete(m_ptr);
+ }
+
+ inline void release() { m_ptr = NULL; }
+
+ T* m_ptr;
+ };
+
+ inline void initialize_views(Areal const& areal)
+ {
+ // initialize number of rings
+ std::size_t n_rings = num_rings<Areal>::apply(areal);
+
+ if (n_rings == 0)
+ {
+ return;
+ }
+
+ // allocate dynamic memory
+ boundary_view_type* views_ptr = static_cast
+ <
+ boundary_view_type*
+ >(operator new(sizeof(boundary_view_type) * n_rings));
+
+ // initialize; if exceptions are thrown by constructors
+ // they are handled automatically by automatic_deallocator
+ automatic_deallocator<boundary_view_type> deallocator(views_ptr);
+ exception_safe_initializer::apply(areal, views_ptr);
+ deallocator.release();
+
+ // now initialize member variables safely
+ m_views = views_ptr;
+ m_num_rings = n_rings;
+ }
+
+ // disallow copies and/or assignments
+ areal_boundary(areal_boundary const&);
+ areal_boundary& operator=(areal_boundary const&);
+
+public:
+ typedef boundary_view_type* iterator;
+ typedef boundary_view_type const* const_iterator;
+
+ typedef multi_linestring_tag tag_type;
+
+ explicit areal_boundary(Areal& areal)
+ : m_views(NULL)
+ , m_num_rings(0)
+ {
+ initialize_views(areal);
+ }
+
+ ~areal_boundary()
+ {
+ boundary_view_type* last = m_views + m_num_rings;
+ for (boundary_view_type* it = m_views; it != last; ++it)
+ {
+ it->~boundary_view_type();
+ }
+ operator delete(m_views);
+ }
+
+ inline iterator begin() { return m_views; }
+ inline iterator end() { return m_views + m_num_rings; }
+ inline const_iterator begin() const { return m_views; }
+ inline const_iterator end() const { return m_views + m_num_rings; }
+
+private:
+ boundary_view_type* m_views;
+ std::size_t m_num_rings;
+};
+
+
+}} // namespace detail::boundary_view
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace detail_dispatch
+{
+
+
+template <typename Ring>
+struct boundary_view<Ring, ring_tag>
+ : detail::boundary_views::ring_boundary<Ring>
+{
+ explicit boundary_view(Ring& ring)
+ : detail::boundary_views::ring_boundary<Ring>(ring)
+ {}
+};
+
+template <typename Polygon>
+struct boundary_view<Polygon, polygon_tag>
+ : detail::boundary_views::areal_boundary<Polygon>
+{
+ explicit boundary_view(Polygon& polygon)
+ : detail::boundary_views::areal_boundary<Polygon>(polygon)
+ {}
+};
+
+template <typename MultiPolygon>
+struct boundary_view<MultiPolygon, multi_polygon_tag>
+ : detail::boundary_views::areal_boundary<MultiPolygon>
+{
+ explicit boundary_view(MultiPolygon& multipolygon)
+ : detail::boundary_views::areal_boundary
+ <
+ MultiPolygon
+ >(multipolygon)
+ {}
+};
+
+
+} // namespace detail_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_VIEWS_DETAIL_BOUNDARY_VIEW_IMPLEMENTATION_HPP
diff --git a/boost/geometry/views/detail/boundary_view/interface.hpp b/boost/geometry/views/detail/boundary_view/interface.hpp
new file mode 100644
index 0000000000..4d0b6d0303
--- /dev/null
+++ b/boost/geometry/views/detail/boundary_view/interface.hpp
@@ -0,0 +1,70 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_VIEWS_DETAIL_BOUNDARY_VIEW_INTERFACE_HPP
+#define BOOST_GEOMETRY_VIEWS_DETAIL_BOUNDARY_VIEW_INTERFACE_HPP
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace detail_dispatch
+{
+
+template <typename Geometry, typename Tag = typename tag<Geometry>::type>
+struct boundary_view
+ : not_implemented<Tag>
+{};
+
+} // namespace detail_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename Geometry>
+struct boundary_view
+ : detail_dispatch::boundary_view<Geometry>
+{
+ explicit boundary_view(Geometry& geometry)
+ : detail_dispatch::boundary_view<Geometry>(geometry)
+ {}
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename Geometry>
+struct tag< geometry::detail::boundary_view<Geometry> >
+{
+ typedef typename detail_dispatch::boundary_view
+ <
+ Geometry
+ >::tag_type type;
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_VIEWS_DETAIL_BOUNDARY_VIEW_INTERFACE_HPP
diff --git a/boost/geometry/views/detail/indexed_point_view.hpp b/boost/geometry/views/detail/indexed_point_view.hpp
index 88b13ec5c4..e5a89c9ae7 100644
--- a/boost/geometry/views/detail/indexed_point_view.hpp
+++ b/boost/geometry/views/detail/indexed_point_view.hpp
@@ -1,9 +1,14 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -62,41 +67,47 @@ namespace traits
{
template <typename Geometry, std::size_t Index>
-struct tag< detail::indexed_point_view<Geometry, Index> >
+struct tag< geometry::detail::indexed_point_view<Geometry, Index> >
{
typedef point_tag type;
};
template <typename Geometry, std::size_t Index>
-struct coordinate_type< detail::indexed_point_view<Geometry, Index> >
+struct coordinate_type< geometry::detail::indexed_point_view<Geometry, Index> >
{
typedef typename geometry::coordinate_type<Geometry>::type type;
};
template <typename Geometry, std::size_t Index>
-struct coordinate_system< detail::indexed_point_view<Geometry, Index> >
+struct coordinate_system
+ <
+ geometry::detail::indexed_point_view<Geometry, Index>
+ >
{
typedef typename geometry::coordinate_system<Geometry>::type type;
};
template <typename Geometry, std::size_t Index>
-struct dimension< detail::indexed_point_view<Geometry, Index> >
+struct dimension< geometry::detail::indexed_point_view<Geometry, Index> >
: geometry::dimension<Geometry>
{};
template<typename Geometry, std::size_t Index, std::size_t Dimension>
-struct access< detail::indexed_point_view<Geometry, Index>, Dimension >
+struct access
+ <
+ geometry::detail::indexed_point_view<Geometry, Index>, Dimension
+ >
{
typedef typename geometry::coordinate_type<Geometry>::type coordinate_type;
static inline coordinate_type get(
- detail::indexed_point_view<Geometry, Index> const& p)
+ geometry::detail::indexed_point_view<Geometry, Index> const& p)
{
return p.template get<Dimension>();
}
static inline void set(
- detail::indexed_point_view<Geometry, Index> & p,
+ geometry::detail::indexed_point_view<Geometry, Index> & p,
coordinate_type const& value)
{
p.template set<Dimension>(value);
diff --git a/boost/geometry/views/detail/two_dimensional_view.hpp b/boost/geometry/views/detail/two_dimensional_view.hpp
new file mode 100644
index 0000000000..fbd993cafc
--- /dev/null
+++ b/boost/geometry/views/detail/two_dimensional_view.hpp
@@ -0,0 +1,196 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_VIEWS_DETAIL_TWO_DIMENSIONAL_VIEW_HPP
+#define BOOST_GEOMETRY_VIEWS_DETAIL_TWO_DIMENSIONAL_VIEW_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/int.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template
+<
+ typename Geometry,
+ std::size_t Dimension1 = 0,
+ std::size_t Dimension2 = 1,
+ typename Tag = typename tag<Geometry>::type
+>
+struct two_dimensional_view
+ : not_implemented<Tag>
+{};
+
+
+// View that enables to choose two dimensions of a point and see it as
+// a two-dimensional point
+template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
+struct two_dimensional_view<Point, Dimension1, Dimension2, point_tag>
+{
+ BOOST_MPL_ASSERT_MSG(
+ (Dimension1 < static_cast<std::size_t>(dimension<Point>::value)),
+ COORDINATE_DIMENSION1_IS_LARGER_THAN_POINT_DIMENSION,
+ (boost::mpl::int_<Dimension1>));
+
+ BOOST_MPL_ASSERT_MSG(
+ (Dimension2 < static_cast<std::size_t>(dimension<Point>::value)),
+ COORDINATE_DIMENSION2_IS_LARGER_THAN_POINT_DIMENSION,
+ (boost::mpl::int_<Dimension2>));
+
+ two_dimensional_view(Point& point)
+ : m_point(point)
+ {}
+
+ Point& m_point;
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+
+template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
+struct tag
+ <
+ geometry::detail::two_dimensional_view
+ <
+ Point, Dimension1, Dimension2, point_tag
+ >
+ >
+{
+ typedef point_tag type;
+};
+
+template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
+struct coordinate_system
+ <
+ geometry::detail::two_dimensional_view
+ <
+ Point, Dimension1, Dimension2, point_tag
+ >
+ > : coordinate_system<typename geometry::point_type<Point>::type>
+{};
+
+template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
+struct coordinate_type
+ <
+ geometry::detail::two_dimensional_view
+ <
+ Point, Dimension1, Dimension2, point_tag
+ >
+ > : coordinate_type<typename geometry::point_type<Point>::type>
+{};
+
+template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
+struct dimension
+ <
+ geometry::detail::two_dimensional_view
+ <
+ Point, Dimension1, Dimension2, point_tag
+ >
+ > : boost::mpl::int_<2>
+{};
+
+template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
+struct point_type
+ <
+ geometry::detail::two_dimensional_view
+ <
+ Point, Dimension1, Dimension2, point_tag
+ >
+ >
+{
+ typedef typename geometry::point_type<Point>::type type;
+};
+
+
+template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
+struct access
+ <
+ geometry::detail::two_dimensional_view
+ <
+ Point, Dimension1, Dimension2, point_tag
+ >,
+ 0
+ >
+{
+ typedef typename geometry::coordinate_type<Point>::type coordinate_type;
+ typedef geometry::detail::two_dimensional_view
+ <
+ Point, Dimension1, Dimension2, point_tag
+ > view_type;
+
+ static inline coordinate_type get(view_type const& view)
+ {
+ return geometry::get<Dimension1>(view.m_point);
+ }
+
+ static inline void set(view_type& view, coordinate_type const& value)
+ {
+ geometry::set<Dimension1>(view.m_point, value);
+ }
+};
+
+template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
+struct access
+ <
+ geometry::detail::two_dimensional_view
+ <
+ Point, Dimension1, Dimension2, point_tag
+ >,
+ 1
+ >
+{
+ typedef typename geometry::coordinate_type<Point>::type coordinate_type;
+ typedef geometry::detail::two_dimensional_view
+ <
+ Point, Dimension1, Dimension2, point_tag
+ > view_type;
+
+ static inline coordinate_type get(view_type const& view)
+ {
+ return geometry::get<Dimension2>(view.m_point);
+ }
+
+ static inline void set(view_type& view, coordinate_type const& value)
+ {
+ geometry::set<Dimension2>(view.m_point, value);
+ }
+};
+
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_VIEWS_DETAIL_TWO_DIMENSIONAL_VIEW_HPP
diff --git a/boost/get_pointer.hpp b/boost/get_pointer.hpp
index b27b98a609..36e2cd7d0f 100644
--- a/boost/get_pointer.hpp
+++ b/boost/get_pointer.hpp
@@ -24,11 +24,39 @@ template<class T> T * get_pointer(T * p)
// get_pointer(shared_ptr<T> 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<class T> T * get_pointer(std::auto_ptr<T> 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<class T> T * get_pointer( std::unique_ptr<T> const& p )
diff --git a/boost/heap/detail/tree_iterator.hpp b/boost/heap/detail/tree_iterator.hpp
index 83c8d3fb4c..2bc05ea1ab 100644
--- a/boost/heap/detail/tree_iterator.hpp
+++ b/boost/heap/detail/tree_iterator.hpp
@@ -6,8 +6,6 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Disclaimer: Not a Boost library.
-
#ifndef BOOST_HEAP_DETAIL_TREE_ITERATOR_HPP
#define BOOST_HEAP_DETAIL_TREE_ITERATOR_HPP
@@ -23,8 +21,7 @@ namespace detail {
template<typename type>
-struct identity:
- public std::unary_function<type,type>
+struct identity
{
type& operator()(type& x) const
{ return x; }
@@ -33,19 +30,6 @@ struct identity:
{ return x; }
};
-template<typename type>
-struct caster:
- public std::unary_function<type,type>
-{
- template <typename U>
- type& operator()(U& x) const
- { return static_cast<type&>(x); }
-
- template <typename U>
- const type& operator()(const U& x) const
- { return static_cast<const type&>(x); }
-};
-
template<typename Node>
struct dereferencer
{
diff --git a/boost/heap/fibonacci_heap.hpp b/boost/heap/fibonacci_heap.hpp
index 4397d565ee..10a1ce3a5e 100644
--- a/boost/heap/fibonacci_heap.hpp
+++ b/boost/heap/fibonacci_heap.hpp
@@ -432,14 +432,7 @@ public:
* */
void update (handle_type handle)
{
- node_pointer n = handle.node_;
- node_pointer parent = n->get_parent();
-
- if (parent) {
- n->parent = NULL;
- roots.splice(roots.begin(), parent->children, node_list_type::s_iterator_to(*n));
- }
- add_children_to_root(n);
+ update_lazy(handle);
consolidate();
}
@@ -458,6 +451,9 @@ public:
roots.splice(roots.begin(), parent->children, node_list_type::s_iterator_to(*n));
}
add_children_to_root(n);
+
+ if (super_t::operator()(top_element->value, n->value))
+ top_element = n;
}
@@ -735,7 +731,7 @@ private:
aux[node_rank] = n;
}
- if (super_t::operator()(top_element->value, n->value))
+ if (!super_t::operator()(n->value, top_element->value))
top_element = n;
}
while (it != roots.end());
diff --git a/boost/heap/pairing_heap.hpp b/boost/heap/pairing_heap.hpp
index d42d3af900..a2bf65472c 100644
--- a/boost/heap/pairing_heap.hpp
+++ b/boost/heap/pairing_heap.hpp
@@ -540,7 +540,7 @@ public:
/// \copydoc boost::heap::priority_queue::end
iterator end(void) const
{
- return iterator();
+ return iterator(super_t::value_comp());
}
/// \copydoc boost::heap::fibonacci_heap::ordered_begin
diff --git a/boost/interprocess/detail/std_fwd.hpp b/boost/interprocess/detail/std_fwd.hpp
index e3f6fc52a8..098e67067c 100644
--- a/boost/interprocess/detail/std_fwd.hpp
+++ b/boost/interprocess/detail/std_fwd.hpp
@@ -22,10 +22,12 @@
// Standard predeclarations
//////////////////////////////////////////////////////////////////////////////
-#if defined(__clang__) && defined(_LIBCPP_VERSION)
+#if defined(_LIBCPP_VERSION)
#define BOOST_INTERPROCESS_CLANG_INLINE_STD_NS
#pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wc++11-extensions"
+ #if defined(__clang__)
+ #pragma GCC diagnostic ignored "-Wc++11-extensions"
+ #endif
#define BOOST_INTERPROCESS_STD_NS_BEG _LIBCPP_BEGIN_NAMESPACE_STD
#define BOOST_INTERPROCESS_STD_NS_END _LIBCPP_END_NAMESPACE_STD
#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE_VERSION) //GCC >= 4.6
diff --git a/boost/interprocess/detail/xsi_shared_memory_device.hpp b/boost/interprocess/detail/xsi_shared_memory_device.hpp
deleted file mode 100644
index 2f256a5f6c..0000000000
--- a/boost/interprocess/detail/xsi_shared_memory_device.hpp
+++ /dev/null
@@ -1,401 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_DEVICE_HPP
-#define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_DEVICE_HPP
-
-#ifndef BOOST_CONFIG_HPP
-# include <boost/config.hpp>
-#endif
-#
-#if defined(BOOST_HAS_PRAGMA_ONCE)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-#include <boost/detail/workaround.hpp>
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-#error "This header can't be used in Windows operating systems"
-#endif
-
-#include <boost/interprocess/creation_tags.hpp>
-#include <boost/interprocess/exceptions.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/os_file_functions.hpp>
-#include <boost/interprocess/detail/shared_dir_helpers.hpp>
-#include <boost/interprocess/detail/simple_swap.hpp>
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/exceptions.hpp>
-
-#include <boost/interprocess/xsi_shared_memory.hpp>
-#include <boost/interprocess/sync/xsi/xsi_named_mutex.hpp>
-#include <boost/interprocess/mapped_region.hpp>
-#include <boost/interprocess/sync/scoped_lock.hpp>
-#include <cstddef>
-#include <boost/cstdint.hpp>
-#include <string>
-#include <cstring>
-
-//!\file
-//!Describes a class representing a native xsi shared memory.
-
-namespace boost {
-namespace interprocess {
-
-class xsi_shared_memory_device
-{
- #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- BOOST_MOVABLE_BUT_NOT_COPYABLE(xsi_shared_memory_file_wrapper)
- #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
-
- public:
-
- xsi_shared_memory_device();
-
- xsi_shared_memory_device(create_only_t, const char *name, mode_t mode, std::size_t size)
- { this->priv_open_or_create_name_only(ipcdetail::DoCreate, name, mode, size); }
-
- xsi_shared_memory_device(open_or_create_t, const char *name, mode_t mode, std::size_t size)
- { this->priv_open_or_create_name_only(ipcdetail::DoOpenOrCreate, name, mode, size); }
-
- xsi_shared_memory_device(open_only_t, const char *name, mode_t mode)
- { this->priv_open_or_create_name_only(ipcdetail::DoOpen, name, mode, 0); }
-
- xsi_shared_memory_device(create_only_t, const char *filepath, boost::uint8_t id, mode_t mode, std::size_t size)
- { this->priv_open_or_create_name_id(ipcdetail::DoCreate, name, id, mode, size); }
-
- xsi_shared_memory_device(open_or_create_t, const char *filepath, boost::uint8_t id, mode_t mode, std::size_t size)
- { this->priv_open_or_create_name_id(ipcdetail::DoOpenOrCreate, id, name, mode, size); }
-
- xsi_shared_memory_device(open_only_t, const char *filepath, boost::uint8_t id, mode_t mode)
- { this->priv_open_or_create_name_id(ipcdetail::DoOpen, name, id, mode, 0); }
-
- xsi_shared_memory_device(BOOST_RV_REF(xsi_shared_memory_device) moved)
- { this->swap(moved); }
-
- xsi_shared_memory_device &operator=(BOOST_RV_REF(xsi_shared_memory_device) moved)
- {
- xsi_shared_memory_device tmp(boost::move(moved));
- this->swap(tmp);
- return *this;
- }
-
- //!Swaps two xsi_shared_memory_device. Does not throw
- void swap(xsi_shared_memory_device &other);
-
- //!Destroys *this. The shared memory won't be destroyed, just
- //!this connection to it. Use remove() to destroy the shared memory.
- ~xsi_shared_memory_device();
-
- //!Returns the name of the
- //!shared memory.
- const char *get_name() const;
-
- //!Returns the shared memory ID that
- //!identifies the shared memory
- int get_shmid() const;
-
- //!Returns access
- //!permissions
- mode_t get_mode() const;
-
- //!Returns the mapping handle.
- //!Never throws
- mapping_handle_t get_mapping_handle() const;
-
- //!Erases a XSI shared memory object identified by shmname
- //!from the system.
- //!Returns false on error. Never throws
- static bool remove(const char *shmname);
-
- //!Erases the XSI shared memory object identified by shmid
- //!from the system.
- //!Returns false on error. Never throws
- static bool remove(int shmid);
-
- #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- private:
- template<int Dummy>
- struct info_constants_t
- {
- static const std::size_t MaxName = 32;
- static const std::size_t FirstID = 2;
- static const std::size_t LastID = 256;
- static const std::size_t NumID = LastID - FirstID;
- };
-
- struct info_t
- {
- struct names_t
- {
- char buf[info_constants_t<0>::MaxName];
- } names[info_constants_t<0>::NumID];
- };
-
- static void priv_obtain_index(mapped_region &m, xsi_named_mutex &m, std::string &path);
- static bool priv_remove_dead_memory(info_t *info, const char *path);
-
- bool priv_open_or_create_name_only( ipcdetail::create_enum_t type
- , const char *shmname
- , mode_t mode
- , std::size_t size);
- bool priv_open_or_create_name_id( ipcdetail::create_enum_t type
- , const char *shmname
- , boost::uint8_t id
- , mode_t mode
- , std::size_t size);
- xsi_shared_memory m_shm;
- mode_t m_mode;
- std::string m_name;
- #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
-};
-
-template<int Dummy>
-const std::size_t xsi_shared_memory_device::info_constants_t<Dummy>::MaxName;
-
-template<int Dummy>
-const std::size_t xsi_shared_memory_device::info_constants_t<Dummy>::FirstID;
-
-template<int Dummy>
-const std::size_t xsi_shared_memory_device::info_constants_t<Dummy>::LastID;
-
-template<int Dummy>
-const std::size_t xsi_shared_memory_device::info_constants_t<Dummy>::NumID;
-
-#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-
-inline xsi_shared_memory_device::xsi_shared_memory_device()
- : m_shm(), m_mode(invalid_mode), m_name()
-{}
-
-inline xsi_shared_memory_device::~xsi_shared_memory_device()
-{}
-
-inline const char *xsi_shared_memory_device::get_name() const
-{ return m_name.c_str(); }
-
-inline void xsi_shared_memory_device::swap(xsi_shared_memory_device &other)
-{
- m_shm.swap(other.m_shm);
- (simple_swap)(m_mode, other.m_mode);
- m_name.swap(other.m_name);
-}
-
-inline mapping_handle_t xsi_shared_memory_device::get_mapping_handle() const
-{ return m_shm.get_mapping_handle(); }
-
-inline mode_t xsi_shared_memory_device::get_mode() const
-{ return m_mode; }
-
-inline int xsi_shared_memory::get_shmid() const
-{ return m_shm.get_shmid(); }
-
-inline void xsi_shared_memory_device::priv_obtain_index
- (mapped_region &reg, xsi_named_mutex &mut, std::string &path)
-{
- const char *const filename = "xsi_shm_emulation_file";
- permissions p;
- p.set_unrestricted();
- std::string xsi_shm_emulation_file_path;
- ipcdetail::create_shared_dir_cleaning_old_and_get_filepath(filename, xsi_shm_emulation_file_path);
- ipcdetail::create_or_open_file(xsi_shm_emulation_file_path.c_str(), read_write, p);
- const std::size_t MemSize = sizeof(info_t);
-
- xsi_shared_memory index_shm(open_or_create, xsi_shm_emulation_file_path.c_str(), 1, MemSize, 0666);
- mapped_region r(index_shm, read_write, 0, MemSize, 0);
- xsi_named_mutex m(open_or_create, xsi_shm_emulation_file_path.c_str(), 2, 0666);
- reg = boost::move(r);
- mut = boost::move(m);
- path.swap(xsi_shm_emulation_file_path);
-}
-
-inline bool xsi_shared_memory_device::priv_remove_dead_memory
- (xsi_shared_memory_device::info_t *info, const char *path)
-{
- bool removed = false;
- for(std::size_t i = 0; i != info_constants_t<0>::NumID; ++i){
- if(info->names[i].buf[0]){
- try{
- xsi_shared_memory temp( open_only, path, i+info_constants_t<0>::FirstID, 0600);
- }
- catch(interprocess_exception &e){
- if(e.get_error_code() == not_found_error){
- std::memset(info->names[i].buf, 0, info_constants_t<0>::MaxName);
- removed = true;
- }
- }
- }
- }
- return removed;
-}
-
-inline bool xsi_shared_memory_device::priv_open_or_create_name_id
- (ipcdetail::create_enum_t type, const char *filepath, mode_t mode, std::size_t size)
-{
- //Set accesses
- if (mode != read_write && mode != read_only){
- error_info err = other_error;
- throw interprocess_exception(err);
- }
-
- int perm = (mode == read_only) ? (0444) : (0666);
-
- if(type == ipcdetail::DoOpen){
- if(!found){
- error_info err = not_found_error;
- throw interprocess_exception(err);
- }
- xsi_shared_memory temp(open_only, filepath, id, perm);
- m_shm = boost::move(temp);
- }
- else if(type == ipcdetail::DoCreate){
- //Try to reuse slot
- xsi_shared_memory temp(create_only, filepath, id, size, perm);
- std::strcpy(info->names[target_entry].buf, shmname);
- m_shm = boost::move(temp);
- }
- else{ // if(type == ipcdetail::DoOpenOrCreate){
- xsi_shared_memory temp(open_or_create, filepath, id, size, perm);
- m_shm = boost::move(temp);
- }
-
- m_mode = mode;
- m_name.clear();
- return true;
-}
-
-inline bool xsi_shared_memory_device::priv_open_or_create_name_only
- (ipcdetail::create_enum_t type, const char *shmname, mode_t mode, std::size_t size)
-{
- //Set accesses
- if (mode != read_write && mode != read_only){
- error_info err = other_error;
- throw interprocess_exception(err);
- }
-
- if (std::strlen(shmname) >= (info_constants_t<0>::MaxName)){
- error_info err = other_error;
- throw interprocess_exception(err);
- }
-
- {
- //Obtain index and index lock
- mapped_region region;
- xsi_named_mutex mut;
- std::string xsi_shm_emulation_file_path;
- priv_obtain_index(region, mut, xsi_shm_emulation_file_path);
- info_t *info = static_cast<info_t *>(region.get_address());
- scoped_lock<xsi_named_mutex> lock(mut);
-
- //Find the correct entry or the first empty index
- bool found = false;
- int target_entry = -1;
- int tries = 2;
- while(tries--){
- for(std::size_t i = 0; i != info_constants_t<0>::NumID; ++i){
- if(target_entry < 0 && !info->names[i].buf[0]){
- target_entry = static_cast<int>(i);
- }
- else if(0 == std::strcmp(info->names[i].buf, shmname)){
- found = true;
- target_entry = static_cast<int>(i);
- break;
- }
- }
- if(target_entry < 0){
- if(!tries || !priv_remove_dead_memory(info, xsi_shm_emulation_file_path.c_str())){
- error_info err = out_of_resource_error;
- throw interprocess_exception(err);
- }
- }
- }
- //Now handle the result
- int perm = (mode == read_only) ? (0444) : (0666);
- if(type == ipcdetail::DoOpen){
- if(!found){
- error_info err = not_found_error;
- throw interprocess_exception(err);
- }
- xsi_shared_memory temp( open_only, xsi_shm_emulation_file_path.c_str()
- , target_entry+info_constants_t<0>::FirstID, perm);
- m_shm = boost::move(temp);
- }
- else{
-
- if(type == ipcdetail::DoCreate){
- //Try to reuse slot
- xsi_shared_memory temp( create_only, xsi_shm_emulation_file_path.c_str()
- , target_entry+info_constants_t<0>::FirstID, size, perm);
- std::strcpy(info->names[target_entry].buf, shmname);
- m_shm = boost::move(temp);
- }
- else{ // if(type == ipcdetail::DoOpenOrCreate){
- xsi_shared_memory temp( open_or_create, xsi_shm_emulation_file_path.c_str()
- , target_entry+info_constants_t<0>::FirstID, size, perm);
- if(!found){
- std::memset(info->names[target_entry].buf, 0, info_constants_t<0>::MaxName);
- std::strcpy(info->names[target_entry].buf, shmname);
- }
- m_shm = boost::move(temp);
- }
- }
- }
-
- m_mode = mode;
- m_name = shmname;
- return true;
-}
-
-inline bool xsi_shared_memory_device::remove(const char *shmname)
-{
- try{
- //Obtain index and index lockss
- mapped_region region;
- xsi_named_mutex mut;
- std::string xsi_shm_emulation_file_path;
- priv_obtain_index(region, mut, xsi_shm_emulation_file_path);
- scoped_lock<xsi_named_mutex> lock(mut);
- info_t *info = static_cast<info_t *>(region.get_address());
-
- //Now check and remove
- bool removed = false;
-
- for(std::size_t i = 0; i != info_constants_t<0>::NumID; ++i){
- if(0 == std::strcmp(info->names[i].buf, name)){
- xsi_shared_memory temp( open_only, xsi_shm_emulation_file_path.c_str()
- , i+info_constants_t<0>::FirstID);
- if(!xsi_shared_memory::remove(temp.get_shmid()) && (system_error_code() != invalid_argument)){
- return false;
- }
- std::memset(info->names[i].buf, 0, info_constants_t<0>::MaxName);
- removed = true;
- break;
- }
- }
- return removed;
- }
- catch(...){
- return false;
- }
-}
-
-inline bool xsi_shared_memory_device::remove(int shmid)
-{ return xsi_shared_memory::remove(shmid); }
-
-#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
-
-} //namespace interprocess {
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //BOOST_INTERPROCESS_XSI_SHARED_MEMORY_DEVICE_HPP
diff --git a/boost/interprocess/exceptions.hpp b/boost/interprocess/exceptions.hpp
index 7c87722d24..700c4c5034 100644
--- a/boost/interprocess/exceptions.hpp
+++ b/boost/interprocess/exceptions.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
+// (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)
//
@@ -33,23 +33,15 @@ namespace interprocess {
//!This class is the base class of all exceptions
//!thrown by boost::interprocess
-class interprocess_exception : public std::exception
+class BOOST_SYMBOL_VISIBLE interprocess_exception : public std::exception
{
public:
- interprocess_exception(const char *err/*error_code_t ec = other_error*/)
+ interprocess_exception(const char *err)
: m_err(other_error)
{
-// try { m_str = "boost::interprocess_exception::library_error"; }
try { m_str = err; }
catch (...) {}
}
-/*
- interprocess_exception(native_error_t sys_err_code)
- : m_err(sys_err_code)
- {
- try { fill_system_message(m_err.get_native_error(), m_str); }
- catch (...) {}
- }*/
interprocess_exception(const error_info &err_info, const char *str = 0)
: m_err(err_info)
@@ -87,7 +79,7 @@ class interprocess_exception : public std::exception
//!This is the exception thrown by shared interprocess_mutex family when a deadlock situation
//!is detected or when using a interprocess_condition the interprocess_mutex is not locked
-class lock_exception : public interprocess_exception
+class BOOST_SYMBOL_VISIBLE lock_exception : public interprocess_exception
{
public:
lock_exception()
@@ -98,45 +90,10 @@ class lock_exception : public interprocess_exception
{ return "boost::interprocess::lock_exception"; }
};
-//!This is the exception thrown by named interprocess_semaphore when a deadlock situation
-//!is detected or when an error is detected in the post/wait operation
-/*
-class sem_exception : public interprocess_exception
-{
- public:
- sem_exception()
- : interprocess_exception(lock_error)
- {}
-
- virtual const char* what() const throw()
- { return "boost::interprocess::sem_exception"; }
-};
-*/
-//!This is the exception thrown by synchronization objects when there is
-//!an error in a wait() function
-/*
-class wait_exception : public interprocess_exception
-{
- public:
- virtual const char* what() const throw()
- { return "boost::interprocess::wait_exception"; }
-};
-*/
-
-//!This exception is thrown when a named object is created
-//!in "open_only" mode and the resource was not already created
-/*
-class not_previously_created : public interprocess_exception
-{
- public:
- virtual const char* what() const throw()
- { return "boost::interprocess::not_previously_created"; }
-};
-*/
//!This exception is thrown when a memory request can't be
//!fulfilled.
-class bad_alloc : public interprocess_exception
+class BOOST_SYMBOL_VISIBLE bad_alloc : public interprocess_exception
{
public:
bad_alloc() : interprocess_exception("::boost::interprocess::bad_alloc"){}
diff --git a/boost/interprocess/streams/bufferstream.hpp b/boost/interprocess/streams/bufferstream.hpp
index 9a862e5e86..015d03c65c 100644
--- a/boost/interprocess/streams/bufferstream.hpp
+++ b/boost/interprocess/streams/bufferstream.hpp
@@ -200,8 +200,8 @@ class basic_bufferbuf
if(!in && !out)
return pos_type(off_type(-1));
- else if((in && (!(m_mode & std::ios_base::in) || this->gptr() == 0)) ||
- (out && (!(m_mode & std::ios_base::out) || this->pptr() == 0)))
+ else if((in && (!(m_mode & std::ios_base::in) || (off != 0 && this->gptr() == 0) )) ||
+ (out && (!(m_mode & std::ios_base::out) || (off != 0 && this->pptr() == 0))))
return pos_type(off_type(-1));
std::streamoff newoff;
diff --git a/boost/interprocess/streams/vectorstream.hpp b/boost/interprocess/streams/vectorstream.hpp
index b6f873e49c..8f6bf38373 100644
--- a/boost/interprocess/streams/vectorstream.hpp
+++ b/boost/interprocess/streams/vectorstream.hpp
@@ -298,8 +298,8 @@ class basic_vectorbuf
return pos_type(off_type(-1));
else if((in && out) && (dir == std::ios_base::cur))
return pos_type(off_type(-1));
- else if((in && (!(m_mode & std::ios_base::in) || this->gptr() == 0)) ||
- (out && (!(m_mode & std::ios_base::out) || this->pptr() == 0)))
+ else if((in && (!(m_mode & std::ios_base::in) || (off != 0 && this->gptr() == 0) )) ||
+ (out && (!(m_mode & std::ios_base::out) || (off != 0 && this->pptr() == 0))))
return pos_type(off_type(-1));
off_type newoff;
diff --git a/boost/interprocess/sync/xsi/advanced_xsi_semaphore.hpp b/boost/interprocess/sync/xsi/advanced_xsi_semaphore.hpp
deleted file mode 100644
index 49562f5cbd..0000000000
--- a/boost/interprocess/sync/xsi/advanced_xsi_semaphore.hpp
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Provide an simpler and easier to understand interface to the System V
- * semaphore system calls. There are 7 routines available to the user:
- *
- * id = sem_create(key, initval); # create with initial value or open
- * id = sem_open(key); # open (must already exist)
- * sem_wait(id); # wait = P = down by 1
- * sem_signal(id); # signal = V = up by 1
- * sem_op(id, amount); # wait if (amount < 0)
- * # signal if (amount > 0)
- * sem_close(id); # close
- * sem_rm(id); # remove (delete)
- *
- * We create and use a 3-member set for the requested semaphore.
- * The first member, [0], is the actual semaphore value, and the second
- * member, [1], is a counter used to know when all processes have finished
- * with the semaphore. The counter is initialized to a large number,
- * decremented on every create or open and incremented on every close.
- * This way we can use the "adjust" feature provided by System V so that
- * any process that exit's without calling sem_close() is accounted
- * for. It doesn't help us if the last process does this (as we have
- * no way of getting control to remove the semaphore) but it will
- * work if any process other than the last does an exit (intentional
- * or unintentional).
- * The third member, [2], of the semaphore set is used as a lock variable
- * to avoid any race conditions in the sem_create() and sem_close()
- * functions.
- */
-
-#ifndef BOOST_INTERPROCESS_SYNC_XSI_ADVANCED_XSI_SEMAPHORE_HPP
-#define BOOST_INTERPROCESS_SYNC_XSI_ADVANCED_XSI_SEMAPHORE_HPP
-
-#ifndef BOOST_CONFIG_HPP
-# include <boost/config.hpp>
-#endif
-#
-#if defined(BOOST_HAS_PRAGMA_ONCE)
-# pragma once
-#endif
-
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#include <errno.h>
-
-namespace boost {
-namespace interprocess {
-namespace xsi {
-
-// Create a semaphore with a specified initial value.
-// If the semaphore already exists, we don't initialize it (of course).
-// We return the semaphore ID if all OK, else -1.
-
-inline bool advanced_sem_open_or_create(::key_t key, int initval, int &semid, int perm)
-{
- semid = -1;
- int id, semval;
- union semun {
- int val;
- ::semid_ds *buf;
- ushort *array;
- } semctl_arg;
-
- if (key == IPC_PRIVATE)
- return false; //not intended for private semaphores
-
- else if (key == (::key_t) -1)
- return false; //probably an ftok() error by caller
-
- again:
- if ((id = ::semget(key, 3, (perm & 0x01FF) | IPC_CREAT)) < 0)
- return false; //permission problem or tables full
-
- // When the semaphore is created, we know that the value of all
- // 3 members is 0.
- // Get a lock on the semaphore by waiting for [2] to equal 0,
- // then increment it.
- //
- // There is a race condition here. There is a possibility that
- // between the semget() above and the ::semop() below, another
- // process can call our sem_close() function which can remove
- // the semaphore if that process is the last one using it.
- // Therefore, we handle the error condition of an invalid
- // semaphore ID specially below, and if it does happen, we just
- // go back and create it again.
- struct sembuf op_lock[2] = {
- {2, 0, 0}, // wait for [2] (lock) to equal 0
- {2, 1, SEM_UNDO} // then increment [2] to 1 - this locks it
- // UNDO to release the lock if processes exits
- // before explicitly unlocking
- };
-
- if (::semop(id, &op_lock[0], 2) < 0) {
- if (errno == EINVAL)
- goto again;
- }
-
- // Get the value of the process counter. If it equals 0,
- // then no one has initialized the semaphore yet.
- if ((semval = ::semctl(id, 1, GETVAL, 0)) < 0)
- return false;
-
- if (semval == 0) {
- // We could initialize by doing a SETALL, but that
- // would clear the adjust value that we set when we
- // locked the semaphore above. Instead, we'll do 2
- // system calls to initialize [0] and [1].
- semctl_arg.val = initval;
- if (::semctl(id, 0, SETVAL, semctl_arg) < 0)
- return false;
-
- semctl_arg.val = 1;
- if (::semctl(id, 1, SETVAL, semctl_arg) < 0)
- return false;
- }
-
- // Decrement the process counter and then release the lock.
- struct sembuf op_unlock[1] = {
- 2, -1, 0/*SEM_UNDO*/ // decrement [2] (lock) back to 0
- };
-
- if (::semop(id, &op_unlock[0], 1) < 0)
- return false;
-
- semid = id;
- return true;
-}
-
-// Open a semaphore that must already exist.
-// This function should be used, instead of sem_create(), if the caller
-// knows that the semaphore must already exist. For example a client
-// from a client-server pair would use this, if its the server's
-// responsibility to create the semaphore.
-// We return the semaphore ID if all OK, else -1.
-/*
-inline bool advanced_sem_open(key_t key, int &semid)
-{
- semid = -1;
- if (key == IPC_PRIVATE)
- return false; // not intended for private semaphores
-
- else if (key == (::key_t) -1)
- return false; // probably an ftok() error by caller
-
- if ((semid = ::semget(key, 3, 0)) < 0)
- return false; // doesn't exist, or tables full
-
- // Decrement the process counter. We don't need a lock
- struct sembuf op_open[1] = {
- 1, -1, SEM_UNDO // decrement [1] (proc counter) with undo on exit
- };
-
- if (::semop(id, &op_open[0], 1) < 0)
- return false;
-
- return true;
-}
-*/
-/****************************************************************************
- * Remove a semaphore.
- * This call is intended to be called by a server, for example,
- * when it is being shut down, as we do an IPC_RMID on the semaphore,
- * regardless whether other processes may be using it or not.
- * Most other processes should use sem_close() below.
- */
-
-inline bool advanced_sem_rm(int id)
-{
- if (::semctl(id, 0, IPC_RMID, 0) < 0)
- return false;
- return true;
-}
-
-
-/****************************************************************************
- * General semaphore operation. Increment or decrement by a user-specified
- * amount (positive or negative; amount can't be zero).
- */
-
-inline bool advanced_sem_op(int id, int value, bool undo = true)
-{
- ::sembuf op_op[1] = {
- 0, 99, 0 // decrement or increment [0] with undo on exit
- // the 99 is set to the actual amount to add
- // or subtract (positive or negative)
- };
- if(undo){
- op_op[0].sem_flg = SEM_UNDO;
- }
- if ((op_op[0].sem_op = value) == 0)
- return false;
-
- if (::semop(id, &op_op[0], 1) < 0)
- return false;
- return true;
-}
-
-} //namespace xsi {
-} //namespace interprocess {
-} //namespace boost {
-
-#endif //BOOST_INTERPROCESS_SYNC_XSI_ADVANCED_XSI_SEMAPHORE_HPP
diff --git a/boost/interprocess/sync/xsi/simple_xsi_semaphore.hpp b/boost/interprocess/sync/xsi/simple_xsi_semaphore.hpp
deleted file mode 100644
index 3d6fd882c6..0000000000
--- a/boost/interprocess/sync/xsi/simple_xsi_semaphore.hpp
+++ /dev/null
@@ -1,124 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#ifndef BOOST_INTERPROCESS_SYNC_XSI_SIMPLE_XSI_SEMAPHORE_HPP
-#define BOOST_INTERPROCESS_SYNC_XSI_SIMPLE_XSI_SEMAPHORE_HPP
-
-#ifndef BOOST_CONFIG_HPP
-# include <boost/config.hpp>
-#endif
-#
-#if defined(BOOST_HAS_PRAGMA_ONCE)
-# pragma once
-#endif
-
-/*
- * Provide an simpler and easier to understand interface to the System V
- * semaphore system calls. There are 7 routines available to the user:
- *
- * id = sem_create(key, initval); # create with initial value or open
- * id = sem_open(key); # open (must already exist)
- * sem_wait(id); # wait = P = down by 1
- * sem_signal(id); # signal = V = up by 1
- * sem_op(id, amount); # wait if (amount < 0)
- * # signal if (amount > 0)
- * sem_close(id); # close
- * sem_rm(id); # remove (delete)
- *
- * We create and use a 3-member set for the requested semaphore.
- * The first member, [0], is the actual semaphore value, and the second
- * member, [1], is a counter used to know when all processes have finished
- * with the semaphore. The counter is initialized to a large number,
- * decremented on every create or open and incremented on every close.
- * This way we can use the "adjust" feature provided by System V so that
- * any process that exit's without calling sem_close() is accounted
- * for. It doesn't help us if the last process does this (as we have
- * no way of getting control to remove the semaphore) but it will
- * work if any process other than the last does an exit (intentional
- * or unintentional).
- * The third member, [2], of the semaphore set is used as a lock variable
- * to avoid any race conditions in the sem_create() and sem_close()
- * functions.
- */
-
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#include <errno.h>
-
-namespace boost {
-namespace interprocess {
-namespace xsi {
-
-// Create a semaphore with a specified initial value.
-// If the semaphore already exists, we don't initialize it (of course).
-// We return the semaphore ID if all OK, else -1.
-
-inline bool simple_sem_open_or_create(::key_t key, int initval, int &semid, int perm)
-{
- int id, semval;
- semid = -1;
-
- if (key == IPC_PRIVATE)
- return false; //not intended for private semaphores
-
- else if (key == (::key_t) -1)
- return false; //probably an ftok() error by caller
-
- again:
- if ((id = ::semget(key, 1, (perm & 0x01FF) | IPC_CREAT)) < 0)
- return false; //permission problem or tables full
-
- semid = id;
- return true;
-}
-
-/****************************************************************************
- * Remove a semaphore.
- * This call is intended to be called by a server, for example,
- * when it is being shut down, as we do an IPC_RMID on the semaphore,
- * regardless whether other processes may be using it or not.
- * Most other processes should use sem_close() below.
- */
-
-inline bool simple_sem_rm(int id)
-{
- if (::semctl(id, 0, IPC_RMID, 0) < 0)
- return false;
- return true;
-}
-
-
-/****************************************************************************
- * General semaphore operation. Increment or decrement by a user-specified
- * amount (positive or negative; amount can't be zero).
- */
-
-inline bool simple_sem_op(int id, int value, bool undo = true)
-{
- ::sembuf op_op[1] = {
- 0, 99, 0 // decrement or increment [0] with undo on exit
- // the 99 is set to the actual amount to add
- // or subtract (positive or negative)
- };
- if(undo){
- op_op[0].sem_flg = SEM_UNDO;
- }
- if ((op_op[0].sem_op = value) == 0)
- return false;
-
- if (::semop(id, &op_op[0], 1) < 0)
- return false;
- return true;
-}
-
-} //namespace xsi {
-} //namespace interprocess {
-} //namespace boost {
-
-#endif //BOOST_INTERPROCESS_SYNC_XSI_SIMPLE_XSI_SEMAPHORE_HPP
diff --git a/boost/interprocess/sync/xsi/xsi_named_mutex.hpp b/boost/interprocess/sync/xsi/xsi_named_mutex.hpp
deleted file mode 100644
index 7d8cf50a83..0000000000
--- a/boost/interprocess/sync/xsi/xsi_named_mutex.hpp
+++ /dev/null
@@ -1,238 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTERPROCESS_XSI_XSI_NAMED_MUTEX_HPP
-#define BOOST_INTERPROCESS_XSI_XSI_NAMED_MUTEX_HPP
-
-#ifndef BOOST_CONFIG_HPP
-# include <boost/config.hpp>
-#endif
-#
-#if defined(BOOST_HAS_PRAGMA_ONCE)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-#error "This header can't be used in Windows operating systems"
-#endif
-
-#include <boost/move/utility_core.hpp>
-#include <boost/interprocess/creation_tags.hpp>
-#include <boost/interprocess/exceptions.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/os_file_functions.hpp>
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/exceptions.hpp>
-#include <boost/interprocess/sync/xsi/basic_xsi_semaphore.hpp>
-#include <boost/interprocess/detail/simple_swap.hpp>
-
-#include <cstddef>
-#include <boost/assert.hpp>
-#include <boost/cstdint.hpp>
-#include <string>
-
-
-//!\file
-//!Describes a class representing a xsi-based named_mutex.
-
-namespace boost {
-namespace interprocess {
-
-//!A class that wraps a XSI (System V)-based named semaphore
-//!that undoes the operation if the process crashes.
-class xsi_named_mutex
-{
- #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- //Non-copyable and non-assignable
- xsi_named_mutex(xsi_named_mutex &);
- xsi_named_mutex &operator=(xsi_named_mutex &);
- #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
-
- public:
- BOOST_MOVABLE_BUT_NOT_COPYABLE(xsi_named_mutex)
-
- //!Default constructor.
- //!Represents an empty xsi_named_mutex.
- xsi_named_mutex();
-
- //!Tries to create a new XSI-based named mutex with a key obtained from a call to ftok (with path
- //!"path" and id "id"), and permissions "perm".
- //!If the named mutex previously exists, it tries to open it.
- //!Otherwise throws an error.
- xsi_named_mutex(open_or_create_t, const char *path, boost::uint8_t id, int perm = 0666)
- { this->priv_open_or_create(ipcdetail::DoOpenOrCreate, path, id, perm); }
-
- //!Moves the ownership of "moved"'s named mutex to *this.
- //!After the call, "moved" does not represent any named mutex
- //!Does not throw
- xsi_named_mutex(BOOST_RV_REF(xsi_named_mutex) moved)
- { this->swap(moved); }
-
- //!Moves the ownership of "moved"'s named mutex to *this.
- //!After the call, "moved" does not represent any named mutex.
- //!Does not throw
- xsi_named_mutex &operator=(BOOST_RV_REF(xsi_named_mutex) moved)
- {
- xsi_named_mutex tmp(boost::move(moved));
- this->swap(tmp);
- return *this;
- }
-
- //!Swaps two xsi_named_mutex. Does not throw
- void swap(xsi_named_mutex &other);
-
- //!Destroys *this. The named mutex is still valid after
- //!destruction. use remove() to destroy the named mutex.
- ~xsi_named_mutex();
-
- //!Returns the path used to construct the
- //!named mutex.
- const char *get_path() const;
-
- //!Returns access
- //!permissions
- int get_permissions() const;
-
- //!Returns the mapping handle.
- //!Never throws
- mapping_handle_t get_mapping_handle() const;
-
- //!Erases a XSI-based named mutex from the system.
- //!Returns false on error. Never throws
- bool remove();
-
- void lock();
-
- void unlock();
-
- #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- private:
-
- //!Closes a previously opened file mapping. Never throws.
- void priv_close();
-
- //!Closes a previously opened file mapping. Never throws.
- bool priv_open_or_create( ipcdetail::create_enum_t type
- , const char *path
- , boost::uint8_t id
- , int perm);
- int m_semid;
- key_t m_key;
- boost::uint8_t m_id;
- int m_perm;
- std::string m_path;
- #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
-};
-
-#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-
-inline xsi_named_mutex::xsi_named_mutex()
- : m_semid(-1), m_key(-1), m_id(0), m_perm(0), m_path()
-{}
-
-inline xsi_named_mutex::~xsi_named_mutex()
-{ this->priv_close(); }
-
-inline const char *xsi_named_mutex::get_path() const
-{ return m_path.c_str(); }
-
-inline void xsi_named_mutex::swap(xsi_named_mutex &other)
-{
- (simple_swap)(m_key, other.m_key);
- (simple_swap)(m_id, other.m_id);
- (simple_swap)(m_semid, other.m_semid);
- (simple_swap)(m_perm, other.m_perm);
- m_path.swap(other.m_path);
-}
-
-inline mapping_handle_t xsi_named_mutex::get_mapping_handle() const
-{ mapping_handle_t mhnd = { m_semid, true}; return mhnd; }
-
-inline int xsi_named_mutex::get_permissions() const
-{ return m_perm; }
-
-inline bool xsi_named_mutex::priv_open_or_create
- (ipcdetail::create_enum_t type, const char *path, boost::uint8_t id, int perm)
-{
- key_t key;
- if(path){
- key = ::ftok(path, id);
- if(((key_t)-1) == key){
- error_info err = system_error_code();
- throw interprocess_exception(err);
- }
- }
- else{
- key = IPC_PRIVATE;
- }
-
- perm &= 0x01FF;
-
- int semid;
- if(!xsi::simple_sem_open_or_create(key, 1, semid, perm)){
- error_info err = system_error_code();
- throw interprocess_exception(err);
- }
-
- m_perm = perm;
- m_semid = semid;
- m_path = path ? path : "";
- m_id = id;
- m_key = key;
-
- return true;
-}
-
-inline void xsi_named_mutex::priv_close()
-{
-}
-
-inline void xsi_named_mutex::lock()
-{
- if(!xsi::simple_sem_op(m_semid, -1)){
- error_info err = system_error_code();
- throw interprocess_exception(err);
- }
-}
-
-inline void xsi_named_mutex::unlock()
-{
- bool success = xsi::simple_sem_op(m_semid, 1);
- (void)success;
- BOOST_ASSERT(success);
-}
-
-inline bool xsi_named_mutex::remove()
-{
- if(m_semid != -1){
- int ret = ::semctl(m_semid, IPC_RMID, 0);
- if(-1 == ret)
- return false;
- //Now put it in default-constructed state
- m_semid = -1;
- m_key = -1;
- m_id = 0;
- m_perm = 0;
- m_path.clear();
- }
- return false;
-}
-
-#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
-
-} //namespace interprocess {
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //BOOST_INTERPROCESS_XSI_XSI_NAMED_MUTEX_HPP
diff --git a/boost/intrusive/avl_set.hpp b/boost/intrusive/avl_set.hpp
index d06d441a19..c3d8d999ac 100644
--- a/boost/intrusive/avl_set.hpp
+++ b/boost/intrusive/avl_set.hpp
@@ -40,15 +40,15 @@ namespace intrusive {
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class avl_set_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder>
#endif
{
/// @cond
- typedef bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder> tree_type;
+ typedef bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_set_impl)
typedef tree_type implementation_defined;
@@ -56,6 +56,8 @@ class avl_set_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -80,16 +82,16 @@ class avl_set_impl
public:
- //! @copydoc ::boost::intrusive::avltree::avltree(const value_compare &,const value_traits &)
- explicit avl_set_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::avltree::avltree(const key_compare &,const value_traits &)
+ explicit avl_set_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::avltree::avltree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::avltree::avltree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
avl_set_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(true, b, e, cmp, v_traits)
{}
@@ -171,11 +173,20 @@ class avl_set_impl
//! @copydoc ::boost::intrusive::avltree::swap
void swap(avl_set_impl& other);
- //! @copydoc ::boost::intrusive::avltree::clone_from
+ //! @copydoc ::boost::intrusive::avltree::clone_from(const avltree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const avl_set_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::avltree::clone_from(avltree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(avl_set_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::avltree::insert_unique(reference)
std::pair<iterator, bool> insert(reference value)
@@ -185,18 +196,18 @@ class avl_set_impl
iterator insert(const_iterator hint, reference value)
{ return tree_type::insert_unique(hint, value); }
- //! @copydoc ::boost::intrusive::avltree::insert_unique_check(const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::avltree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(key, key_value_comp, commit_data); }
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(key, comp, commit_data); }
- //! @copydoc ::boost::intrusive::avltree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::avltree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(hint, key, key_value_comp, commit_data); }
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(hint, key, comp, commit_data); }
//! @copydoc ::boost::intrusive::avltree::insert_unique(Iterator,Iterator)
template<class Iterator>
@@ -223,12 +234,12 @@ class avl_set_impl
//! @copydoc ::boost::intrusive::avltree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::avltree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::erase(const key_type &key)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -238,13 +249,13 @@ class avl_set_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::avltree::clear
void clear();
@@ -255,100 +266,100 @@ class avl_set_impl
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::avltree::count(const_reference)const
- size_type count(const_reference value) const
- { return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
+ //! @copydoc ::boost::intrusive::avltree::count(const key_type &)const
+ size_type count(const key_type &key) const
+ { return static_cast<size_type>(this->tree_type::find(key) != this->tree_type::cend()); }
- //! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const
+ //! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::avltree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::avltree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::avltree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->tree_type::lower_bound_range(value); }
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key)
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp)
{ return this->tree_type::lower_bound_range(key, comp); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->tree_type::lower_bound_range(value); }
+ equal_range(const key_type &key) const
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const
{ return this->tree_type::lower_bound_range(key, comp); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::avltree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -402,7 +413,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_avl_set
{
@@ -410,7 +421,7 @@ struct make_avl_set
typedef typename pack_options
< avltree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -421,6 +432,7 @@ struct make_avl_set
typedef avl_set_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -432,14 +444,14 @@ struct make_avl_set
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class avl_set
: public make_avl_set<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -448,7 +460,7 @@ class avl_set
typedef typename make_avl_set
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -456,7 +468,7 @@ class avl_set
BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_set)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -464,14 +476,14 @@ class avl_set
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit avl_set( const value_compare &cmp = value_compare()
+ explicit avl_set( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
avl_set( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -483,6 +495,14 @@ class avl_set
avl_set& operator=(BOOST_RV_REF(avl_set) x)
{ return static_cast<avl_set &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const avl_set &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(avl_set) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static avl_set &container_from_end_iterator(iterator end_iterator)
{ return static_cast<avl_set &>(Base::container_from_end_iterator(end_iterator)); }
@@ -512,15 +532,15 @@ class avl_set
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class avl_multiset_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder>
#endif
{
/// @cond
- typedef bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder> tree_type;
+ typedef bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_multiset_impl)
typedef tree_type implementation_defined;
@@ -528,6 +548,8 @@ class avl_multiset_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -551,16 +573,16 @@ class avl_multiset_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::avltree::avltree(const value_compare &,const value_traits &)
- explicit avl_multiset_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::avltree::avltree(const key_compare &,const value_traits &)
+ explicit avl_multiset_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::avltree::avltree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::avltree::avltree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
avl_multiset_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(false, b, e, cmp, v_traits)
{}
@@ -641,11 +663,20 @@ class avl_multiset_impl
//! @copydoc ::boost::intrusive::avltree::swap
void swap(avl_multiset_impl& other);
- //! @copydoc ::boost::intrusive::avltree::clone_from
+ //! @copydoc ::boost::intrusive::avltree::clone_from(const avltree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const avl_multiset_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::avltree::clone_from(avltree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(avl_multiset_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::avltree::insert_equal(reference)
iterator insert(reference value)
@@ -676,12 +707,12 @@ class avl_multiset_impl
//! @copydoc ::boost::intrusive::avltree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::avltree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -691,13 +722,13 @@ class avl_multiset_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::avltree::clear
void clear();
@@ -706,88 +737,88 @@ class avl_multiset_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::avltree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::avltree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::avltree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::avltree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::avltree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::avltree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::avltree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::avltree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &key upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::avltree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -841,7 +872,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_avl_multiset
{
@@ -849,7 +880,7 @@ struct make_avl_multiset
typedef typename pack_options
< avltree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -860,6 +891,7 @@ struct make_avl_multiset
typedef avl_multiset_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -872,14 +904,14 @@ struct make_avl_multiset
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class avl_multiset
: public make_avl_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -887,7 +919,7 @@ class avl_multiset
{
typedef typename make_avl_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -896,7 +928,7 @@ class avl_multiset
BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_multiset)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -904,14 +936,14 @@ class avl_multiset
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit avl_multiset( const value_compare &cmp = value_compare()
+ explicit avl_multiset( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
avl_multiset( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -923,6 +955,14 @@ class avl_multiset
avl_multiset& operator=(BOOST_RV_REF(avl_multiset) x)
{ return static_cast<avl_multiset &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const avl_multiset &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(avl_multiset) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static avl_multiset &container_from_end_iterator(iterator end_iterator)
{ return static_cast<avl_multiset &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/avltree.hpp b/boost/intrusive/avltree.hpp
index 1996d69c68..8462293d6f 100644
--- a/boost/intrusive/avltree.hpp
+++ b/boost/intrusive/avltree.hpp
@@ -48,19 +48,16 @@ struct is_default_hook_tag<default_avltree_hook_applier>
{ static const bool value = true; };
struct avltree_defaults
+ : bstree_defaults
{
typedef default_avltree_hook_applier proto_value_traits;
- static const bool constant_time_size = true;
- typedef std::size_t size_type;
- typedef void compare;
- typedef void header_holder_type;
};
/// @endcond
//! The class template avltree is an intrusive AVL tree container, that
//! is used to construct intrusive avl_set and avl_multiset containers.
-//! The no-throw guarantee holds only, if the value_compare object
+//! The no-throw guarantee holds only, if the key_compare object
//! doesn't throw.
//!
//! The template parameter \c T is the type to be managed by the container.
@@ -74,17 +71,17 @@ struct avltree_defaults
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class avltree_impl
/// @cond
- : public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder>
/// @endcond
{
public:
typedef ValueTraits value_traits;
/// @cond
- typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
+ typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
, ConstantTimeSize, AvlTreeAlgorithms
, HeaderHolder> tree_type;
typedef tree_type implementation_defined;
@@ -94,6 +91,7 @@ class avltree_impl
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
@@ -124,16 +122,16 @@ class avltree_impl
typedef typename implementation_defined::insert_commit_data insert_commit_data;
- //! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &)
- explicit avltree_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
+ explicit avltree_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
avltree_impl( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(unique, b, e, cmp, v_traits)
{}
@@ -215,10 +213,23 @@ class avltree_impl
//! @copydoc ::boost::intrusive::bstree::swap
void swap(avltree_impl& other);
- //! @copydoc ::boost::intrusive::bstree::clone_from
+ //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const avltree_impl &src, Cloner cloner, Disposer disposer);
+ #else //BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(avltree_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
+
+ #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
iterator insert_equal(reference value);
@@ -235,16 +246,16 @@ class avltree_impl
//! @copydoc ::boost::intrusive::bstree::insert_unique(const_iterator,reference)
iterator insert_unique(const_iterator hint, reference value);
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data);
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_commit
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data);
@@ -268,12 +279,12 @@ class avltree_impl
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::bstree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -283,13 +294,13 @@ class avltree_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::clear
void clear();
@@ -298,88 +309,88 @@ class avltree_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &ke)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &key)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -404,33 +415,23 @@ class avltree_impl
//! @copydoc ::boost::intrusive::bstree::remove_node
void remove_node(reference value);
- #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
-};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ friend bool operator< (const avltree_impl &x, const avltree_impl &y);
-template<class T, class ...Options>
-bool operator< (const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
+ friend bool operator==(const avltree_impl &x, const avltree_impl &y);
-template<class T, class ...Options>
-bool operator==(const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
+ friend bool operator!= (const avltree_impl &x, const avltree_impl &y);
-template<class T, class ...Options>
-bool operator!= (const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator>(const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
+ friend bool operator>(const avltree_impl &x, const avltree_impl &y);
-template<class T, class ...Options>
-bool operator<=(const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
+ friend bool operator<=(const avltree_impl &x, const avltree_impl &y);
-template<class T, class ...Options>
-bool operator>=(const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
+ friend bool operator>=(const avltree_impl &x, const avltree_impl &y);
-template<class T, class ...Options>
-void swap(avltree_impl<T, Options...> &x, avltree_impl<T, Options...> &y);
+ friend void swap(avltree_impl &x, avltree_impl &y);
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+};
-#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! Helper metafunction to define a \c avltree that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
@@ -439,7 +440,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_avltree
{
@@ -447,7 +448,7 @@ struct make_avltree
typedef typename pack_options
< avltree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -458,6 +459,7 @@ struct make_avltree
typedef avltree_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -471,14 +473,14 @@ struct make_avltree
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class avltree
: public make_avltree<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -487,7 +489,7 @@ class avltree
typedef typename make_avltree
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -495,7 +497,7 @@ class avltree
BOOST_MOVABLE_BUT_NOT_COPYABLE(avltree)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -505,14 +507,14 @@ class avltree
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit avltree( const value_compare &cmp = value_compare()
+ explicit avltree( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
avltree( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, v_traits)
{}
@@ -524,6 +526,14 @@ class avltree
avltree& operator=(BOOST_RV_REF(avltree) x)
{ return static_cast<avltree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const avltree &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(avltree) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static avltree &container_from_end_iterator(iterator end_iterator)
{ return static_cast<avltree &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/bs_set.hpp b/boost/intrusive/bs_set.hpp
index f246ce606d..a46ca38a01 100644
--- a/boost/intrusive/bs_set.hpp
+++ b/boost/intrusive/bs_set.hpp
@@ -40,15 +40,15 @@ namespace intrusive {
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class bs_set_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>
#endif
{
/// @cond
- typedef bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder> tree_type;
+ typedef bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_set_impl)
typedef tree_type implementation_defined;
@@ -56,6 +56,7 @@ class bs_set_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -79,16 +80,16 @@ class bs_set_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &)
- explicit bs_set_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
+ explicit bs_set_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
bs_set_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(true, b, e, cmp, v_traits)
{}
@@ -169,11 +170,20 @@ class bs_set_impl
//! @copydoc ::boost::intrusive::bstree::swap
void swap(bs_set_impl& other);
- //! @copydoc ::boost::intrusive::bstree::clone_from
+ //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const bs_set_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(bs_set_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::bstree::insert_unique(reference)
std::pair<iterator, bool> insert(reference value)
@@ -183,18 +193,18 @@ class bs_set_impl
iterator insert(const_iterator hint, reference value)
{ return tree_type::insert_unique(hint, value); }
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(key, key_value_comp, commit_data); }
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(key, comp, commit_data); }
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(hint, key, key_value_comp, commit_data); }
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(hint, key, comp, commit_data); }
//! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator)
template<class Iterator>
@@ -221,12 +231,12 @@ class bs_set_impl
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::bstree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -236,13 +246,13 @@ class bs_set_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::clear
void clear();
@@ -253,100 +263,100 @@ class bs_set_impl
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
- size_type count(const_reference value) const
- { return static_cast<size_type>(this->tree_type::find(value) == this->tree_type::cend()); }
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
+ size_type count(const key_type &key) const
+ { return static_cast<size_type>(this->tree_type::find(key) != this->tree_type::cend()); }
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const
- { return static_cast<size_type>(this->tree_type::find(key, comp) == this->tree_type::cend()); }
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const
+ { return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->tree_type::lower_bound_range(value); }
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key)
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp)
{ return this->tree_type::lower_bound_range(key, comp); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->tree_type::lower_bound_range(value); }
+ equal_range(const key_type &key) const
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const
{ return this->tree_type::lower_bound_range(key, comp); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type&,const key_type&,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type& lower_key, const key_type& upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type&,const key_type&,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type& lower_key, const key_type& upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -400,7 +410,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_bs_set
{
@@ -408,7 +418,7 @@ struct make_bs_set
typedef typename pack_options
< bstree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -419,6 +429,7 @@ struct make_bs_set
typedef bs_set_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -430,14 +441,14 @@ struct make_bs_set
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class bs_set
: public make_bs_set<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -446,7 +457,7 @@ class bs_set
typedef typename make_bs_set
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -454,22 +465,22 @@ class bs_set
BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_set)
public:
- typedef typename Base::value_compare value_compare;
typedef typename Base::value_traits value_traits;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit bs_set( const value_compare &cmp = value_compare()
+ explicit bs_set( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
bs_set( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -481,6 +492,14 @@ class bs_set
bs_set& operator=(BOOST_RV_REF(bs_set) x)
{ return static_cast<bs_set &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const bs_set &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(bs_set) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static bs_set &container_from_end_iterator(iterator end_iterator)
{ return static_cast<bs_set &>(Base::container_from_end_iterator(end_iterator)); }
@@ -510,15 +529,15 @@ class bs_set
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class bs_multiset_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>
#endif
{
/// @cond
- typedef bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder> tree_type;
+ typedef bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_multiset_impl)
typedef tree_type implementation_defined;
@@ -526,6 +545,7 @@ class bs_multiset_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -549,16 +569,16 @@ class bs_multiset_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &)
- explicit bs_multiset_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
+ explicit bs_multiset_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
bs_multiset_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(false, b, e, cmp, v_traits)
{}
@@ -639,11 +659,20 @@ class bs_multiset_impl
//! @copydoc ::boost::intrusive::bstree::swap
void swap(bs_multiset_impl& other);
- //! @copydoc ::boost::intrusive::bstree::clone_from
+ //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const bs_multiset_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(bs_multiset_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
iterator insert(reference value)
@@ -674,12 +703,12 @@ class bs_multiset_impl
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::bstree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -689,13 +718,13 @@ class bs_multiset_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::clear
void clear();
@@ -704,88 +733,88 @@ class bs_multiset_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type & lower_key, const key_type & upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type & lower_key, const key_type & upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -839,7 +868,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_bs_multiset
{
@@ -847,7 +876,7 @@ struct make_bs_multiset
typedef typename pack_options
< bstree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -858,6 +887,7 @@ struct make_bs_multiset
typedef bs_multiset_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -870,14 +900,14 @@ struct make_bs_multiset
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class bs_multiset
: public make_bs_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -885,7 +915,7 @@ class bs_multiset
{
typedef typename make_bs_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -894,7 +924,7 @@ class bs_multiset
BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_multiset)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -902,14 +932,14 @@ class bs_multiset
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit bs_multiset( const value_compare &cmp = value_compare()
+ explicit bs_multiset( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
bs_multiset( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -921,6 +951,14 @@ class bs_multiset
bs_multiset& operator=(BOOST_RV_REF(bs_multiset) x)
{ return static_cast<bs_multiset &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const bs_multiset &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(bs_multiset) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static bs_multiset &container_from_end_iterator(iterator end_iterator)
{ return static_cast<bs_multiset &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/bstree.hpp b/boost/intrusive/bstree.hpp
index 39c9d3ed2a..7a67de6e12 100644
--- a/boost/intrusive/bstree.hpp
+++ b/boost/intrusive/bstree.hpp
@@ -35,6 +35,7 @@
#include <boost/intrusive/detail/size_holder.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#include <boost/intrusive/detail/algorithm.hpp>
+#include <boost/intrusive/detail/tree_value_compare.hpp>
#include <boost/intrusive/detail/get_value_traits.hpp>
#include <boost/intrusive/bstree_algorithms.hpp>
@@ -69,6 +70,7 @@ struct bstree_defaults
static const bool constant_time_size = true;
typedef std::size_t size_type;
typedef void compare;
+ typedef void key_of_value;
static const bool floating_point = true; //For sgtree
typedef void priority; //For treap
typedef void header_holder_type;
@@ -90,7 +92,6 @@ struct bstbase3
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type) value_type;
- typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference) const_reference;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type) difference_type;
@@ -239,28 +240,62 @@ struct get_compare<void, T>
typedef ::std::less<T> type;
};
-template<class ValueTraits, class VoidOrKeyComp, algo_types AlgoType, typename HeaderHolder>
+template<class KeyOfValue, class T>
+struct get_key_of_value
+{
+ typedef KeyOfValue type;
+};
+
+template<class T>
+struct get_key_of_value<void, T>
+{
+ typedef ::boost::intrusive::detail::identity<T> type;
+};
+
+template<class T, class VoidOrKeyOfValue, class VoidOrKeyComp>
+struct bst_key_types
+{
+ typedef typename get_key_of_value
+ < VoidOrKeyOfValue, T>::type key_of_value;
+ typedef typename key_of_value::type key_type;
+ typedef typename get_compare< VoidOrKeyComp
+ , key_type
+ >::type key_compare;
+ typedef tree_value_compare
+ <key_type, T, key_compare, key_of_value> value_compare;
+};
+
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, algo_types AlgoType, typename HeaderHolder>
struct bstbase2
//Put the (possibly empty) functor in the first position to get EBO in MSVC
//Use public inheritance to avoid MSVC bugs with closures
- : public detail::ebo_functor_holder<typename get_compare< VoidOrKeyComp
- , typename ValueTraits::value_type
- >::type>
+ : public detail::ebo_functor_holder
+ < typename bst_key_types
+ < typename ValueTraits::value_type
+ , VoidOrKeyOfValue
+ , VoidOrKeyComp
+ >::value_compare
+ >
, public bstbase3<ValueTraits, AlgoType, HeaderHolder>
{
typedef bstbase3<ValueTraits, AlgoType, HeaderHolder> treeheader_t;
+ typedef bst_key_types< typename ValueTraits::value_type
+ , VoidOrKeyOfValue
+ , VoidOrKeyComp> key_types;
typedef typename treeheader_t::value_traits value_traits;
typedef typename treeheader_t::node_algorithms node_algorithms;
- typedef typename get_compare
- < VoidOrKeyComp, typename value_traits::value_type>::type value_compare;
- typedef BOOST_INTRUSIVE_IMPDEF(value_compare) key_compare;
+ typedef typename ValueTraits::value_type value_type;
+ typedef typename key_types::key_type key_type;
+ typedef typename key_types::key_of_value key_of_value;
+ typedef typename key_types::key_compare key_compare;
+ typedef typename key_types::value_compare value_compare;
typedef typename treeheader_t::iterator iterator;
typedef typename treeheader_t::const_iterator const_iterator;
typedef typename treeheader_t::node_ptr node_ptr;
typedef typename treeheader_t::const_node_ptr const_node_ptr;
- bstbase2(const value_compare &comp, const ValueTraits &vtraits)
- : detail::ebo_functor_holder<value_compare>(comp), treeheader_t(vtraits)
+ bstbase2(const key_compare &comp, const ValueTraits &vtraits)
+ : detail::ebo_functor_holder<value_compare>(value_compare(comp)), treeheader_t(vtraits)
{}
const value_compare &comp() const
@@ -271,8 +306,6 @@ struct bstbase2
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
- typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type) value_type;
- typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference) const_reference;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type) difference_type;
@@ -282,203 +315,181 @@ struct bstbase2
{ return this->comp(); }
key_compare key_comp() const
- { return this->comp(); }
+ { return this->comp().key_comp(); }
//lower_bound
- iterator lower_bound(const_reference value)
- { return this->lower_bound(value, this->comp()); }
+ iterator lower_bound(const key_type &key)
+ { return this->lower_bound(key, this->key_comp()); }
- const_iterator lower_bound(const_reference value) const
- { return this->lower_bound(value, this->comp()); }
+ const_iterator lower_bound(const key_type &key) const
+ { return this->lower_bound(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType &key, KeyValueCompare comp)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
return iterator(node_algorithms::lower_bound
- (this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
+ (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
}
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) const
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
return const_iterator(node_algorithms::lower_bound
- (this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
+ (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
}
//upper_bound
- iterator upper_bound(const_reference value)
- { return this->upper_bound(value, this->comp()); }
+ iterator upper_bound(const key_type &key)
+ { return this->upper_bound(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType &key, KeyValueCompare comp)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
return iterator(node_algorithms::upper_bound
- (this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
+ (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
}
- const_iterator upper_bound(const_reference value) const
- { return this->upper_bound(value, this->comp()); }
+ const_iterator upper_bound(const key_type &key) const
+ { return this->upper_bound(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) const
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
return const_iterator(node_algorithms::upper_bound
- (this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
+ (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
+ }
+
+ template<class KeyTypeKeyCompare>
+ detail::key_nodeptr_comp<KeyTypeKeyCompare, value_traits, key_of_value> key_node_comp(KeyTypeKeyCompare comp) const
+ {
+ return detail::key_nodeptr_comp<KeyTypeKeyCompare, value_traits, key_of_value>(comp, &this->get_value_traits());
}
//find
- iterator find(const_reference value)
- { return this->find(value, this->comp()); }
+ iterator find(const key_type &key)
+ { return this->find(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType &key, KeyValueCompare comp)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType &key, KeyTypeKeyCompare comp)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
return iterator
- (node_algorithms::find(this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
+ (node_algorithms::find(this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
}
- const_iterator find(const_reference value) const
- { return this->find(value, this->comp()); }
+ const_iterator find(const key_type &key) const
+ { return this->find(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType &key, KeyValueCompare comp) const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType &key, KeyTypeKeyCompare comp) const
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
return const_iterator
- (node_algorithms::find(this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
+ (node_algorithms::find(this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
}
//equal_range
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->equal_range(value, this->comp()); }
+ std::pair<iterator,iterator> equal_range(const key_type &key)
+ { return this->equal_range(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType &key, KeyValueCompare comp)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
- (node_algorithms::equal_range(this->header_ptr(), key, key_node_comp));
+ (node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp)));
return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
, iterator(ret.second, this->priv_value_traits_ptr()));
}
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->equal_range(value, this->comp()); }
+ equal_range(const key_type &key) const
+ { return this->equal_range(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType &key, KeyValueCompare comp) const
+ equal_range(const KeyType &key, KeyTypeKeyCompare comp) const
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
- (node_algorithms::equal_range(this->header_ptr(), key, key_node_comp));
+ (node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp)));
return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
, const_iterator(ret.second, this->priv_value_traits_ptr()));
}
//lower_bound_range
- std::pair<iterator,iterator> lower_bound_range(const_reference value)
- { return this->lower_bound_range(value, this->comp()); }
+ std::pair<iterator,iterator> lower_bound_range(const key_type &key)
+ { return this->lower_bound_range(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> lower_bound_range(const KeyType &key, KeyValueCompare comp)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> lower_bound_range(const KeyType &key, KeyTypeKeyCompare comp)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
- (node_algorithms::lower_bound_range(this->header_ptr(), key, key_node_comp));
+ (node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp)));
return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
, iterator(ret.second, this->priv_value_traits_ptr()));
}
std::pair<const_iterator, const_iterator>
- lower_bound_range(const_reference value) const
- { return this->lower_bound_range(value, this->comp()); }
+ lower_bound_range(const key_type &key) const
+ { return this->lower_bound_range(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- lower_bound_range(const KeyType &key, KeyValueCompare comp) const
+ lower_bound_range(const KeyType &key, KeyTypeKeyCompare comp) const
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
- (node_algorithms::lower_bound_range(this->header_ptr(), key, key_node_comp));
+ (node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp)));
return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
, const_iterator(ret.second, this->priv_value_traits_ptr()));
}
//bounded_range
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed)
- { return this->bounded_range(lower_value, upper_value, this->comp(), left_closed, right_closed); }
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed)
+ { return this->bounded_range(lower_key, upper_key, this->key_comp(), left_closed, right_closed); }
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed)
+ (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
(node_algorithms::bounded_range
- (this->header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed));
+ (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed));
return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
, iterator(ret.second, this->priv_value_traits_ptr()));
}
std::pair<const_iterator,const_iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const
- { return this->bounded_range(lower_value, upper_value, this->comp(), left_closed, right_closed); }
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const
+ { return this->bounded_range(lower_key, upper_key, this->key_comp(), left_closed, right_closed); }
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator,const_iterator> bounded_range
- (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const
+ (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
(node_algorithms::bounded_range
- (this->header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed));
+ (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed));
return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
, const_iterator(ret.second, this->priv_value_traits_ptr()));
}
//insert_unique_check
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- ocomp(key_value_comp, &this->get_value_traits());
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
- (this->header_ptr(), key, ocomp, commit_data));
+ (this->header_ptr(), key, this->key_node_comp(comp), commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
}
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- ocomp(key_value_comp, &this->get_value_traits());
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
- (this->header_ptr(), hint.pointed_node(), key, ocomp, commit_data));
+ (this->header_ptr(), hint.pointed_node(), key, this->key_node_comp(comp), commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
}
};
@@ -486,19 +497,20 @@ struct bstbase2
//Due to MSVC's EBO implementation, to save space and maintain the ABI, we must put the non-empty size member
//in the first position, but if size is not going to be stored then we'll use an specialization
//that doesn't inherit from size_holder
-template<class ValueTraits, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType, typename HeaderHolder>
struct bstbase_hack
: public detail::size_holder<ConstantTimeSize, SizeType>
- , public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType, HeaderHolder>
+ , public bstbase2 < ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder>
{
- typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType, HeaderHolder> base_type;
+ typedef bstbase2< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder> base_type;
+ typedef typename base_type::key_compare key_compare;
typedef typename base_type::value_compare value_compare;
typedef SizeType size_type;
typedef typename base_type::node_traits node_traits;
typedef typename get_algo
<AlgoType, node_traits>::type algo_type;
- bstbase_hack(const value_compare & comp, const ValueTraits &vtraits)
+ bstbase_hack(const key_compare & comp, const ValueTraits &vtraits)
: base_type(comp, vtraits)
{
this->sz_traits().set_size(size_type(0));
@@ -514,17 +526,18 @@ struct bstbase_hack
};
//Specialization for ConstantTimeSize == false
-template<class ValueTraits, class VoidOrKeyComp, class SizeType, algo_types AlgoType, typename HeaderHolder>
-struct bstbase_hack<ValueTraits, VoidOrKeyComp, false, SizeType, AlgoType, HeaderHolder>
- : public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType, HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, algo_types AlgoType, typename HeaderHolder>
+struct bstbase_hack<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, false, SizeType, AlgoType, HeaderHolder>
+ : public bstbase2 < ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder>
{
- typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType, HeaderHolder> base_type;
+ typedef bstbase2< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder> base_type;
typedef typename base_type::value_compare value_compare;
- bstbase_hack(const value_compare & comp, const ValueTraits &vtraits)
+ typedef typename base_type::key_compare key_compare;
+ bstbase_hack(const key_compare & comp, const ValueTraits &vtraits)
: base_type(comp, vtraits)
{}
- typedef detail::size_holder<true, SizeType> size_traits;
+ typedef detail::size_holder<false, SizeType> size_traits;
size_traits &sz_traits()
{ return s_size_traits; }
@@ -535,18 +548,18 @@ struct bstbase_hack<ValueTraits, VoidOrKeyComp, false, SizeType, AlgoType, Heade
static size_traits s_size_traits;
};
-template<class ValueTraits, class VoidOrKeyComp, class SizeType, algo_types AlgoType, typename HeaderHolder>
-detail::size_holder<true, SizeType> bstbase_hack<ValueTraits, VoidOrKeyComp, false, SizeType, AlgoType, HeaderHolder>::s_size_traits;
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, algo_types AlgoType, typename HeaderHolder>
+detail::size_holder<false, SizeType> bstbase_hack<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, false, SizeType, AlgoType, HeaderHolder>::s_size_traits;
//This class will
-template<class ValueTraits, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType, typename HeaderHolder>
struct bstbase
- : public bstbase_hack< ValueTraits, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder>
+ : public bstbase_hack< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder>
{
- typedef bstbase_hack< ValueTraits, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> base_type;
+ typedef bstbase_hack< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> base_type;
typedef ValueTraits value_traits;
typedef typename base_type::value_compare value_compare;
- typedef value_compare key_compare;
+ typedef typename base_type::key_compare key_compare;
typedef typename base_type::const_reference const_reference;
typedef typename base_type::reference reference;
typedef typename base_type::iterator iterator;
@@ -556,7 +569,7 @@ struct bstbase
<AlgoType, node_traits>::type node_algorithms;
typedef SizeType size_type;
- bstbase(const value_compare & comp, const ValueTraits &vtraits)
+ bstbase(const key_compare & comp, const ValueTraits &vtraits)
: base_type(comp, vtraits)
{}
@@ -578,7 +591,7 @@ struct bstbase
/// @endcond
//! The class template bstree is an unbalanced intrusive binary search tree
-//! container. The no-throw guarantee holds only, if the value_compare object
+//! container. The no-throw guarantee holds only, if the key_compare object
//! doesn't throw.
//!
//! The complexity guarantees only hold if the tree is balanced, logarithmic
@@ -595,14 +608,14 @@ struct bstbase
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
#endif
class bstree_impl
- : public bstbase<ValueTraits, VoidKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder>
+ : public bstbase<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder>
{
public:
/// @cond
- typedef bstbase<ValueTraits, VoidKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> data_type;
+ typedef bstbase<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> data_type;
typedef tree_iterator<ValueTraits, false> iterator_type;
typedef tree_iterator<ValueTraits, true> const_iterator_type;
/// @endcond
@@ -611,13 +624,14 @@ class bstree_impl
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type) value_type;
- typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type;
+ typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_type) key_type;
+ typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_of_value) key_of_value;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference) const_reference;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type) difference_type;
typedef BOOST_INTRUSIVE_IMPDEF(SizeType) size_type;
typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::value_compare) value_compare;
- typedef BOOST_INTRUSIVE_IMPDEF(value_compare) key_compare;
+ typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_compare) key_compare;
typedef BOOST_INTRUSIVE_IMPDEF(iterator_type) iterator;
typedef BOOST_INTRUSIVE_IMPDEF(const_iterator_type) const_iterator;
typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::reverse_iterator<iterator>) reverse_iterator;
@@ -660,8 +674,8 @@ class bstree_impl
//!
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor of the value_compare object throws. Basic guarantee.
- explicit bstree_impl( const value_compare &cmp = value_compare()
+ //! or the copy constructor of the key_compare object throws. Basic guarantee.
+ explicit bstree_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: data_type(cmp, v_traits)
{}
@@ -677,10 +691,10 @@ class bstree_impl
//!
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor/operator() of the value_compare object throws. Basic guarantee.
+ //! or the copy constructor/operator() of the key_compare object throws. Basic guarantee.
template<class Iterator>
bstree_impl( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: data_type(cmp, v_traits)
{
@@ -863,7 +877,7 @@ class bstree_impl
//!
//! <b>Complexity</b>: Constant.
//!
- //! <b>Throws</b>: If value_compare copy-constructor throws.
+ //! <b>Throws</b>: If key_compare copy-constructor throws.
key_compare key_comp() const;
//! <b>Effects</b>: Returns the value_compare object used by the container.
@@ -960,7 +974,7 @@ class bstree_impl
//!
//! <b>Effects</b>: Erases all the elements from *this
//! calling Disposer::operator()(pointer), clones all the
- //! elements from src calling Cloner::operator()(const_reference )
+ //! elements from src calling Cloner::operator()(reference)
//! and inserts them on *this. Copies the predicate from the source container.
//!
//! If cloner throws, all cloned elements are unlinked and disposed
@@ -973,7 +987,7 @@ class bstree_impl
//! <b>Note</b>: This version can modify the source container, useful to implement
//! move semantics.
template <class Cloner, class Disposer>
- void clone_from(bstree_impl &src, Cloner cloner, Disposer disposer)
+ void clone_from(BOOST_RV_REF(bstree_impl) src, Cloner cloner, Disposer disposer)
{
this->clear_and_dispose(disposer);
if(!src.empty()){
@@ -997,19 +1011,17 @@ class bstree_impl
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
- //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If the internal key_compare ordering function throws. Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
iterator insert_equal(reference value)
{
- detail::key_nodeptr_comp<value_compare, value_traits>
- key_node_comp(this->comp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret(node_algorithms::insert_equal_upper_bound
- (this->header_ptr(), to_insert, key_node_comp), this->priv_value_traits_ptr());
+ (this->header_ptr(), to_insert, this->key_node_comp(this->key_comp())), this->priv_value_traits_ptr());
this->sz_traits().increment();
return ret;
}
@@ -1024,19 +1036,17 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic in general, but it is amortized
//! constant time if t is inserted immediately before hint.
//!
- //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If the internal key_compare ordering function throws. Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
iterator insert_equal(const_iterator hint, reference value)
{
- detail::key_nodeptr_comp<value_compare, value_traits>
- key_node_comp(this->comp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret(node_algorithms::insert_equal
- (this->header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this->priv_value_traits_ptr());
+ (this->header_ptr(), hint.pointed_node(), to_insert, this->key_node_comp(this->key_comp())), this->priv_value_traits_ptr());
this->sz_traits().increment();
return ret;
}
@@ -1078,10 +1088,13 @@ class bstree_impl
std::pair<iterator, bool> insert_unique(reference value)
{
insert_commit_data commit_data;
- std::pair<iterator, bool> ret = this->insert_unique_check(value, this->comp(), commit_data);
- if(!ret.second)
- return ret;
- return std::pair<iterator, bool> (this->insert_unique_commit(value, commit_data), true);
+ std::pair<node_ptr, bool> ret =
+ (node_algorithms::insert_unique_check
+ (this->header_ptr(), key_of_value()(value), this->key_node_comp(this->key_comp()), commit_data));
+ return std::pair<iterator, bool>
+ ( ret.second ? this->insert_unique_commit(value, commit_data)
+ : iterator(ret.first, this->priv_value_traits_ptr())
+ , ret.second);
}
//! <b>Requires</b>: value must be an lvalue, and "hint" must be
@@ -1101,10 +1114,11 @@ class bstree_impl
iterator insert_unique(const_iterator hint, reference value)
{
insert_commit_data commit_data;
- std::pair<iterator, bool> ret = this->insert_unique_check(hint, value, this->comp(), commit_data);
- if(!ret.second)
- return ret.first;
- return this->insert_unique_commit(value, commit_data);
+ std::pair<node_ptr, bool> ret =
+ (node_algorithms::insert_unique_check
+ (this->header_ptr(), hint.pointed_node(), key_of_value()(value), this->key_node_comp(this->key_comp()), commit_data));
+ return ret.second ? this->insert_unique_commit(value, commit_data)
+ : iterator(ret.first, this->priv_value_traits_ptr());
}
//! <b>Requires</b>: Dereferencing iterator must yield an lvalue
@@ -1136,9 +1150,9 @@ class bstree_impl
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! <b>Requires</b>: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an arbitrary key with the contained values.
+ //! <b>Requires</b>: comp must be a comparison function that induces
+ //! the same strict weak ordering as key_compare. The difference is that
+ //! comp compares an arbitrary key with the contained values.
//!
//! <b>Effects</b>: Checks if a value can be inserted in the container, using
//! a user provided key instead of the value itself.
@@ -1151,7 +1165,7 @@ class bstree_impl
//!
//! <b>Complexity</b>: Average complexity is at most logarithmic.
//!
- //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If the comp ordering function throws. Strong guarantee.
//!
//! <b>Notes</b>: This function is used to improve performance when constructing
//! a value_type is expensive: if there is an equivalent value
@@ -1166,13 +1180,13 @@ class bstree_impl
//!
//! "commit_data" remains valid for a subsequent "insert_commit" only if no more
//! objects are inserted or erased from the container.
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data);
- //! <b>Requires</b>: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an arbitrary key with the contained values.
+ //! <b>Requires</b>: comp must be a comparison function that induces
+ //! the same strict weak ordering as key_compare. The difference is that
+ //! comp compares an arbitrary key with the contained values.
//!
//! <b>Effects</b>: Checks if a value can be inserted in the container, using
//! a user provided key instead of the value itself, using "hint"
@@ -1187,7 +1201,7 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic in general, but it's amortized
//! constant time if t is inserted immediately before hint.
//!
- //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If the comp ordering function throws. Strong guarantee.
//!
//! <b>Notes</b>: This function is used to improve performance when constructing
//! a value_type is expensive: if there is an equivalent value
@@ -1202,10 +1216,10 @@ class bstree_impl
//!
//! "commit_data" remains valid for a subsequent "insert_commit" only if no more
//! objects are inserted or erased from the container.
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data);
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
@@ -1351,8 +1365,8 @@ class bstree_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- size_type erase(const_reference value)
- { return this->erase(value, this->comp()); }
+ size_type erase(const key_type &key)
+ { return this->erase(key, this->key_comp()); }
//! <b>Effects</b>: Erases all the elements with the given key.
//! according to the comparison functor "comp".
@@ -1365,12 +1379,10 @@ class bstree_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
- /// @endcond
- )
+ template<class KeyType, class KeyTypeKeyCompare>
+ BOOST_INTRUSIVE_DOC1ST(size_type
+ , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
+ erase(const KeyType& key, KeyTypeKeyCompare comp)
{
std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n;
@@ -1398,12 +1410,6 @@ class bstree_impl
return ret;
}
- #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
- template<class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
- { return this->erase_and_dispose(const_iterator(i), disposer); }
- #endif
-
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//!
//! <b>Effects</b>: Erases all the elements with the given value.
@@ -1418,9 +1424,9 @@ class bstree_impl
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer)
+ size_type erase_and_dispose(const key_type &key, Disposer disposer)
{
- std::pair<iterator,iterator> p = this->equal_range(value);
+ std::pair<iterator,iterator> p = this->equal_range(key);
size_type n;
this->private_erase(p.first, p.second, n, disposer);
return n;
@@ -1456,12 +1462,10 @@ class bstree_impl
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
- /// @endcond
- )
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ BOOST_INTRUSIVE_DOC1ST(size_type
+ , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
+ erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer)
{
std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n;
@@ -1512,9 +1516,9 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
//! to number of objects with the given value.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- size_type count(const_reference value) const
- { return size_type(this->count(value, this->comp())); }
+ //! <b>Throws</b>: If `key_compare` throws.
+ size_type count(const key_type &key) const
+ { return size_type(this->count(key, this->key_comp())); }
//! <b>Effects</b>: Returns the number of contained elements with the given key
//!
@@ -1522,8 +1526,8 @@ class bstree_impl
//! to number of objects with the given key.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType &key, KeyValueCompare comp) const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType &key, KeyTypeKeyCompare comp) const
{
std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
size_type n = 0;
@@ -1535,11 +1539,11 @@ class bstree_impl
//Add non-const overloads to theoretically const members
//as some algorithms have different behavior when non-const versions are used (like splay trees).
- size_type count(const_reference value)
- { return size_type(this->count(value, this->comp())); }
+ size_type count(const key_type &key)
+ { return size_type(this->count(key, this->key_comp())); }
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType &key, KeyValueCompare comp)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType &key, KeyTypeKeyCompare comp)
{
std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
size_type n = 0;
@@ -1554,16 +1558,16 @@ class bstree_impl
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- iterator lower_bound(const_reference value);
+ //! <b>Throws</b>: If `key_compare` throws.
+ iterator lower_bound(const key_type &key);
//! <b>Effects</b>: Returns an iterator to the first element whose
//! key is not less than k or end() if that element does not exist.
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- const_iterator lower_bound(const_reference value) const;
+ //! <b>Throws</b>: If `key_compare` throws.
+ const_iterator lower_bound(const key_type &key) const;
//! <b>Effects</b>: Returns an iterator to the first element whose
//! key is not less than k or end() if that element does not exist.
@@ -1571,8 +1575,8 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp);
//! <b>Effects</b>: Returns a const iterator to the first element whose
//! key is not less than k or end() if that element does not exist.
@@ -1580,16 +1584,16 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
//! <b>Effects</b>: Returns an iterator to the first element whose
//! key is greater than k or end() if that element does not exist.
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- iterator upper_bound(const_reference value);
+ //! <b>Throws</b>: If `key_compare` throws.
+ iterator upper_bound(const key_type &key);
//! <b>Effects</b>: Returns an iterator to the first element whose
//! key is greater than k according to comp or end() if that element
@@ -1598,16 +1602,16 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp);
//! <b>Effects</b>: Returns an iterator to the first element whose
//! key is greater than k or end() if that element does not exist.
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- const_iterator upper_bound(const_reference value) const;
+ //! <b>Throws</b>: If `key_compare` throws.
+ const_iterator upper_bound(const key_type &key) const;
//! <b>Effects</b>: Returns an iterator to the first element whose
//! key is greater than k according to comp or end() if that element
@@ -1616,16 +1620,16 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
//! <b>Effects</b>: Finds an iterator to the first element whose key is
//! k or end() if that element does not exist.
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- iterator find(const_reference value);
+ //! <b>Throws</b>: If `key_compare` throws.
+ iterator find(const key_type &key);
//! <b>Effects</b>: Finds an iterator to the first element whose key is
//! k or end() if that element does not exist.
@@ -1633,16 +1637,16 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType &key, KeyTypeKeyCompare comp);
//! <b>Effects</b>: Finds a const_iterator to the first element whose key is
//! k or end() if that element does not exist.
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- const_iterator find(const_reference value) const;
+ //! <b>Throws</b>: If `key_compare` throws.
+ const_iterator find(const key_type &key) const;
//! <b>Effects</b>: Finds a const_iterator to the first element whose key is
//! k or end() if that element does not exist.
@@ -1650,8 +1654,8 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType &key, KeyTypeKeyCompare comp) const;
//! <b>Effects</b>: Finds a range containing all elements whose key is k or
//! an empty range that indicates the position where those elements would be
@@ -1659,8 +1663,8 @@ class bstree_impl
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! <b>Throws</b>: If `key_compare` throws.
+ std::pair<iterator,iterator> equal_range(const key_type &key);
//! <b>Effects</b>: Finds a range containing all elements whose key is k or
//! an empty range that indicates the position where those elements would be
@@ -1669,8 +1673,8 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp);
//! <b>Effects</b>: Finds a range containing all elements whose key is k or
//! an empty range that indicates the position where those elements would be
@@ -1678,9 +1682,9 @@ class bstree_impl
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
+ //! <b>Throws</b>: If `key_compare` throws.
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
//! <b>Effects</b>: Finds a range containing all elements whose key is k or
//! an empty range that indicates the position where those elements would be
@@ -1689,12 +1693,12 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType &key, KeyValueCompare comp) const;
+ equal_range(const KeyType &key, KeyTypeKeyCompare comp) const;
- //! <b>Requires</b>: 'lower_value' must not be greater than 'upper_value'. If
- //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false.
+ //! <b>Requires</b>: 'lower_key' must not be greater than 'upper_key'. If
+ //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false.
//!
//! <b>Effects</b>: Returns an a pair with the following criteria:
//!
@@ -1704,16 +1708,16 @@ class bstree_impl
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
+ //! <b>Throws</b>: If `key_compare` throws.
//!
//! <b>Note</b>: This function can be more efficient than calling upper_bound
//! and lower_bound for lower_value and upper_value.
//!
//! <b>Note</b>: Experimental function, the interface might change in future releases.
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_value, bool left_closed, bool right_closed);
- //! <b>Requires</b>: KeyValueCompare is a function object that induces a strict weak
+ //! <b>Requires</b>: KeyTypeKeyCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
//! the container.
//! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If
@@ -1733,12 +1737,12 @@ class bstree_impl
//! and lower_bound for lower_key and upper_key.
//!
//! <b>Note</b>: Experimental function, the interface might change in future releases.
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! <b>Requires</b>: 'lower_value' must not be greater than 'upper_value'. If
- //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false.
+ //! <b>Requires</b>: 'lower_key' must not be greater than 'upper_key'. If
+ //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false.
//!
//! <b>Effects</b>: Returns an a pair with the following criteria:
//!
@@ -1748,16 +1752,16 @@ class bstree_impl
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
+ //! <b>Throws</b>: If `key_compare` throws.
//!
//! <b>Note</b>: This function can be more efficient than calling upper_bound
//! and lower_bound for lower_value and upper_value.
//!
//! <b>Note</b>: Experimental function, the interface might change in future releases.
std::pair<const_iterator,const_iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! <b>Requires</b>: KeyValueCompare is a function object that induces a strict weak
+ //! <b>Requires</b>: KeyTypeKeyCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
//! the container.
//! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If
@@ -1777,9 +1781,9 @@ class bstree_impl
//! and lower_bound for lower_key and upper_key.
//!
//! <b>Note</b>: Experimental function, the interface might change in future releases.
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator,const_iterator> bounded_range
- (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! <b>Requires</b>: value must be an lvalue and shall be in a set of
//! appropriate type. Otherwise the behavior is undefined.
@@ -1936,8 +1940,8 @@ class bstree_impl
template <class ExtraChecker>
void check(ExtraChecker extra_checker) const
{
- typedef detail::key_nodeptr_comp<value_compare, value_traits> nodeptr_comp_t;
- nodeptr_comp_t nodeptr_comp(this->comp(), &this->get_value_traits());
+ typedef detail::key_nodeptr_comp<key_compare, value_traits, key_of_value> nodeptr_comp_t;
+ nodeptr_comp_t nodeptr_comp(this->key_comp(), &this->get_value_traits());
typedef typename get_node_checker<AlgoType, ValueTraits, nodeptr_comp_t, ExtraChecker>::type node_checker_t;
typename node_checker_t::return_type checker_return;
node_algorithms::check(this->header_ptr(), node_checker_t(nodeptr_comp, extra_checker), checker_return);
@@ -1956,6 +1960,32 @@ class bstree_impl
check(detail::empty_node_checker<ValueTraits>());
}
+ friend bool operator==(const bstree_impl &x, const bstree_impl &y)
+ {
+ if(constant_time_size && x.size() != y.size()){
+ return false;
+ }
+ return boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
+ }
+
+ friend bool operator!=(const bstree_impl &x, const bstree_impl &y)
+ { return !(x == y); }
+
+ friend bool operator<(const bstree_impl &x, const bstree_impl &y)
+ { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+
+ friend bool operator>(const bstree_impl &x, const bstree_impl &y)
+ { return y < x; }
+
+ friend bool operator<=(const bstree_impl &x, const bstree_impl &y)
+ { return !(x > y); }
+
+ friend bool operator>=(const bstree_impl &x, const bstree_impl &y)
+ { return !(x < y); }
+
+ friend void swap(bstree_impl &x, bstree_impl &y)
+ { x.swap(y); }
+
/// @cond
private:
template<class Disposer>
@@ -1975,111 +2005,6 @@ class bstree_impl
/// @endcond
};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
-#endif
-inline bool operator<
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
-#else
-( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
-, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
-#endif
-{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
-#endif
-bool operator==
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
-#else
-( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
-, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
-#endif
-{
- typedef bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> tree_type;
-
- if(tree_type::constant_time_size && x.size() != y.size()){
- return false;
- }
- return boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
-}
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
-#endif
-inline bool operator!=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
-#else
-( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
-, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
-#endif
-{ return !(x == y); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
-#endif
-inline bool operator>
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
-#else
-( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
-, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
-#endif
-{ return y < x; }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
-#endif
-inline bool operator<=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
-#else
-( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
-, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
-#endif
-{ return !(y < x); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
-#endif
-inline bool operator>=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
-#else
-( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
-, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
-#endif
-{ return !(x < y); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
-#endif
-inline void swap
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(bstree_impl<T, Options...> &x, bstree_impl<T, Options...> &y)
-#else
-( bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
-, bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
-#endif
-{ x.swap(y); }
-
//! Helper metafunction to define a \c bstree that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
@@ -2087,7 +2012,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_bstree
{
@@ -2095,7 +2020,7 @@ struct make_bstree
typedef typename pack_options
< bstree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -2106,6 +2031,7 @@ struct make_bstree
typedef bstree_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -2120,14 +2046,14 @@ struct make_bstree
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class bstree
: public make_bstree<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -2136,7 +2062,7 @@ class bstree
typedef typename make_bstree
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -2144,7 +2070,7 @@ class bstree
BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -2152,14 +2078,14 @@ class bstree
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- bstree( const value_compare &cmp = value_compare()
+ bstree( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
bstree( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, v_traits)
{}
@@ -2171,6 +2097,14 @@ class bstree
bstree& operator=(BOOST_RV_REF(bstree) x)
{ return static_cast<bstree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const bstree &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(bstree) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static bstree &container_from_end_iterator(iterator end_iterator)
{ return static_cast<bstree &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/bstree_algorithms.hpp b/boost/intrusive/bstree_algorithms.hpp
index f7e915e914..dcb7e5c4ff 100644
--- a/boost/intrusive/bstree_algorithms.hpp
+++ b/boost/intrusive/bstree_algorithms.hpp
@@ -37,10 +37,6 @@ namespace intrusive {
template <class NodePtr>
struct insert_commit_data_t
{
- insert_commit_data_t()
- : link_left(false)
- , node()
- {}
bool link_left;
NodePtr node;
};
diff --git a/boost/intrusive/detail/common_slist_algorithms.hpp b/boost/intrusive/detail/common_slist_algorithms.hpp
index deaea7c97b..c6fa289a23 100644
--- a/boost/intrusive/detail/common_slist_algorithms.hpp
+++ b/boost/intrusive/detail/common_slist_algorithms.hpp
@@ -46,7 +46,7 @@ class common_slist_algorithms
; this_node != (p_next = NodeTraits::get_next(p))
; p = p_next){
//Logic error: possible use of linear lists with
- //operations only permitted with lists
+ //operations only permitted with circular lists
BOOST_INTRUSIVE_INVARIANT_ASSERT(p);
}
return p;
diff --git a/boost/intrusive/detail/default_header_holder.hpp b/boost/intrusive/detail/default_header_holder.hpp
index d10109b8c9..5f9cd9a444 100644
--- a/boost/intrusive/detail/default_header_holder.hpp
+++ b/boost/intrusive/detail/default_header_holder.hpp
@@ -51,15 +51,15 @@ struct default_header_holder : public NodeTraits::node
};
// type function producing the header node holder
-template < typename Value_Traits, typename HeaderHolder >
+template < typename ValueTraits, typename HeaderHolder >
struct get_header_holder_type
{
typedef HeaderHolder type;
};
-template < typename Value_Traits >
-struct get_header_holder_type< Value_Traits, void >
+template < typename ValueTraits >
+struct get_header_holder_type< ValueTraits, void >
{
- typedef default_header_holder< typename Value_Traits::node_traits > type;
+ typedef default_header_holder< typename ValueTraits::node_traits > type;
};
} //namespace detail
diff --git a/boost/intrusive/detail/ebo_functor_holder.hpp b/boost/intrusive/detail/ebo_functor_holder.hpp
index e8e73ff62a..27dd093b60 100644
--- a/boost/intrusive/detail/ebo_functor_holder.hpp
+++ b/boost/intrusive/detail/ebo_functor_holder.hpp
@@ -203,6 +203,7 @@ class ebo_functor_holder
typedef ebo_functor_holder_impl<T, is_unary_or_binary_function<T>::value> super;
public:
+ typedef T functor_type;
ebo_functor_holder(){}
explicit ebo_functor_holder(const T& t)
: super(t)
diff --git a/boost/intrusive/detail/get_value_traits.hpp b/boost/intrusive/detail/get_value_traits.hpp
index 686e059583..222f8078a6 100644
--- a/boost/intrusive/detail/get_value_traits.hpp
+++ b/boost/intrusive/detail/get_value_traits.hpp
@@ -107,9 +107,9 @@ BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, hooktags::is_ba
template <class T>
struct internal_member_value_traits
{
- template <class U> static one test(...);
- template <class U> static two test(typename U::member_value_traits* = 0);
- static const bool value = sizeof(test<T>(0)) == sizeof(two);
+ template <class U> static yes_type test(...);
+ template <class U> static no_type test(typename U::member_value_traits* = 0);
+ static const bool value = sizeof(test<T>(0)) == sizeof(no_type);
};
template<class SupposedValueTraits, class T, bool = is_default_hook_tag<SupposedValueTraits>::value>
diff --git a/boost/intrusive/detail/hashtable_node.hpp b/boost/intrusive/detail/hashtable_node.hpp
index 923a3e1d38..352be28cbe 100644
--- a/boost/intrusive/detail/hashtable_node.hpp
+++ b/boost/intrusive/detail/hashtable_node.hpp
@@ -113,9 +113,9 @@ struct bucket_traits_impl
template <class NodeTraits>
struct hash_reduced_slist_node_traits
{
- template <class U> static detail::one test(...);
- template <class U> static detail::two test(typename U::reduced_slist_node_traits* = 0);
- static const bool value = sizeof(test<NodeTraits>(0)) == sizeof(detail::two);
+ template <class U> static detail::no_type test(...);
+ template <class U> static detail::yes_type test(typename U::reduced_slist_node_traits*);
+ static const bool value = sizeof(test<NodeTraits>(0)) == sizeof(detail::yes_type);
};
template <class NodeTraits>
@@ -154,52 +154,48 @@ struct get_slist_impl
template<class BucketValueTraits, bool IsConst>
class hashtable_iterator
{
- typedef boost::intrusive::iterator
- < std::forward_iterator_tag
- , typename BucketValueTraits::value_traits::value_type
- , typename pointer_traits<typename BucketValueTraits::value_traits::value_type*>::difference_type
- , typename detail::add_const_if_c
- <typename BucketValueTraits::value_traits::value_type, IsConst>::type *
- , typename detail::add_const_if_c
- <typename BucketValueTraits::value_traits::value_type, IsConst>::type &
- > iterator_traits;
-
- typedef typename BucketValueTraits::value_traits value_traits;
- typedef typename BucketValueTraits::bucket_traits bucket_traits;
- typedef typename value_traits::node_traits node_traits;
+ typedef typename BucketValueTraits::value_traits value_traits;
+ typedef typename BucketValueTraits::bucket_traits bucket_traits;
+
+ typedef iiterator< value_traits, IsConst
+ , std::forward_iterator_tag> types_t;
+ public:
+ typedef typename types_t::iterator_traits::difference_type difference_type;
+ typedef typename types_t::iterator_traits::value_type value_type;
+ typedef typename types_t::iterator_traits::pointer pointer;
+ typedef typename types_t::iterator_traits::reference reference;
+ typedef typename types_t::iterator_traits::iterator_category iterator_category;
+
+ private:
+ typedef typename value_traits::node_traits node_traits;
+ typedef typename node_traits::node_ptr node_ptr;
typedef typename detail::get_slist_impl
- <typename detail::reduced_slist_node_traits
- <typename value_traits::node_traits>::type
- >::type slist_impl;
- typedef typename slist_impl::iterator siterator;
- typedef typename slist_impl::const_iterator const_siterator;
- typedef detail::bucket_impl<slist_impl> bucket_type;
+ < typename detail::reduced_slist_node_traits
+ <node_traits>::type >::type slist_impl;
+ typedef typename slist_impl::iterator siterator;
+ typedef typename slist_impl::const_iterator const_siterator;
+ typedef detail::bucket_impl<slist_impl> bucket_type;
typedef typename pointer_traits
- <typename value_traits::pointer>::template rebind_pointer
- < const BucketValueTraits >::type const_bucketvaltraits_ptr;
- typedef typename slist_impl::size_type size_type;
-
+ <pointer>::template rebind_pointer
+ < const BucketValueTraits >::type const_bucketvaltraits_ptr;
+ typedef typename slist_impl::size_type size_type;
- static typename node_traits::node_ptr downcast_bucket(typename bucket_type::node_ptr p)
+ static node_ptr downcast_bucket(typename bucket_type::node_ptr p)
{
- return pointer_traits<typename node_traits::node_ptr>::
+ return pointer_traits<node_ptr>::
pointer_to(static_cast<typename node_traits::node&>(*p));
}
public:
- typedef typename iterator_traits::difference_type difference_type;
- typedef typename iterator_traits::value_type value_type;
- typedef typename iterator_traits::pointer pointer;
- typedef typename iterator_traits::reference reference;
- typedef typename iterator_traits::iterator_category iterator_category;
hashtable_iterator ()
: slist_it_() //Value initialization to achieve "null iterators" (N3644)
{}
explicit hashtable_iterator(siterator ptr, const BucketValueTraits *cont)
- : slist_it_ (ptr), traitsptr_ (cont ? pointer_traits<const_bucketvaltraits_ptr>::pointer_to(*cont) : const_bucketvaltraits_ptr() )
+ : slist_it_ (ptr)
+ , traitsptr_ (cont ? pointer_traits<const_bucketvaltraits_ptr>::pointer_to(*cont) : const_bucketvaltraits_ptr() )
{}
hashtable_iterator(const hashtable_iterator<BucketValueTraits, false> &other)
@@ -212,7 +208,6 @@ class hashtable_iterator
hashtable_iterator<BucketValueTraits, false> unconst() const
{ return hashtable_iterator<BucketValueTraits, false>(this->slist_it(), this->get_bucket_value_traits()); }
- public:
hashtable_iterator& operator++()
{ this->increment(); return *this; }
@@ -234,8 +229,8 @@ class hashtable_iterator
pointer operator->() const
{
- return boost::intrusive::detail::to_raw_pointer(this->priv_value_traits().to_value_ptr
- (downcast_bucket(slist_it_.pointed_node())));
+ return this->priv_value_traits().to_value_ptr
+ (downcast_bucket(slist_it_.pointed_node()));
}
const const_bucketvaltraits_ptr &get_bucket_value_traits() const
diff --git a/boost/intrusive/detail/is_stateful_value_traits.hpp b/boost/intrusive/detail/is_stateful_value_traits.hpp
index 680b043aa8..e43f6d340a 100644
--- a/boost/intrusive/detail/is_stateful_value_traits.hpp
+++ b/boost/intrusive/detail/is_stateful_value_traits.hpp
@@ -32,7 +32,7 @@ namespace detail {
template<class ValueTraits>
struct is_stateful_value_traits
{
- static const bool value = !detail::is_empty_class<ValueTraits>::value;
+ static const bool value = !detail::is_empty<ValueTraits>::value;
};
}}}
diff --git a/boost/intrusive/detail/iterator.hpp b/boost/intrusive/detail/iterator.hpp
index fb6fb81976..9f0fe606f4 100644
--- a/boost/intrusive/detail/iterator.hpp
+++ b/boost/intrusive/detail/iterator.hpp
@@ -141,6 +141,14 @@ typename iterator_enable_if_tag_difference_type
return off;
}
+template<class I>
+typename iterator_traits<I>::pointer iterator_arrow_result(const I &i)
+{ return i.operator->(); }
+
+template<class T>
+T * iterator_arrow_result(T *p)
+{ return p; }
+
} //namespace intrusive
} //namespace boost
diff --git a/boost/intrusive/detail/key_nodeptr_comp.hpp b/boost/intrusive/detail/key_nodeptr_comp.hpp
index 8c456634e5..df2b895db9 100644
--- a/boost/intrusive/detail/key_nodeptr_comp.hpp
+++ b/boost/intrusive/detail/key_nodeptr_comp.hpp
@@ -28,18 +28,27 @@ namespace boost {
namespace intrusive {
namespace detail {
-template<class KeyValueCompare, class ValueTraits>
+template < class KeyTypeKeyCompare
+ , class ValueTraits
+ , class KeyOfValue = void
+ >
struct key_nodeptr_comp
//Use public inheritance to avoid MSVC bugs with closures
- : public ebo_functor_holder<KeyValueCompare>
+ : public ebo_functor_holder<KeyTypeKeyCompare>
{
typedef ValueTraits value_traits;
typedef typename value_traits::value_type value_type;
typedef typename value_traits::node_ptr node_ptr;
typedef typename value_traits::const_node_ptr const_node_ptr;
- typedef ebo_functor_holder<KeyValueCompare> base_t;
-
- key_nodeptr_comp(KeyValueCompare kcomp, const ValueTraits *traits)
+ typedef ebo_functor_holder<KeyTypeKeyCompare> base_t;
+ typedef typename detail::if_c
+ < detail::is_same<KeyOfValue, void>::value
+ , detail::identity<value_type>
+ , KeyOfValue
+ >::type key_of_value;
+ typedef typename key_of_value::type key_type;
+
+ key_nodeptr_comp(KeyTypeKeyCompare kcomp, const ValueTraits *traits)
: base_t(kcomp), traits_(traits)
{}
@@ -51,12 +60,13 @@ struct key_nodeptr_comp
//key_forward
template<class T>
- const value_type & key_forward
- (const T &node, typename enable_if_c<is_node_ptr<T>::value>::type * = 0) const
- { return *traits_->to_value_ptr(node); }
+ typename enable_if<is_node_ptr<T>, const key_type &>::type
+ key_forward(const T &node) const
+ { return key_of_value()(*traits_->to_value_ptr(node)); }
template<class T>
- const T & key_forward(const T &key, typename enable_if_c<!is_node_ptr<T>::value>::type* = 0) const
+ typename disable_if<is_node_ptr<T>, const T &>::type
+ const key_forward(const T &key) const
{ return key; }
//operator() 1 arg
diff --git a/boost/intrusive/detail/list_iterator.hpp b/boost/intrusive/detail/list_iterator.hpp
index 77c9fa6097..6af4841c3e 100644
--- a/boost/intrusive/detail/list_iterator.hpp
+++ b/boost/intrusive/detail/list_iterator.hpp
@@ -34,7 +34,7 @@ namespace intrusive {
template<class ValueTraits, bool IsConst>
class list_iterator
{
- protected:
+ private:
typedef iiterator
<ValueTraits, IsConst, std::bidirectional_iterator_tag> types_t;
diff --git a/boost/intrusive/detail/math.hpp b/boost/intrusive/detail/math.hpp
index 03000fceeb..dfebe2ab42 100644
--- a/boost/intrusive/detail/math.hpp
+++ b/boost/intrusive/detail/math.hpp
@@ -127,7 +127,7 @@ namespace detail {
{ return (n >> 1) + ((n & 1u) & (n != 1)); }
template<std::size_t N>
- inline std::size_t floor_log2 (std::size_t x, integer<std::size_t, N>)
+ inline std::size_t floor_log2 (std::size_t x, integral_constant<std::size_t, N>)
{
const std::size_t Bits = N;
const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
@@ -156,7 +156,7 @@ namespace detail {
//http://stackoverflow.com/questions/11376288/fast-computing-of-log2-for-64-bit-integers
//Thanks to Desmond Hume
- inline std::size_t floor_log2 (std::size_t v, integer<std::size_t, 32>)
+ inline std::size_t floor_log2 (std::size_t v, integral_constant<std::size_t, 32>)
{
static const int MultiplyDeBruijnBitPosition[32] =
{
@@ -173,7 +173,7 @@ namespace detail {
return MultiplyDeBruijnBitPosition[(std::size_t)(v * 0x07C4ACDDU) >> 27];
}
- inline std::size_t floor_log2 (std::size_t v, integer<std::size_t, 64>)
+ inline std::size_t floor_log2 (std::size_t v, integral_constant<std::size_t, 64>)
{
static const std::size_t MultiplyDeBruijnBitPosition[64] = {
63, 0, 58, 1, 59, 47, 53, 2,
@@ -198,7 +198,7 @@ namespace detail {
inline std::size_t floor_log2 (std::size_t x)
{
const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
- return floor_log2(x, integer<std::size_t, Bits>());
+ return floor_log2(x, integral_constant<std::size_t, Bits>());
}
#endif
diff --git a/boost/intrusive/detail/mpl.hpp b/boost/intrusive/detail/mpl.hpp
index 39d2c58bd3..8d227a16fd 100644
--- a/boost/intrusive/detail/mpl.hpp
+++ b/boost/intrusive/detail/mpl.hpp
@@ -23,260 +23,48 @@
#endif
#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/move/detail/type_traits.hpp>
#include <cstddef>
namespace boost {
namespace intrusive {
namespace detail {
-
-template <typename T, typename U>
-struct is_same
-{
- static const bool value = false;
-};
-
-template <typename T>
-struct is_same<T, T>
-{
- static const bool value = true;
-};
-
-template<typename T>
-struct add_const
-{ typedef const T type; };
-
-template<typename T>
-struct remove_const
-{ typedef T type; };
-
-template<typename T>
-struct remove_const<const T>
-{ typedef T type; };
-
-template<typename T>
-struct remove_cv
-{ typedef T type; };
-
-template<typename T>
-struct remove_cv<const T>
-{ typedef T type; };
-
-template<typename T>
-struct remove_cv<const volatile T>
-{ typedef T type; };
-
-template<typename T>
-struct remove_cv<volatile T>
-{ typedef T type; };
-
-template<class T>
-struct remove_reference
-{
- typedef T type;
-};
-
-template<class T>
-struct remove_reference<T&>
-{
- typedef T type;
-};
-
-template<class T>
-struct remove_pointer
-{
- typedef T type;
-};
-
-template<class T>
-struct remove_pointer<T*>
-{
- typedef T type;
-};
-
-template<class T>
-struct add_pointer
-{
- typedef T *type;
-};
-
-typedef char one;
-struct two {one _[2];};
-
-template< bool C_ >
-struct bool_
-{
- static const bool value = C_;
-};
-
-template< class Integer, Integer Value >
-struct integer
-{
- static const Integer value = Value;
-};
-
-typedef bool_<true> true_;
-typedef bool_<false> false_;
-
-typedef true_ true_type;
-typedef false_ false_type;
-
-typedef char yes_type;
-struct no_type
-{
- char padding[8];
-};
-
-template <bool B, class T = void>
-struct enable_if_c {
- typedef T type;
-};
-
-template <class T>
-struct enable_if_c<false, T> {};
-
-template <class Cond, class T = void>
-struct enable_if : public enable_if_c<Cond::value, T>{};
-
-template<class F, class Param>
-struct apply
-{
- typedef typename F::template apply<Param>::type type;
-};
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
-
-template <class T, class U>
-struct is_convertible
-{
- static const bool value = __is_convertible_to(T, U);
-};
-
-#else
-
-template <class T, class U>
-class is_convertible
-{
- typedef char true_t;
- class false_t { char dummy[2]; };
- //use any_conversion as first parameter since in MSVC
- //overaligned types can't go through ellipsis
- static false_t dispatch(...);
- static true_t dispatch(U);
- static typename remove_reference<T>::type &trigger();
- public:
- static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
-};
-
-#endif
-
-template<
- bool C
- , typename T1
- , typename T2
- >
-struct if_c
-{
- typedef T1 type;
-};
-
-template<
- typename T1
- , typename T2
- >
-struct if_c<false,T1,T2>
-{
- typedef T2 type;
-};
-
-template<
- typename C
- , typename T1
- , typename T2
- >
-struct if_
-{
- typedef typename if_c<0 != C::value, T1, T2>::type type;
-};
-
-template<
- bool C
- , typename F1
- , typename F2
- >
-struct eval_if_c
- : if_c<C,F1,F2>::type
-{};
-
-template<
- typename C
- , typename T1
- , typename T2
- >
-struct eval_if
- : if_<C,T1,T2>::type
-{};
-
-// identity is an extension: it is not part of the standard.
-template <class T>
-struct identity
-{
- typedef T type;
-};
-
-template<class T, bool Add>
-struct add_const_if_c
-{
- typedef typename if_c
- < Add
- , typename add_const<T>::type
- , T
- >::type type;
-};
-
-
-//boost::alignment_of yields to 10K lines of preprocessed code, so we
-//need an alternative
-template <typename T> struct alignment_of;
-
-template <typename T>
-struct alignment_of_hack
-{
- char c;
- T t;
- alignment_of_hack();
-};
-
-template <unsigned A, unsigned S>
-struct alignment_logic
-{
- static const std::size_t value = A < S ? A : S;
-};
-
-template< typename T >
-struct alignment_of
-{
- static const std::size_t value = alignment_logic
- < sizeof(alignment_of_hack<T>) - sizeof(T)
- , sizeof(T)
- >::value;
-};
-
-template<class Class>
-class is_empty_class
-{
- template <typename T>
- struct empty_helper_t1 : public T
- {
- empty_helper_t1();
- int i[256];
- };
-
- struct empty_helper_t2
- { int i[256]; };
-
- public:
- static const bool value = sizeof(empty_helper_t1<Class>) == sizeof(empty_helper_t2);
-};
+
+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<std::size_t S>
struct ls_zeros
@@ -296,10 +84,6 @@ struct ls_zeros<1>
static const std::size_t value = 0;
};
-template <typename T> struct unvoid_ref { typedef T &type; };
-template <> struct unvoid_ref<void> { struct type_impl { }; typedef type_impl & type; };
-template <> struct unvoid_ref<const void> { struct type_impl { }; typedef type_impl & type; };
-
// Infrastructure for providing a default type for T::TNAME if absent.
#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \
template <typename T, typename DefaultType> \
@@ -360,8 +144,8 @@ template <class T>\
struct TRAITS_PREFIX##_bool\
{\
template<bool Add>\
- struct two_or_three {one _[2 + Add];};\
- template <class U> static one test(...);\
+ struct two_or_three {yes_type _[2 + Add];};\
+ template <class U> static yes_type test(...);\
template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\
static const std::size_t value = sizeof(test<T>(0));\
};\
@@ -369,7 +153,7 @@ struct TRAITS_PREFIX##_bool\
template <class T>\
struct TRAITS_PREFIX##_bool_is_true\
{\
- static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(one)*2;\
+ static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(yes_type)*2;\
};\
//
@@ -380,10 +164,10 @@ struct TRAITS_PREFIX##_bool_is_true\
private: \
template<Signature> struct helper;\
template<typename T> \
- static ::boost::intrusive::detail::yes_type check(helper<&T::FUNC_NAME>*); \
- template<typename T> static ::boost::intrusive::detail::no_type check(...); \
+ static ::boost::intrusive::detail::yes_type test(helper<&T::FUNC_NAME>*); \
+ template<typename T> static ::boost::intrusive::detail::no_type test(...); \
public: \
- static const bool value = sizeof(check<U>(0)) == sizeof(::boost::intrusive::detail::yes_type); \
+ static const bool value = sizeof(test<U>(0)) == sizeof(::boost::intrusive::detail::yes_type); \
}; \
//
@@ -398,9 +182,9 @@ struct TRAITS_NAME \
struct Base : public Type, public BaseMixin { Base(); }; \
template <typename T, T t> class Helper{}; \
template <typename U> \
- static ::boost::intrusive::detail::no_type check(U*, Helper<void (BaseMixin::*)(), &U::FUNC_NAME>* = 0); \
- static ::boost::intrusive::detail::yes_type check(...); \
- static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(check((Base*)(0))); \
+ static ::boost::intrusive::detail::no_type test(U*, Helper<void (BaseMixin::*)(), &U::FUNC_NAME>* = 0); \
+ static ::boost::intrusive::detail::yes_type test(...); \
+ static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(test((Base*)(0))); \
};\
//
@@ -413,18 +197,6 @@ struct TRAITS_NAME \
{};\
//
-
-template <typename T>
-inline T* addressof(T& obj)
-{
- return static_cast<T*>
- (static_cast<void*>
- (const_cast<char*>
- (&reinterpret_cast<const char&>(obj))
- )
- );
-}
-
} //namespace detail
} //namespace intrusive
} //namespace boost
diff --git a/boost/intrusive/detail/node_cloner_disposer.hpp b/boost/intrusive/detail/node_cloner_disposer.hpp
index 65af3e37b8..3fe2954347 100644
--- a/boost/intrusive/detail/node_cloner_disposer.hpp
+++ b/boost/intrusive/detail/node_cloner_disposer.hpp
@@ -36,21 +36,22 @@ struct node_cloner
//Use public inheritance to avoid MSVC bugs with closures
: public ebo_functor_holder<F>
{
- typedef ValueTraits value_traits;
- typedef typename value_traits::node_traits node_traits;
- typedef typename node_traits::node_ptr node_ptr;
- typedef ebo_functor_holder<F> base_t;
+ typedef ValueTraits value_traits;
+ typedef typename value_traits::node_traits node_traits;
+ typedef typename node_traits::node_ptr node_ptr;
+ typedef ebo_functor_holder<F> base_t;
typedef typename get_algo< AlgoType
- , node_traits>::type node_algorithms;
+ , node_traits>::type node_algorithms;
static const bool safemode_or_autounlink =
is_safe_autounlink<value_traits::link_mode>::value;
- typedef typename value_traits::value_type value_type;
- typedef typename value_traits::pointer pointer;
- typedef typename node_traits::node node;
- typedef typename value_traits::const_node_ptr const_node_ptr;
- typedef typename value_traits::reference reference;
- typedef typename value_traits::const_reference const_reference;
-
+ typedef typename value_traits::value_type value_type;
+ typedef typename value_traits::pointer pointer;
+ typedef typename value_traits::const_pointer const_pointer;
+ typedef typename node_traits::node node;
+ typedef typename value_traits::const_node_ptr const_node_ptr;
+ typedef typename pointer_traits<pointer>::reference reference;
+ typedef typename pointer_traits
+ <const_pointer>::reference const_reference;
typedef typename if_c<IsConst, const_reference, reference>::type reference_type;
node_cloner(F f, const ValueTraits *traits)
@@ -63,21 +64,7 @@ struct node_cloner
reference_type v = *traits_->to_value_ptr(p);
node_ptr n = traits_->to_node_ptr(*base_t::get()(v));
//Cloned node must be in default mode if the linking mode requires it
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
- return n;
- }
-
- // hashtables use this method, which is proxy-reference unfriendly
- node_ptr operator()(const node &to_clone)
- {
- reference_type v =
- *traits_->to_value_ptr
- (pointer_traits<const_node_ptr>::pointer_to(to_clone));
- node_ptr n = traits_->to_node_ptr(*base_t::get()(v));
- //Cloned node must be in default mode if the linking mode requires it
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(n));
return n;
}
diff --git a/boost/intrusive/detail/reverse_iterator.hpp b/boost/intrusive/detail/reverse_iterator.hpp
index 6a6fee5ac2..552e8f4d71 100644
--- a/boost/intrusive/detail/reverse_iterator.hpp
+++ b/boost/intrusive/detail/reverse_iterator.hpp
@@ -23,6 +23,7 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/iterator.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
namespace boost {
namespace intrusive {
@@ -49,10 +50,17 @@ class reverse_iterator
{}
template<class OtherIt>
- reverse_iterator(const reverse_iterator<OtherIt>& r)
+ reverse_iterator( const reverse_iterator<OtherIt>& r
+ , typename boost::intrusive::detail::enable_if_convertible<OtherIt, It>::type* =0
+ )
: m_current(r.base())
{}
+ template<class OtherIt>
+ typename boost::intrusive::detail::enable_if_convertible<OtherIt, It, reverse_iterator &>::type
+ operator=( const reverse_iterator<OtherIt>& r)
+ { m_current = r.base(); return *this; }
+
It base() const
{ return m_current; }
@@ -60,10 +68,10 @@ class reverse_iterator
{ It temp(m_current); --temp; return *temp; }
pointer operator->() const
- { It temp(m_current); --temp; return temp.operator->(); }
+ { It temp(m_current); --temp; return iterator_arrow_result(temp); }
reference operator[](difference_type off) const
- { return this->m_current[-off-1]; }
+ { return this->m_current[-off - 1]; }
reverse_iterator& operator++()
{ --m_current; return *this; }
@@ -109,22 +117,17 @@ class reverse_iterator
reverse_iterator& operator+=(difference_type off)
{ m_current -= off; return *this; }
- friend reverse_iterator operator+(const reverse_iterator & l, difference_type off)
- {
- reverse_iterator tmp(l.m_current);
- tmp.m_current -= off;
- return tmp;
- }
+ friend reverse_iterator operator+(reverse_iterator l, difference_type off)
+ { l.m_current -= off; return l; }
+
+ friend reverse_iterator operator+(difference_type off, reverse_iterator r)
+ { return (r += off); }
reverse_iterator& operator-=(difference_type off)
{ m_current += off; return *this; }
- friend reverse_iterator operator-(const reverse_iterator & l, difference_type off)
- {
- reverse_iterator tmp(l.m_current);
- tmp.m_current += off;
- return tmp;
- }
+ friend reverse_iterator operator-(reverse_iterator l, difference_type off)
+ { l.m_current += off; return l; }
friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r)
{ return r.m_current - l.m_current; }
diff --git a/boost/intrusive/detail/slist_iterator.hpp b/boost/intrusive/detail/slist_iterator.hpp
index 80a6fef924..1699064ec1 100644
--- a/boost/intrusive/detail/slist_iterator.hpp
+++ b/boost/intrusive/detail/slist_iterator.hpp
@@ -36,7 +36,7 @@ namespace intrusive {
template<class ValueTraits, bool IsConst>
class slist_iterator
{
- protected:
+ private:
typedef iiterator
<ValueTraits, IsConst, std::forward_iterator_tag> types_t;
diff --git a/boost/intrusive/detail/std_fwd.hpp b/boost/intrusive/detail/std_fwd.hpp
index 0492c1dc3d..4b5cedbae3 100644
--- a/boost/intrusive/detail/std_fwd.hpp
+++ b/boost/intrusive/detail/std_fwd.hpp
@@ -23,10 +23,12 @@
// Standard predeclarations
//////////////////////////////////////////////////////////////////////////////
-#if defined(__clang__) && defined(_LIBCPP_VERSION)
+#if defined(_LIBCPP_VERSION)
#define BOOST_INTRUSIVE_CLANG_INLINE_STD_NS
#pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wc++11-extensions"
+ #if defined(__clang__)
+ #pragma GCC diagnostic ignored "-Wc++11-extensions"
+ #endif
#define BOOST_INTRUSIVE_STD_NS_BEG _LIBCPP_BEGIN_NAMESPACE_STD
#define BOOST_INTRUSIVE_STD_NS_END _LIBCPP_END_NAMESPACE_STD
#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE_VERSION) //GCC >= 4.6
diff --git a/boost/intrusive/detail/transform_iterator.hpp b/boost/intrusive/detail/transform_iterator.hpp
index 89ec973967..5e3b1a7652 100644
--- a/boost/intrusive/detail/transform_iterator.hpp
+++ b/boost/intrusive/detail/transform_iterator.hpp
@@ -23,6 +23,7 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/intrusive/detail/iterator.hpp>
namespace boost {
namespace intrusive {
@@ -58,14 +59,14 @@ struct operator_arrow_proxy<T&>
template <class Iterator, class UnaryFunction>
class transform_iterator
- : public boost::intrusive::iterator
- < typename Iterator::iterator_category
- , typename detail::remove_reference<typename UnaryFunction::result_type>::type
- , typename Iterator::difference_type
- , operator_arrow_proxy<typename UnaryFunction::result_type>
- , typename UnaryFunction::result_type>
{
public:
+ typedef typename Iterator::iterator_category iterator_category;
+ typedef typename detail::remove_reference<typename UnaryFunction::result_type>::type value_type;
+ typedef typename Iterator::difference_type difference_type;
+ typedef operator_arrow_proxy<typename UnaryFunction::result_type> pointer;
+ typedef typename UnaryFunction::result_type reference;
+
explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
: members_(it, f)
{}
diff --git a/boost/intrusive/detail/tree_iterator.hpp b/boost/intrusive/detail/tree_iterator.hpp
index 525761f3d6..c2e980d27a 100644
--- a/boost/intrusive/detail/tree_iterator.hpp
+++ b/boost/intrusive/detail/tree_iterator.hpp
@@ -40,13 +40,11 @@ namespace intrusive {
template<class ValueTraits, bool IsConst>
class tree_iterator
{
- protected:
+ private:
typedef iiterator< ValueTraits, IsConst
, std::bidirectional_iterator_tag> types_t;
-
- typedef ValueTraits value_traits;
+ typedef typename types_t::value_traits value_traits;
typedef typename types_t::node_traits node_traits;
-
typedef typename types_t::node node;
typedef typename types_t::node_ptr node_ptr;
typedef typename types_t::const_value_traits_ptr const_value_traits_ptr;
diff --git a/boost/intrusive/detail/tree_value_compare.hpp b/boost/intrusive/detail/tree_value_compare.hpp
new file mode 100644
index 0000000000..a05741edee
--- /dev/null
+++ b/boost/intrusive/detail/tree_value_compare.hpp
@@ -0,0 +1,78 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP
+#define BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/intrusive/detail/ebo_functor_holder.hpp>
+
+namespace boost{
+namespace intrusive{
+
+template<class Key, class T, class KeyCompare, class KeyOfValue>
+struct tree_value_compare
+ : public boost::intrusive::detail::ebo_functor_holder<KeyCompare>
+{
+ typedef boost::intrusive::detail::ebo_functor_holder<KeyCompare> base_t;
+ typedef T value_type;
+ typedef KeyCompare key_compare;
+ typedef KeyOfValue key_of_value;
+ typedef Key key_type;
+
+ explicit tree_value_compare(const key_compare &kcomp)
+ : base_t(kcomp)
+ {}
+
+ tree_value_compare()
+ : base_t()
+ {}
+
+ const key_compare &key_comp() const
+ { return static_cast<const key_compare &>(*this); }
+
+ key_compare &key_comp()
+ { return static_cast<key_compare &>(*this); }
+
+ template<class U>
+ struct is_key
+ : boost::intrusive::detail::is_same<const U, const key_type>
+ {};
+
+ template<class U>
+ typename boost::intrusive::detail::enable_if<is_key<U>, const key_type &>::type
+ key_forward(const U &key) const
+ { return key; }
+
+ template<class U>
+ typename boost::intrusive::detail::disable_if<is_key<U>, const key_type &>::type
+ key_forward(const U &key) const
+ { return KeyOfValue()(key); }
+
+ template<class KeyType, class KeyType2>
+ bool operator()(const KeyType &key1, const KeyType2 &key2) const
+ { return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
+
+ template<class KeyType, class KeyType2>
+ bool operator()(const KeyType &key1, const KeyType2 &key2)
+ { return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
+};
+
+} //namespace intrusive{
+} //namespace boost{
+
+#endif //#ifdef BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP
diff --git a/boost/intrusive/hashtable.hpp b/boost/intrusive/hashtable.hpp
index 1d4f3d3f0c..125330ff6e 100644
--- a/boost/intrusive/hashtable.hpp
+++ b/boost/intrusive/hashtable.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2013
+// (C) Copyright Ion Gaztanaga 2006-2015
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -26,6 +26,7 @@
#include <boost/intrusive/detail/node_cloner_disposer.hpp>
#include <boost/intrusive/detail/simple_disposers.hpp>
#include <boost/intrusive/detail/size_holder.hpp>
+#include <boost/intrusive/detail/iterator.hpp>
//Implementation utilities
#include <boost/intrusive/unordered_set_hook.hpp>
@@ -55,6 +56,62 @@ namespace intrusive {
/// @cond
+template<class InputIt, class T>
+InputIt priv_algo_find(InputIt first, InputIt last, const T& value)
+{
+ for (; first != last; ++first) {
+ if (*first == value) {
+ return first;
+ }
+ }
+ return last;
+}
+
+template<class InputIt, class T>
+typename boost::intrusive::iterator_traits<InputIt>::difference_type
+ priv_algo_count(InputIt first, InputIt last, const T& value)
+{
+ typename boost::intrusive::iterator_traits<InputIt>::difference_type ret = 0;
+ for (; first != last; ++first) {
+ if (*first == value) {
+ ret++;
+ }
+ }
+ return ret;
+}
+
+template <class ForwardIterator1, class ForwardIterator2>
+bool priv_algo_is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2)
+{
+ typedef typename
+ boost::intrusive::iterator_traits<ForwardIterator2>::difference_type
+ distance_type;
+ //Efficiently compare identical prefixes: O(N) if sequences
+ //have the same elements in the same order.
+ for ( ; first1 != last1; ++first1, ++first2){
+ if (! (*first1 == *first2))
+ break;
+ }
+ if (first1 == last1){
+ return true;
+ }
+
+ //Establish last2 assuming equal ranges by iterating over the
+ //rest of the list.
+ ForwardIterator2 last2 = first2;
+ boost::intrusive::iterator_advance(last2, boost::intrusive::iterator_distance(first1, last1));
+ for(ForwardIterator1 scan = first1; scan != last1; ++scan){
+ if (scan != (priv_algo_find)(first1, scan, *scan)){
+ continue; //We've seen this one before.
+ }
+ distance_type matches = (priv_algo_count)(first2, last2, *scan);
+ if (0 == matches || (priv_algo_count)(scan, last1, *scan != matches)){
+ return false;
+ }
+ }
+ return true;
+}
+
template<int Dummy = 0>
struct prime_list_holder
{
@@ -169,35 +226,23 @@ struct unordered_bucket_ptr_impl
};
template <class T>
-struct store_hash_bool
+struct store_hash_is_true
{
template<bool Add>
- struct two_or_three {one _[2 + Add];};
- template <class U> static one test(...);
+ struct two_or_three {yes_type _[2 + Add];};
+ template <class U> static yes_type test(...);
template <class U> static two_or_three<U::store_hash> test (int);
- static const std::size_t value = sizeof(test<T>(0));
+ static const bool value = sizeof(test<T>(0)) > sizeof(yes_type)*2;
};
template <class T>
-struct store_hash_is_true
-{
- static const bool value = store_hash_bool<T>::value > sizeof(one)*2;
-};
-
-template <class T>
-struct optimize_multikey_bool
+struct optimize_multikey_is_true
{
template<bool Add>
- struct two_or_three {one _[2 + Add];};
- template <class U> static one test(...);
+ struct two_or_three {yes_type _[2 + Add];};
+ template <class U> static yes_type test(...);
template <class U> static two_or_three<U::optimize_multikey> test (int);
- static const std::size_t value = sizeof(test<T>(0));
-};
-
-template <class T>
-struct optimize_multikey_is_true
-{
- static const bool value = optimize_multikey_bool<T>::value > sizeof(one)*2;
+ static const bool value = sizeof(test<T>(0)) > sizeof(yes_type)*2;
};
struct insert_commit_data_impl
@@ -216,6 +261,23 @@ inline typename pointer_traits<SlistNodePtr>::template rebind_pointer<Node>::typ
template<class NodeTraits>
struct group_functions
{
+ // A group is reverse-linked
+ //
+ // A is "first in group"
+ // C is "last in group"
+ // __________________
+ // | _____ _____ |
+ // | | | | | | <- Group links
+ // ^ V ^ V ^ V
+ // _ _ _ _
+ // A|_| B|_| C|_| D|_|
+ //
+ // ^ | ^ | ^ | ^ V <- Bucket links
+ // _ _____| |_____| |______| |____| |
+ // |B| |
+ // ^________________________________|
+ //
+
typedef NodeTraits node_traits;
typedef unordered_group_adapter<node_traits> group_traits;
typedef typename node_traits::node_ptr node_ptr;
@@ -225,6 +287,7 @@ struct group_functions
typedef typename reduced_node_traits::node_ptr slist_node_ptr;
typedef typename reduced_node_traits::node slist_node;
typedef circular_slist_algorithms<group_traits> group_algorithms;
+ typedef circular_slist_algorithms<node_traits> node_algorithms;
static slist_node_ptr get_bucket_before_begin
(const slist_node_ptr &bucket_beg, const slist_node_ptr &bucket_end, const node_ptr &p)
@@ -260,53 +323,20 @@ struct group_functions
static node_ptr get_prev_to_first_in_group(const slist_node_ptr &bucket_node, const node_ptr &first_in_group)
{
- //Just iterate using group links and obtain the node
- //before "first_in_group)"
- node_ptr prev_node = detail::dcast_bucket_ptr<node>(bucket_node);
- node_ptr nxt(node_traits::get_next(prev_node));
- while(nxt != first_in_group){
- prev_node = group_traits::get_next(nxt);
- nxt = node_traits::get_next(prev_node);
+ node_ptr nb = detail::dcast_bucket_ptr<node>(bucket_node);
+ node_ptr n;
+ while((n = node_traits::get_next(nb)) != first_in_group){
+ nb = group_traits::get_next(n); //go to last in group
}
- return prev_node;
- }
-
- static node_ptr get_first_in_group_of_last_in_group(const node_ptr &last_in_group)
- {
- //Just iterate using group links and obtain the node
- //before "last_in_group"
- node_ptr possible_first = group_traits::get_next(last_in_group);
- node_ptr possible_first_prev = group_traits::get_next(possible_first);
- // The deleted node is at the end of the group, so the
- // node in the group pointing to it is at the beginning
- // of the group. Find that to change its pointer.
- while(possible_first_prev != last_in_group){
- possible_first = possible_first_prev;
- possible_first_prev = group_traits::get_next(possible_first);
- }
- return possible_first;
+ return nb;
}
static void erase_from_group(const slist_node_ptr &end_ptr, const node_ptr &to_erase_ptr, detail::true_)
{
- node_ptr nxt_ptr(node_traits::get_next(to_erase_ptr));
- node_ptr prev_in_group_ptr(group_traits::get_next(to_erase_ptr));
- bool last_in_group = (end_ptr == nxt_ptr) ||
- (group_traits::get_next(nxt_ptr) != to_erase_ptr);
- bool is_first_in_group = node_traits::get_next(prev_in_group_ptr) != to_erase_ptr;
-
- if(is_first_in_group && last_in_group){
- group_algorithms::init(to_erase_ptr);
- }
- else if(is_first_in_group){
- group_algorithms::unlink_after(nxt_ptr);
- }
- else if(last_in_group){
- node_ptr first_in_group =
- get_first_in_group_of_last_in_group(to_erase_ptr);
- group_algorithms::unlink_after(first_in_group);
- }
- else{
+ node_ptr const nxt_ptr(node_traits::get_next(to_erase_ptr));
+ //Check if the next node is in the group (not end node) and reverse linked to
+ //'to_erase_ptr'. Erase if that's the case.
+ if(nxt_ptr != end_ptr && to_erase_ptr == group_traits::get_next(nxt_ptr)){
group_algorithms::unlink_after(nxt_ptr);
}
}
@@ -317,81 +347,42 @@ struct group_functions
static node_ptr get_last_in_group(const node_ptr &first_in_group, detail::true_)
{ return group_traits::get_next(first_in_group); }
- static node_ptr get_last_in_group(const node_ptr &n, detail::false_)
+ static node_ptr get_last_in_group(node_ptr n, detail::false_)
{ return n; }
- static void init_group(const node_ptr &n, true_)
- { group_algorithms::init(n); }
-
- static void init_group(const node_ptr &, false_)
- {}
-
- static void insert_in_group(const node_ptr &first_in_group, const node_ptr &n, true_)
+ static node_ptr get_first_in_group(node_ptr n, detail::true_)
{
- if(first_in_group){
- if(group_algorithms::unique(first_in_group))
- group_algorithms::link_after(first_in_group, n);
- else{
- group_algorithms::link_after(node_traits::get_next(first_in_group), n);
- }
- }
- else{
- group_algorithms::init_header(n);
+ node_ptr ng;
+ while(n == node_traits::get_next((ng = group_traits::get_next(n)))){
+ n = ng;
}
+ return n;
}
- static slist_node_ptr get_previous_and_next_in_group
- ( const slist_node_ptr &i, node_ptr &nxt_in_group
- //If first_end_ptr == last_end_ptr, then first_end_ptr is the bucket of i
- //Otherwise first_end_ptr is the first bucket and last_end_ptr the last one.
- , const slist_node_ptr &first_end_ptr, const slist_node_ptr &last_end_ptr)
- {
- slist_node_ptr prev;
- node_ptr elem(detail::dcast_bucket_ptr<node>(i));
-
- //It's the last in group if the next_node is a bucket
- slist_node_ptr nxt(node_traits::get_next(elem));
- bool last_in_group = (first_end_ptr <= nxt && nxt <= last_end_ptr) ||
- (group_traits::get_next(detail::dcast_bucket_ptr<node>(nxt)) != elem);
- //It's the first in group if group_previous's next_node is not
- //itself, as group list does not link bucket
- node_ptr prev_in_group(group_traits::get_next(elem));
- bool first_in_group = node_traits::get_next(prev_in_group) != elem;
-
- if(first_in_group){
- node_ptr start_pos;
- if(last_in_group){
- start_pos = elem;
- nxt_in_group = node_ptr();
- }
- else{
- start_pos = prev_in_group;
- nxt_in_group = node_traits::get_next(elem);
- }
- slist_node_ptr bucket_node;
- if(first_end_ptr != last_end_ptr){
- bucket_node = group_functions::get_bucket_before_begin
- (first_end_ptr, last_end_ptr, start_pos);
- }
- else{
- bucket_node = first_end_ptr;
- }
- prev = group_functions::get_prev_to_first_in_group(bucket_node, elem);
- }
- else{
- if(last_in_group){
- nxt_in_group = group_functions::get_first_in_group_of_last_in_group(elem);
- }
- else{
- nxt_in_group = node_traits::get_next(elem);
- }
- prev = group_traits::get_next(elem);
- }
- return prev;
+ static node_ptr next_group_if_first_in_group(node_ptr ptr)
+ {
+ return node_traits::get_next(group_traits::get_next(ptr));
}
+ static node_ptr get_first_in_group(const node_ptr &n, detail::false_)
+ { return n; }
+
+ static void insert_in_group(const node_ptr &first_in_group, const node_ptr &n, true_)
+ { group_algorithms::link_after(first_in_group, n); }
+
static void insert_in_group(const node_ptr&, const node_ptr&, false_)
{}
+
+ static node_ptr split_group(node_ptr const new_first_in_group)
+ {
+ node_ptr const first((get_first_in_group)(new_first_in_group, detail::true_()));
+ if(first != new_first_in_group){
+ node_ptr const last = group_traits::get_next(first);
+ group_traits::set_next(first, group_traits::get_next(new_first_in_group));
+ group_traits::set_next(new_first_in_group, last);
+ }
+ return first;
+ }
};
template<class BucketType, class SplitTraits>
@@ -453,8 +444,7 @@ inline std::size_t hash_to_bucket_split(std::size_t hash_value, std::size_t buck
{
std::size_t bucket_number = detail::hash_to_bucket(hash_value, bucket_cnt, detail::bool_<Power2Buckets>());
if(Incremental)
- if(bucket_number >= split)
- bucket_number -= bucket_cnt/2;
+ bucket_number -= static_cast<std::size_t>(bucket_number >= split)*(bucket_cnt/2);
return bucket_number;
}
@@ -513,6 +503,7 @@ struct hashtable_defaults
{
typedef default_hashtable_hook_applier proto_value_traits;
typedef std::size_t size_type;
+ typedef void key_of_value;
typedef void equal;
typedef void hash;
typedef default_bucket_traits bucket_traits;
@@ -576,17 +567,11 @@ struct node_cast_adaptor
}
};
-static const std::size_t hashtable_data_bool_flags_mask =
- ( hash_bool_flags::cache_begin_pos
- | hash_bool_flags::constant_time_size_pos
- | hash_bool_flags::incremental_pos
- );
-
//bucket_plus_vtraits stores ValueTraits + BucketTraits
//this data is needed by iterators to obtain the
//value from the iterator and detect the bucket
template<class ValueTraits, class BucketTraits>
-struct bucket_plus_vtraits : public ValueTraits
+struct bucket_plus_vtraits
{
typedef BucketTraits bucket_traits;
typedef ValueTraits value_traits;
@@ -607,6 +592,11 @@ struct bucket_plus_vtraits : public ValueTraits
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::node node;
typedef typename value_traits::value_type value_type;
+ typedef typename value_traits::pointer pointer;
+ typedef typename value_traits::const_pointer const_pointer;
+ typedef typename pointer_traits<pointer>::reference reference;
+ typedef typename pointer_traits
+ <const_pointer>::reference const_reference;
typedef circular_slist_algorithms<group_traits> group_algorithms;
typedef typename pointer_traits
<typename value_traits::pointer>::
@@ -618,16 +608,14 @@ struct bucket_plus_vtraits : public ValueTraits
<const bucket_plus_vtraits>::type const_bucket_value_traits_ptr;
typedef typename detail::unordered_bucket_ptr_impl
<value_traits>::type bucket_ptr;
- typedef detail::bool_<detail::optimize_multikey_is_true
- <node_traits>::value> optimize_multikey_t;
template<class BucketTraitsType>
bucket_plus_vtraits(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits)
- : ValueTraits(val_traits), bucket_traits_(::boost::forward<BucketTraitsType>(b_traits))
+ : data(val_traits, ::boost::forward<BucketTraitsType>(b_traits))
{}
bucket_plus_vtraits & operator =(const bucket_plus_vtraits &x)
- { bucket_traits_ = x.bucket_traits_; return *this; }
+ { data.bucket_traits_ = x.data.bucket_traits_; return *this; }
const_value_traits_ptr priv_value_traits_ptr() const
{ return pointer_traits<const_value_traits_ptr>::pointer_to(this->priv_value_traits()); }
@@ -646,18 +634,18 @@ struct bucket_plus_vtraits : public ValueTraits
//value traits
//
const value_traits &priv_value_traits() const
- { return *this; }
+ { return this->data; }
value_traits &priv_value_traits()
- { return *this; }
+ { return this->data; }
//bucket_traits
//
const bucket_traits &priv_bucket_traits() const
- { return this->bucket_traits_; }
+ { return this->data.bucket_traits_; }
bucket_traits &priv_bucket_traits()
- { return this->bucket_traits_; }
+ { return this->data.bucket_traits_; }
//bucket operations
bucket_ptr priv_bucket_pointer() const
@@ -674,6 +662,119 @@ struct bucket_plus_vtraits : public ValueTraits
siterator priv_invalid_local_it() const
{ return this->priv_bucket_traits().bucket_begin()->before_begin(); }
+ template<class NodeDisposer>
+ static size_type priv_erase_from_single_bucket(bucket_type &b, siterator sbefore_first, siterator slast, NodeDisposer node_disposer, detail::true_) //optimize multikey
+ {
+ size_type n = 0;
+ siterator const sfirst(++siterator(sbefore_first));
+ if(sfirst != slast){
+ node_ptr const nf = detail::dcast_bucket_ptr<node>(sfirst.pointed_node());
+ node_ptr const nl = detail::dcast_bucket_ptr<node>(slast.pointed_node());
+ node_ptr const ne = detail::dcast_bucket_ptr<node>(b.end().pointed_node());
+
+ if(group_functions_t::next_group_if_first_in_group(nf) != nf) {
+ // The node is at the beginning of a group.
+ if(nl != ne){
+ group_functions_t::split_group(nl);
+ }
+ }
+ else {
+ node_ptr const group1 = group_functions_t::split_group(nf);
+ if(nl != ne) {
+ node_ptr const group2 = group_functions_t::split_group(ne);
+ if(nf == group2) { //Both first and last in the same group
+ //so join group1 and group2
+ node_ptr const end1 = group_traits::get_next(group1);
+ node_ptr const end2 = group_traits::get_next(group2);
+ group_traits::set_next(group1, end2);
+ group_traits::set_next(group2, end1);
+ }
+ }
+ }
+
+ siterator it(++siterator(sbefore_first));
+ while(it != slast){
+ node_disposer((it++).pointed_node());
+ ++n;
+ }
+ b.erase_after(sbefore_first, slast);
+ }
+ return n;
+ }
+
+ template<class NodeDisposer>
+ static size_type priv_erase_from_single_bucket(bucket_type &b, siterator sbefore_first, siterator slast, NodeDisposer node_disposer, detail::false_) //optimize multikey
+ {
+ size_type n = 0;
+ siterator it(++siterator(sbefore_first));
+ while(it != slast){
+ node_disposer((it++).pointed_node());
+ ++n;
+ }
+ b.erase_after(sbefore_first, slast);
+ return n;
+ }
+
+ template<class NodeDisposer>
+ static void priv_erase_node(bucket_type &b, siterator i, NodeDisposer node_disposer, detail::true_) //optimize multikey
+ {
+ node_ptr const ne(detail::dcast_bucket_ptr<node>(b.end().pointed_node()));
+ node_ptr n(detail::dcast_bucket_ptr<node>(i.pointed_node()));
+ node_ptr pos = node_traits::get_next(group_traits::get_next(n));
+ node_ptr bn;
+ node_ptr nn(node_traits::get_next(n));
+
+ if(pos != n) {
+ //Node is the first of the group
+ bn = group_functions_t::get_prev_to_first_in_group(ne, n);
+
+ //Unlink the rest of the group if it's not the last node of its group
+ if(nn != ne && group_traits::get_next(nn) == n){
+ group_algorithms::unlink_after(nn);
+ }
+ }
+ else if(nn != ne && group_traits::get_next(nn) == n){
+ //Node is not the end of the group
+ bn = group_traits::get_next(n);
+ group_algorithms::unlink_after(nn);
+ }
+ else{
+ //Node is the end of the group
+ bn = group_traits::get_next(n);
+ node_ptr const x(group_algorithms::get_previous_node(n));
+ group_algorithms::unlink_after(x);
+ }
+ b.erase_after_and_dispose(bucket_type::s_iterator_to(*bn), node_disposer);
+ }
+
+ template<class NodeDisposer>
+ static void priv_erase_node(bucket_type &b, siterator i, NodeDisposer node_disposer, detail::false_) //optimize multikey
+ { b.erase_after_and_dispose(b.previous(i), node_disposer); }
+
+ template<class NodeDisposer, bool OptimizeMultikey>
+ size_type priv_erase_node_range( siterator const &before_first_it, size_type const first_bucket
+ , siterator const &last_it, size_type const last_bucket
+ , NodeDisposer node_disposer, detail::bool_<OptimizeMultikey> optimize_multikey_tag)
+ {
+ size_type num_erased(0);
+ siterator last_step_before_it;
+ if(first_bucket != last_bucket){
+ bucket_type *b = (&this->priv_bucket_pointer()[0]);
+ num_erased += this->priv_erase_from_single_bucket
+ (b[first_bucket], before_first_it, b[first_bucket].end(), node_disposer, optimize_multikey_tag);
+ for(size_type i = 0, n = (last_bucket - first_bucket - 1); i != n; ++i){
+ num_erased += this->priv_erase_whole_bucket(b[first_bucket+i+1], node_disposer);
+ }
+ last_step_before_it = b[last_bucket].before_begin();
+ }
+ else{
+ last_step_before_it = before_first_it;
+ }
+ num_erased += this->priv_erase_from_single_bucket
+ (this->priv_bucket_pointer()[last_bucket], last_step_before_it, last_it, node_disposer, optimize_multikey_tag);
+ return num_erased;
+ }
+
static siterator priv_get_last(bucket_type &b, detail::true_) //optimize multikey
{
//First find the last node of p's group.
@@ -690,14 +791,30 @@ struct bucket_plus_vtraits : public ValueTraits
return bucket_type::s_iterator_to(*last_node_group);
}
+ template<class NodeDisposer>
+ size_type priv_erase_whole_bucket(bucket_type &b, NodeDisposer node_disposer)
+ {
+ size_type num_erased = 0;
+ siterator b_begin(b.before_begin());
+ siterator nxt(b_begin);
+ ++nxt;
+ siterator const end_sit(b.end());
+ while(nxt != end_sit){
+ //No need to init group links as we'll delete all bucket nodes
+ nxt = bucket_type::s_erase_after_and_dispose(b_begin, node_disposer);
+ ++num_erased;
+ }
+ return num_erased;
+ }
+
static siterator priv_get_last(bucket_type &b, detail::false_) //NOT optimize multikey
{ return b.previous(b.end()); }
static siterator priv_get_previous(bucket_type &b, siterator i, detail::true_) //optimize multikey
{
- node_ptr elem(detail::dcast_bucket_ptr<node>(i.pointed_node()));
- node_ptr prev_in_group(group_traits::get_next(elem));
- bool first_in_group = node_traits::get_next(prev_in_group) != elem;
+ node_ptr const elem(detail::dcast_bucket_ptr<node>(i.pointed_node()));
+ node_ptr const prev_in_group(group_traits::get_next(elem));
+ bool const first_in_group = node_traits::get_next(prev_in_group) != elem;
typename bucket_type::node &n = first_in_group
? *group_functions_t::get_prev_to_first_in_group(b.end().pointed_node(), elem)
: *group_traits::get_next(elem)
@@ -708,19 +825,6 @@ struct bucket_plus_vtraits : public ValueTraits
static siterator priv_get_previous(bucket_type &b, siterator i, detail::false_) //NOT optimize multikey
{ return b.previous(i); }
- static void priv_clear_group_nodes(bucket_type &b, detail::true_) //optimize multikey
- {
- siterator it(b.begin()), itend(b.end());
- while(it != itend){
- node_ptr to_erase(detail::dcast_bucket_ptr<node>(it.pointed_node()));
- ++it;
- group_algorithms::init(to_erase);
- }
- }
-
- static void priv_clear_group_nodes(bucket_type &, detail::false_) //NOT optimize multikey
- {}
-
std::size_t priv_get_bucket_num_no_hash_store(siterator it, detail::true_) //optimize multikey
{
const bucket_ptr f(this->priv_bucket_pointer()), l(f + this->priv_bucket_count() - 1);
@@ -757,19 +861,19 @@ struct bucket_plus_vtraits : public ValueTraits
static std::size_t priv_stored_hash(slist_node_ptr n, detail::true_) //store_hash
{ return node_traits::get_hash(detail::dcast_bucket_ptr<node>(n)); }
- static std::size_t priv_stored_hash(slist_node_ptr, detail::false_) //NO store_hash (This should never be called)
- { BOOST_INTRUSIVE_INVARIANT_ASSERT(0); return 0; }
+ static std::size_t priv_stored_hash(slist_node_ptr, detail::false_) //NO store_hash
+ { return std::size_t(-1); }
- node &priv_value_to_node(value_type &v)
+ node &priv_value_to_node(reference v)
{ return *this->priv_value_traits().to_node_ptr(v); }
- const node &priv_value_to_node(const value_type &v) const
+ const node &priv_value_to_node(const_reference v) const
{ return *this->priv_value_traits().to_node_ptr(v); }
- value_type &priv_value_from_slist_node(slist_node_ptr n)
+ reference priv_value_from_slist_node(slist_node_ptr n)
{ return *this->priv_value_traits().to_value_ptr(detail::dcast_bucket_ptr<node>(n)); }
- const value_type &priv_value_from_slist_node(slist_node_ptr n) const
+ const_reference priv_value_from_slist_node(slist_node_ptr n) const
{ return *this->priv_value_traits().to_value_ptr(detail::dcast_bucket_ptr<node>(n)); }
void priv_clear_buckets(const bucket_ptr buckets_ptr, const size_type bucket_cnt)
@@ -777,7 +881,6 @@ struct bucket_plus_vtraits : public ValueTraits
bucket_ptr buckets_it = buckets_ptr;
for(size_type bucket_i = 0; bucket_i != bucket_cnt; ++buckets_it, ++bucket_i){
if(safemode_or_autounlink){
- bucket_plus_vtraits::priv_clear_group_nodes(*buckets_it, optimize_multikey_t());
buckets_it->clear_and_dispose(detail::init_disposer<node_algorithms>());
}
else{
@@ -786,10 +889,51 @@ struct bucket_plus_vtraits : public ValueTraits
}
}
- bucket_traits bucket_traits_;
+ std::size_t priv_stored_or_compute_hash(const value_type &v, detail::true_) const //For store_hash == true
+ { return node_traits::get_hash(this->priv_value_traits().to_node_ptr(v)); }
+
+ typedef hashtable_iterator<bucket_plus_vtraits, false> iterator;
+ typedef hashtable_iterator<bucket_plus_vtraits, true> const_iterator;
+
+ iterator end()
+ { return iterator(this->priv_invalid_local_it(), 0); }
+
+ const_iterator end() const
+ { return this->cend(); }
+
+ const_iterator cend() const
+ { return const_iterator(this->priv_invalid_local_it(), 0); }
+
+ static size_type suggested_upper_bucket_count(size_type n)
+ {
+ const std::size_t *primes = &prime_list_holder<0>::prime_list[0];
+ const std::size_t *primes_end = primes + prime_list_holder<0>::prime_list_size;
+ std::size_t const* bound = std::lower_bound(primes, primes_end, n);
+ bound -= (bound == primes_end);
+ return size_type(*bound);
+ }
+
+ static size_type suggested_lower_bucket_count(size_type n)
+ {
+ const std::size_t *primes = &prime_list_holder<0>::prime_list[0];
+ const std::size_t *primes_end = primes + prime_list_holder<0>::prime_list_size;
+ size_type const* bound = std::upper_bound(primes, primes_end, n);
+ bound -= (bound != primes);
+ return size_type(*bound);
+ }
+
+ //Public functions:
+ struct data_type : public ValueTraits
+ {
+ template<class BucketTraitsType>
+ data_type(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits)
+ : ValueTraits(val_traits), bucket_traits_(::boost::forward<BucketTraitsType>(b_traits))
+ {}
+ bucket_traits bucket_traits_;
+ } data;
};
-template<class Hash, class T>
+template<class Hash, class>
struct get_hash
{
typedef Hash type;
@@ -801,76 +945,124 @@ struct get_hash<void, T>
typedef ::boost::hash<T> type;
};
+template<class EqualTo, class>
+struct get_equal_to
+{
+ typedef EqualTo type;
+};
+
+template<class T>
+struct get_equal_to<void, T>
+{
+ typedef std::equal_to<T> type;
+};
+
+template<class KeyOfValue, class T>
+struct get_hash_key_of_value
+{
+ typedef KeyOfValue type;
+};
+
+template<class T>
+struct get_hash_key_of_value<void, T>
+{
+ typedef ::boost::intrusive::detail::identity<T> type;
+};
+
+template<class T, class VoidOrKeyOfValue>
+struct hash_key_types_base
+{
+ typedef typename get_hash_key_of_value
+ < VoidOrKeyOfValue, T>::type key_of_value;
+ typedef typename key_of_value::type key_type;
+};
+
+template<class T, class VoidOrKeyOfValue, class VoidOrKeyHash>
+struct hash_key_hash
+ : get_hash
+ < VoidOrKeyHash
+ , typename hash_key_types_base<T, VoidOrKeyOfValue>::key_type
+ >
+{};
+
+template<class T, class VoidOrKeyOfValue, class VoidOrKeyEqual>
+struct hash_key_equal
+ : get_equal_to
+ < VoidOrKeyEqual
+ , typename hash_key_types_base<T, VoidOrKeyOfValue>::key_type
+ >
+
+{};
+
//bucket_hash_t
//Stores bucket_plus_vtraits plust the hash function
-template<class VoidOrKeyHash, class ValueTraits, class BucketTraits>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class BucketTraits>
struct bucket_hash_t
//Use public inheritance to avoid MSVC bugs with closures
: public detail::ebo_functor_holder
- <typename get_hash< VoidOrKeyHash
- , typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits::value_type
- >::type
- >
+ <typename hash_key_hash < typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits::value_type
+ , VoidOrKeyOfValue
+ , VoidOrKeyHash
+ >::type
+ >
+ , bucket_plus_vtraits<ValueTraits, BucketTraits> //4
{
typedef typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits value_traits;
typedef typename value_traits::value_type value_type;
typedef typename value_traits::node_traits node_traits;
- typedef typename get_hash< VoidOrKeyHash, value_type>::type hasher;
+ typedef hash_key_hash
+ < value_type, VoidOrKeyOfValue, VoidOrKeyHash> hash_key_hash_t;
+ typedef typename hash_key_hash_t::type hasher;
+ typedef typename hash_key_types_base<value_type, VoidOrKeyOfValue>::key_of_value key_of_value;
+
typedef BucketTraits bucket_traits;
typedef bucket_plus_vtraits<ValueTraits, BucketTraits> bucket_plus_vtraits_t;
+ typedef detail::ebo_functor_holder<hasher> base_t;
template<class BucketTraitsType>
bucket_hash_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h)
- : detail::ebo_functor_holder<hasher>(h), internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits))
+ : detail::ebo_functor_holder<hasher>(h), bucket_plus_vtraits_t(val_traits, ::boost::forward<BucketTraitsType>(b_traits))
{}
const hasher &priv_hasher() const
- { return this->detail::ebo_functor_holder<hasher>::get(); }
+ { return this->base_t::get(); }
hasher &priv_hasher()
- { return this->detail::ebo_functor_holder<hasher>::get(); }
+ { return this->base_t::get(); }
- std::size_t priv_stored_or_compute_hash(const value_type &v, detail::true_) const //For store_hash == true
- { return node_traits::get_hash(this->internal.priv_value_traits().to_node_ptr(v)); }
+ using bucket_plus_vtraits_t::priv_stored_or_compute_hash; //For store_hash == true
std::size_t priv_stored_or_compute_hash(const value_type &v, detail::false_) const //For store_hash == false
- { return this->priv_hasher()(v); }
-
- bucket_plus_vtraits_t internal; //4
+ { return this->priv_hasher()(key_of_value()(v)); }
};
-
-template<class EqualTo, class T>
-struct get_equal_to
+template<class ValueTraits, class BucketTraits, class VoidOrKeyOfValue, class VoidOrKeyEqual>
+struct hashtable_equal_holder
{
- typedef EqualTo type;
-};
-
-template<class T>
-struct get_equal_to<void, T>
-{
- typedef ::std::equal_to<T> type;
+ typedef detail::ebo_functor_holder
+ < typename hash_key_equal < typename bucket_plus_vtraits<ValueTraits, BucketTraits>::value_traits::value_type
+ , VoidOrKeyOfValue
+ , VoidOrKeyEqual
+ >::type
+ > type;
};
//bucket_hash_equal_t
//Stores bucket_hash_t and the equality function when the first
//non-empty bucket shall not be cached.
-template<class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits, bool>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits, bool>
struct bucket_hash_equal_t
//Use public inheritance to avoid MSVC bugs with closures
- : public detail::ebo_functor_holder //equal
- <typename get_equal_to< VoidOrKeyEqual
- , typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits::value_type
- >::type
- >
+ : public bucket_hash_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, BucketTraits> //3
+ , public hashtable_equal_holder<ValueTraits, BucketTraits, VoidOrKeyOfValue, VoidOrKeyEqual>::type //equal
{
- typedef bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> bucket_hash_type;
+ typedef typename hashtable_equal_holder
+ <ValueTraits, BucketTraits, VoidOrKeyOfValue, VoidOrKeyEqual>::type equal_holder_t;
+ typedef bucket_hash_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, BucketTraits> bucket_hash_type;
typedef bucket_plus_vtraits<ValueTraits,BucketTraits> bucket_plus_vtraits_t;
- typedef typename bucket_plus_vtraits_t::value_traits value_traits;
- typedef typename get_equal_to< VoidOrKeyEqual
- , typename value_traits::value_type
- >::type value_equal;
+ typedef ValueTraits value_traits;
+ typedef typename equal_holder_t::functor_type key_equal;
typedef typename bucket_hash_type::hasher hasher;
typedef BucketTraits bucket_traits;
typedef typename bucket_plus_vtraits_t::slist_impl slist_impl;
@@ -880,13 +1072,13 @@ struct bucket_hash_equal_t
typedef typename detail::unordered_bucket_ptr_impl<value_traits>::type bucket_ptr;
template<class BucketTraitsType>
- bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const value_equal &e)
- : detail::ebo_functor_holder<value_equal>(e)
- , internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h)
+ bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const key_equal &e)
+ : bucket_hash_type(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h)
+ , equal_holder_t(e)
{}
bucket_ptr priv_get_cache()
- { return this->internal.internal.priv_bucket_pointer(); }
+ { return this->bucket_hash_type::priv_bucket_pointer(); }
void priv_set_cache(const bucket_ptr &)
{}
@@ -903,14 +1095,14 @@ struct bucket_hash_equal_t
siterator priv_begin() const
{
size_type n = 0;
- size_type bucket_cnt = this->internal.internal.priv_bucket_count();
+ size_type bucket_cnt = this->bucket_hash_type::priv_bucket_count();
for (n = 0; n < bucket_cnt; ++n){
- bucket_type &b = this->internal.internal.priv_bucket_pointer()[n];
+ bucket_type &b = this->bucket_hash_type::priv_bucket_pointer()[n];
if(!b.empty()){
return b.begin();
}
}
- return this->internal.internal.priv_invalid_local_it();
+ return this->bucket_hash_type::priv_invalid_local_it();
}
void priv_insertion_update_cache(size_type)
@@ -922,43 +1114,38 @@ struct bucket_hash_equal_t
void priv_erasure_update_cache()
{}
- const value_equal &priv_equal() const
- { return this->detail::ebo_functor_holder<value_equal>::get(); }
+ const key_equal &priv_equal() const
+ { return this->equal_holder_t::get(); }
- value_equal &priv_equal()
- { return this->detail::ebo_functor_holder<value_equal>::get(); }
-
- bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> internal; //3
+ key_equal &priv_equal()
+ { return this->equal_holder_t::get(); }
};
//bucket_hash_equal_t
//Stores bucket_hash_t and the equality function when the first
//non-empty bucket shall be cached.
-template<class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits> //cache_begin == true version
-struct bucket_hash_equal_t<VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits, true>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits> //cache_begin == true version
+struct bucket_hash_equal_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, true>
//Use public inheritance to avoid MSVC bugs with closures
- : public detail::ebo_functor_holder //equal
- <typename get_equal_to< VoidOrKeyEqual
- , typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits::value_type
- >::type
- >
+ : bucket_hash_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, BucketTraits> //2
+ , hashtable_equal_holder<ValueTraits, BucketTraits, VoidOrKeyOfValue, VoidOrKeyEqual>::type
{
- typedef bucket_plus_vtraits<ValueTraits, BucketTraits> bucket_plus_vtraits_t;
- typedef bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> bucket_hash_type;
- typedef typename bucket_plus_vtraits
- <ValueTraits,BucketTraits>::value_traits value_traits;
- typedef typename get_equal_to
- < VoidOrKeyEqual
- , typename value_traits::value_type>::type value_equal;
+ typedef typename hashtable_equal_holder
+ <ValueTraits, BucketTraits, VoidOrKeyOfValue, VoidOrKeyEqual>::type equal_holder_t;
+
+ typedef bucket_plus_vtraits<ValueTraits,BucketTraits> bucket_plus_vtraits_t;
+ typedef ValueTraits value_traits;
+ typedef typename equal_holder_t::functor_type key_equal;
+ typedef bucket_hash_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, BucketTraits> bucket_hash_type;
typedef typename bucket_hash_type::hasher hasher;
typedef BucketTraits bucket_traits;
typedef typename bucket_plus_vtraits_t::slist_impl::size_type size_type;
typedef typename bucket_plus_vtraits_t::slist_impl::iterator siterator;
template<class BucketTraitsType>
- bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const value_equal &e)
- : detail::ebo_functor_holder<value_equal>(e)
- , internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h)
+ bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const key_equal &e)
+ : bucket_hash_type(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h)
+ , equal_holder_t(e)
{}
typedef typename detail::unordered_bucket_ptr_impl
@@ -974,10 +1161,10 @@ struct bucket_hash_equal_t<VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTra
{ cached_begin_ = p; }
std::size_t priv_get_cache_bucket_num()
- { return this->cached_begin_ - this->internal.internal.priv_bucket_pointer(); }
+ { return this->cached_begin_ - this->bucket_hash_type::priv_bucket_pointer(); }
void priv_initialize_cache()
- { this->cached_begin_ = this->internal.internal.priv_invalid_bucket(); }
+ { this->cached_begin_ = this->bucket_hash_type::priv_invalid_bucket(); }
void priv_swap_cache(bucket_hash_equal_t &other)
{
@@ -986,8 +1173,8 @@ struct bucket_hash_equal_t<VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTra
siterator priv_begin() const
{
- if(this->cached_begin_ == this->internal.internal.priv_invalid_bucket()){
- return this->internal.internal.priv_invalid_local_it();
+ if(this->cached_begin_ == this->bucket_hash_type::priv_invalid_bucket()){
+ return this->bucket_hash_type::priv_invalid_local_it();
}
else{
return this->cached_begin_->begin();
@@ -996,34 +1183,34 @@ struct bucket_hash_equal_t<VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTra
void priv_insertion_update_cache(size_type insertion_bucket)
{
- bucket_ptr p = this->internal.internal.priv_bucket_pointer() + insertion_bucket;
+ bucket_ptr p = this->bucket_hash_type::priv_bucket_pointer() + insertion_bucket;
if(p < this->cached_begin_){
this->cached_begin_ = p;
}
}
- const value_equal &priv_equal() const
- { return this->detail::ebo_functor_holder<value_equal>::get(); }
+ const key_equal &priv_equal() const
+ { return this->equal_holder_t::get(); }
- value_equal &priv_equal()
- { return this->detail::ebo_functor_holder<value_equal>::get(); }
+ key_equal &priv_equal()
+ { return this->equal_holder_t::get(); }
void priv_erasure_update_cache_range(size_type first_bucket_num, size_type last_bucket_num)
{
//If the last bucket is the end, the cache must be updated
//to the last position if all
if(this->priv_get_cache_bucket_num() == first_bucket_num &&
- this->internal.internal.priv_bucket_pointer()[first_bucket_num].empty() ){
- this->priv_set_cache(this->internal.internal.priv_bucket_pointer() + last_bucket_num);
+ this->bucket_hash_type::priv_bucket_pointer()[first_bucket_num].empty() ){
+ this->priv_set_cache(this->bucket_hash_type::priv_bucket_pointer() + last_bucket_num);
this->priv_erasure_update_cache();
}
}
void priv_erasure_update_cache()
{
- if(this->cached_begin_ != this->internal.internal.priv_invalid_bucket()){
- size_type current_n = this->priv_get_cache() - this->internal.internal.priv_bucket_pointer();
- for( const size_type num_buckets = this->internal.internal.priv_bucket_count()
+ if(this->cached_begin_ != this->bucket_hash_type::priv_invalid_bucket()){
+ size_type current_n = this->priv_get_cache() - this->bucket_hash_type::priv_bucket_pointer();
+ for( const size_type num_buckets = this->bucket_hash_type::priv_bucket_count()
; current_n < num_buckets
; ++current_n, ++this->priv_get_cache()){
if(!this->priv_get_cache()->empty()){
@@ -1035,103 +1222,291 @@ struct bucket_hash_equal_t<VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTra
}
bucket_ptr cached_begin_;
- bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> internal; //2
};
+//This wrapper around size_traits is used
+//to maintain minimal container size with compilers like MSVC
+//that have problems with EBO and multiple empty base classes
+template<class DeriveFrom, class SizeType, bool>
+struct hashtable_size_traits_wrapper
+ : public DeriveFrom
+{
+ template<class Base, class Arg0, class Arg1, class Arg2>
+ hashtable_size_traits_wrapper( BOOST_FWD_REF(Base) base, BOOST_FWD_REF(Arg0) arg0
+ , BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2)
+ : DeriveFrom(::boost::forward<Base>(base)
+ , ::boost::forward<Arg0>(arg0)
+ , ::boost::forward<Arg1>(arg1)
+ , ::boost::forward<Arg2>(arg2))
+ {}
+ typedef detail::size_holder < true, SizeType> size_traits;//size_traits
+
+ size_traits size_traits_;
+
+ const size_traits &priv_size_traits() const
+ { return size_traits_; }
+
+ size_traits &priv_size_traits()
+ { return size_traits_; }
+};
+
+template<class DeriveFrom, class SizeType>
+struct hashtable_size_traits_wrapper<DeriveFrom, SizeType, false>
+ : public DeriveFrom
+{
+ template<class Base, class Arg0, class Arg1, class Arg2>
+ hashtable_size_traits_wrapper( BOOST_FWD_REF(Base) base, BOOST_FWD_REF(Arg0) arg0
+ , BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2)
+ : DeriveFrom(::boost::forward<Base>(base)
+ , ::boost::forward<Arg0>(arg0)
+ , ::boost::forward<Arg1>(arg1)
+ , ::boost::forward<Arg2>(arg2))
+ {}
+
+ typedef detail::size_holder< false, SizeType> size_traits;
+
+ const size_traits &priv_size_traits() const
+ { return size_traits_; }
+
+ size_traits &priv_size_traits()
+ { return size_traits_; }
+
+ static size_traits size_traits_;
+};
+
+template<class DeriveFrom, class SizeType>
+detail::size_holder< false, SizeType > hashtable_size_traits_wrapper<DeriveFrom, SizeType, false>::size_traits_;
+
//hashdata_internal
//Stores bucket_hash_equal_t and split_traits
-template<class SizeType, std::size_t BoolFlags, class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits, class SizeType, std::size_t BoolFlags>
struct hashdata_internal
- : public detail::size_holder< 0 != (BoolFlags & hash_bool_flags::incremental_pos), SizeType, int> //split_traits
+ : public hashtable_size_traits_wrapper
+ < bucket_hash_equal_t
+ < ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual
+ , BucketTraits
+ , 0 != (BoolFlags & hash_bool_flags::cache_begin_pos)
+ > //2
+ , SizeType
+ , (BoolFlags & hash_bool_flags::incremental_pos) != 0
+ >
{
- typedef bucket_hash_equal_t
- < VoidOrKeyHash, VoidOrKeyEqual
- , ValueTraits, BucketTraits
- , 0 != (BoolFlags & hash_bool_flags::cache_begin_pos)
+ typedef hashtable_size_traits_wrapper
+ < bucket_hash_equal_t
+ < ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual
+ , BucketTraits
+ , 0 != (BoolFlags & hash_bool_flags::cache_begin_pos)
+ > //2
+ , SizeType
+ , (BoolFlags & hash_bool_flags::incremental_pos) != 0
> internal_type;
- typedef typename internal_type::value_equal value_equal;
+ typedef typename internal_type::key_equal key_equal;
typedef typename internal_type::hasher hasher;
typedef bucket_plus_vtraits<ValueTraits,BucketTraits> bucket_plus_vtraits_t;
typedef typename bucket_plus_vtraits_t::size_type size_type;
+ typedef typename internal_type::size_traits split_traits;
typedef typename bucket_plus_vtraits_t::bucket_ptr bucket_ptr;
- typedef detail::size_holder
- <0 != (BoolFlags & hash_bool_flags::incremental_pos)
- , SizeType, int> split_traits;
- typedef typename bucket_plus_vtraits_t::
- value_traits::node_traits node_traits;
- typedef detail::bool_<detail::optimize_multikey_is_true
- <node_traits>::value> optimize_multikey_t;
+ typedef typename bucket_plus_vtraits_t::const_value_traits_ptr const_value_traits_ptr;
+ typedef typename bucket_plus_vtraits_t::siterator siterator;
+ typedef typename bucket_plus_vtraits_t::bucket_traits bucket_traits;
+ typedef typename bucket_plus_vtraits_t::value_traits value_traits;
+ typedef typename bucket_plus_vtraits_t::bucket_type bucket_type;
+ typedef typename value_traits::value_type value_type;
+ typedef typename value_traits::pointer pointer;
+ typedef typename value_traits::const_pointer const_pointer;
+ typedef typename pointer_traits<pointer>::reference reference;
+ typedef typename pointer_traits
+ <const_pointer>::reference const_reference;
+ typedef typename value_traits::node_traits node_traits;
+ typedef typename node_traits::node node;
+ typedef typename node_traits::node_ptr node_ptr;
+ typedef typename node_traits::const_node_ptr const_node_ptr;
+ typedef detail::node_functions<node_traits> node_functions_t;
+ typedef typename detail::get_slist_impl
+ <typename detail::reduced_slist_node_traits
+ <typename value_traits::node_traits>::type
+ >::type slist_impl;
+ typedef typename slist_impl::node_algorithms node_algorithms;
+ typedef typename slist_impl::node_ptr slist_node_ptr;
+
+ typedef hash_key_types_base
+ < typename ValueTraits::value_type
+ , VoidOrKeyOfValue
+ > hash_types_base;
+ typedef typename hash_types_base::key_of_value key_of_value;
+
+ static const bool store_hash = detail::store_hash_is_true<node_traits>::value;
+ static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
+ static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
+
+ typedef detail::bool_<store_hash> store_hash_t;
+
+ typedef detail::transform_iterator
+ < typename slist_impl::iterator
+ , downcast_node_to_value_t
+ < value_traits
+ , false> > local_iterator;
+
+ typedef detail::transform_iterator
+ < typename slist_impl::iterator
+ , downcast_node_to_value_t
+ < value_traits
+ , true> > const_local_iterator;
+ //
template<class BucketTraitsType>
hashdata_internal( const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits
- , const hasher & h, const value_equal &e)
- : internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h, e)
+ , const hasher & h, const key_equal &e)
+ : internal_type(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h, e)
{}
split_traits &priv_split_traits()
- { return *this; }
+ { return this->priv_size_traits(); }
const split_traits &priv_split_traits() const
- { return *this; }
+ { return this->priv_size_traits(); }
~hashdata_internal()
{ this->priv_clear_buckets(); }
void priv_clear_buckets()
{
- this->internal.internal.internal.priv_clear_buckets
- ( this->internal.priv_get_cache()
- , this->internal.internal.internal.priv_bucket_count()
- - (this->internal.priv_get_cache()
- - this->internal.internal.internal.priv_bucket_pointer()));
+ this->internal_type::priv_clear_buckets
+ ( this->priv_get_cache()
+ , this->internal_type::priv_bucket_count()
+ - (this->priv_get_cache()
+ - this->internal_type::priv_bucket_pointer()));
}
void priv_clear_buckets_and_cache()
{
this->priv_clear_buckets();
- this->internal.priv_initialize_cache();
+ this->priv_initialize_cache();
}
void priv_initialize_buckets_and_cache()
{
- this->internal.internal.internal.priv_clear_buckets
- ( this->internal.internal.internal.priv_bucket_pointer()
- , this->internal.internal.internal.priv_bucket_count());
- this->internal.priv_initialize_cache();
+ this->internal_type::priv_clear_buckets
+ ( this->internal_type::priv_bucket_pointer()
+ , this->internal_type::priv_bucket_count());
+ this->priv_initialize_cache();
}
- internal_type internal; //2
-};
+ typedef hashtable_iterator<bucket_plus_vtraits_t, false> iterator;
+ typedef hashtable_iterator<bucket_plus_vtraits_t, true> const_iterator;
-//hashtable_data_t
-//Stores hashdata_internal and size_traits
-template<class SizeType, std::size_t BoolFlags, class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits>
-struct hashtable_data_t
- : public detail::size_holder
- < 0 != (BoolFlags & hash_bool_flags::constant_time_size_pos), SizeType> //size_traits
-{
- typedef detail::size_holder
- < 0 != (BoolFlags & hash_bool_flags::constant_time_size_pos)
- , SizeType> size_traits;
- typedef hashdata_internal
- < SizeType
- , BoolFlags & (hash_bool_flags::incremental_pos | hash_bool_flags::cache_begin_pos)
- , VoidOrKeyHash, VoidOrKeyEqual
- , ValueTraits, BucketTraits> internal_type;
- typedef ValueTraits value_traits;
- typedef typename internal_type::value_equal value_equal;
- typedef typename internal_type::hasher hasher;
- typedef BucketTraits bucket_traits;
- typedef bucket_plus_vtraits
- <ValueTraits,BucketTraits> bucket_plus_vtraits_t;
+ static std::size_t priv_stored_hash(slist_node_ptr n, detail::true_ true_value)
+ { return bucket_plus_vtraits<ValueTraits, BucketTraits>::priv_stored_hash(n, true_value); }
- template<class BucketTraitsType>
- hashtable_data_t( BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h
- , const value_equal &e, const value_traits &val_traits)
- : internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h, e)
- {}
+ static std::size_t priv_stored_hash(slist_node_ptr n, detail::false_ false_value)
+ { return bucket_plus_vtraits<ValueTraits, BucketTraits>::priv_stored_hash(n, false_value); }
+
+ //public functions
+ SizeType split_count() const
+ {
+ return this->priv_split_traits().get_size();
+ }
+
+ iterator iterator_to(reference value)
+ {
+ return iterator(bucket_type::s_iterator_to
+ (this->priv_value_to_node(value)), &this->get_bucket_value_traits());
+ }
+
+ const_iterator iterator_to(const_reference value) const
+ {
+ siterator const sit = bucket_type::s_iterator_to
+ ( *pointer_traits<node_ptr>::const_cast_from
+ (pointer_traits<const_node_ptr>::pointer_to(this->priv_value_to_node(value)))
+ );
+ return const_iterator(sit, &this->get_bucket_value_traits());
+ }
+
+ static local_iterator s_local_iterator_to(reference value)
+ {
+ BOOST_STATIC_ASSERT((!stateful_value_traits));
+ siterator sit = bucket_type::s_iterator_to(*value_traits::to_node_ptr(value));
+ return local_iterator(sit, const_value_traits_ptr());
+ }
+
+ static const_local_iterator s_local_iterator_to(const_reference value)
+ {
+ BOOST_STATIC_ASSERT((!stateful_value_traits));
+ siterator const sit = bucket_type::s_iterator_to
+ ( *pointer_traits<node_ptr>::const_cast_from
+ (value_traits::to_node_ptr(value))
+ );
+ return const_local_iterator(sit, const_value_traits_ptr());
+ }
+
+ local_iterator local_iterator_to(reference value)
+ {
+ siterator sit = bucket_type::s_iterator_to(this->priv_value_to_node(value));
+ return local_iterator(sit, this->priv_value_traits_ptr());
+ }
+
+ const_local_iterator local_iterator_to(const_reference value) const
+ {
+ siterator sit = bucket_type::s_iterator_to
+ ( *pointer_traits<node_ptr>::const_cast_from
+ (pointer_traits<const_node_ptr>::pointer_to(this->priv_value_to_node(value)))
+ );
+ return const_local_iterator(sit, this->priv_value_traits_ptr());
+ }
+
+ size_type bucket_count() const
+ { return this->priv_bucket_count(); }
- internal_type internal; //1
+ size_type bucket_size(size_type n) const
+ { return this->priv_bucket_pointer()[n].size(); }
+
+ bucket_ptr bucket_pointer() const
+ { return this->priv_bucket_pointer(); }
+
+ local_iterator begin(size_type n)
+ { return local_iterator(this->priv_bucket_pointer()[n].begin(), this->priv_value_traits_ptr()); }
+
+ const_local_iterator begin(size_type n) const
+ { return this->cbegin(n); }
+
+ const_local_iterator cbegin(size_type n) const
+ {
+ return const_local_iterator
+ ( pointer_traits<bucket_ptr>::const_cast_from(this->priv_bucket_pointer())[n].begin()
+ , this->priv_value_traits_ptr());
+ }
+
+ using internal_type::end;
+ using internal_type::cend;
+ local_iterator end(size_type n)
+ { return local_iterator(this->priv_bucket_pointer()[n].end(), this->priv_value_traits_ptr()); }
+
+ const_local_iterator end(size_type n) const
+ { return this->cend(n); }
+
+ const_local_iterator cend(size_type n) const
+ {
+ return const_local_iterator
+ ( pointer_traits<bucket_ptr>::const_cast_from(this->priv_bucket_pointer())[n].end()
+ , this->priv_value_traits_ptr());
+ }
+
+ //Public functions for hashtable_impl
+
+ iterator begin()
+ { return iterator(this->priv_begin(), &this->get_bucket_value_traits()); }
+
+ const_iterator begin() const
+ { return this->cbegin(); }
+
+ const_iterator cbegin() const
+ { return const_iterator(this->priv_begin(), &this->get_bucket_value_traits()); }
+
+ hasher hash_function() const
+ { return this->priv_hasher(); }
+
+ key_equal key_eq() const
+ { return this->priv_equal(); }
};
/// @endcond
@@ -1175,61 +1550,82 @@ struct hashtable_data_t
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyHash, class VoidOrKeyEqual, class SizeType, class BucketTraits, std::size_t BoolFlags>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits, class SizeType, std::size_t BoolFlags>
#endif
class hashtable_impl
- : private hashtable_data_t
- < SizeType
- , BoolFlags & hashtable_data_bool_flags_mask
- , VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits>
+ : private hashtable_size_traits_wrapper
+ < hashdata_internal
+ < ValueTraits
+ , VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual
+ , BucketTraits, SizeType
+ , BoolFlags & (hash_bool_flags::incremental_pos | hash_bool_flags::cache_begin_pos) //1
+ >
+ , SizeType
+ , (BoolFlags & hash_bool_flags::constant_time_size_pos) != 0
+ >
{
- typedef hashtable_data_t
- < SizeType
- , BoolFlags & hashtable_data_bool_flags_mask
- , VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits> data_type;
-
+ typedef hashtable_size_traits_wrapper
+ < hashdata_internal
+ < ValueTraits
+ , VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual
+ , BucketTraits, SizeType
+ , BoolFlags & (hash_bool_flags::incremental_pos | hash_bool_flags::cache_begin_pos) //1
+ >
+ , SizeType
+ , (BoolFlags & hash_bool_flags::constant_time_size_pos) != 0
+ > internal_type;
+ typedef typename internal_type::size_traits size_traits;
+ typedef hash_key_types_base
+ < typename ValueTraits::value_type
+ , VoidOrKeyOfValue
+ > hash_types_base;
public:
typedef ValueTraits value_traits;
/// @cond
typedef BucketTraits bucket_traits;
- typedef typename detail::get_slist_impl
- <typename detail::reduced_slist_node_traits
- <typename value_traits::node_traits>::type
- >::type slist_impl;
+ typedef typename internal_type::slist_impl slist_impl;
typedef bucket_plus_vtraits<ValueTraits, BucketTraits> bucket_plus_vtraits_t;
typedef typename bucket_plus_vtraits_t::const_value_traits_ptr const_value_traits_ptr;
+ using internal_type::begin;
+ using internal_type::cbegin;
+ using internal_type::end;
+ using internal_type::cend;
+ using internal_type::hash_function;
+ using internal_type::key_eq;
+ using internal_type::bucket_size;
+ using internal_type::bucket_count;
+ using internal_type::local_iterator_to;
+ using internal_type::s_local_iterator_to;
+ using internal_type::iterator_to;
+ using internal_type::bucket_pointer;
+ using internal_type::suggested_upper_bucket_count;
+ using internal_type::suggested_lower_bucket_count;
+ using internal_type::split_count;
/// @endcond
typedef typename value_traits::pointer pointer;
typedef typename value_traits::const_pointer const_pointer;
typedef typename value_traits::value_type value_type;
+ typedef typename hash_types_base::key_type key_type;
+ typedef typename hash_types_base::key_of_value key_of_value;
typedef typename pointer_traits<pointer>::reference reference;
typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef typename pointer_traits<pointer>::difference_type difference_type;
typedef SizeType size_type;
- typedef value_type key_type;
- typedef typename data_type::value_equal key_equal;
- typedef typename data_type::value_equal value_equal;
- typedef typename data_type::hasher hasher;
+ typedef typename internal_type::key_equal key_equal;
+ typedef typename internal_type::hasher hasher;
typedef detail::bucket_impl<slist_impl> bucket_type;
- typedef typename pointer_traits
- <pointer>::template rebind_pointer
- < bucket_type >::type bucket_ptr;
- typedef typename pointer_traits
- <pointer>::template rebind_pointer
- < const bucket_type >::type const_bucket_ptr;
- typedef typename pointer_traits
- <bucket_ptr>::reference bucket_reference;
- typedef typename pointer_traits
- <bucket_ptr>::reference const_bucket_reference;
+ typedef typename internal_type::bucket_ptr bucket_ptr;
typedef typename slist_impl::iterator siterator;
typedef typename slist_impl::const_iterator const_siterator;
- typedef hashtable_iterator<bucket_plus_vtraits_t, false> iterator;
- typedef hashtable_iterator<bucket_plus_vtraits_t, true> const_iterator;
+ typedef typename internal_type::iterator iterator;
+ typedef typename internal_type::const_iterator const_iterator;
+ typedef typename internal_type::local_iterator local_iterator;
+ typedef typename internal_type::const_local_iterator const_local_iterator;
typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename pointer_traits
@@ -1244,8 +1640,8 @@ class hashtable_impl
<const_node_ptr>::reference const_node_reference;
typedef typename slist_impl::node_algorithms node_algorithms;
- static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
- static const bool store_hash = detail::store_hash_is_true<node_traits>::value;
+ static const bool stateful_value_traits = internal_type::stateful_value_traits;
+ static const bool store_hash = internal_type::store_hash;
static const bool unique_keys = 0 != (BoolFlags & hash_bool_flags::unique_keys_pos);
static const bool constant_time_size = 0 != (BoolFlags & hash_bool_flags::constant_time_size_pos);
@@ -1258,6 +1654,7 @@ class hashtable_impl
= detail::optimize_multikey_is_true<node_traits>::value && !unique_keys;
/// @cond
+ static const bool is_multikey = !unique_keys;
private:
//Configuration error: compare_hash<> can't be specified without store_hash<>
@@ -1272,12 +1669,11 @@ class hashtable_impl
//optimize_multikey is not true
typedef unordered_group_adapter<node_traits> group_traits;
typedef circular_slist_algorithms<group_traits> group_algorithms;
- typedef detail::bool_<store_hash> store_hash_t;
+ typedef typename internal_type::store_hash_t store_hash_t;
typedef detail::bool_<optimize_multikey> optimize_multikey_t;
typedef detail::bool_<cache_begin> cache_begin_t;
typedef detail::bool_<power_2_buckets> power_2_buckets_t;
- typedef detail::size_holder<constant_time_size, size_type> size_traits;
- typedef detail::size_holder<incremental, size_type, int> split_traits;
+ typedef typename internal_type::split_traits split_traits;
typedef detail::group_functions<node_traits> group_functions_t;
typedef detail::node_functions<node_traits> node_functions_t;
@@ -1285,7 +1681,7 @@ class hashtable_impl
//noncopyable, movable
BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable_impl)
- static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
+ static const bool safemode_or_autounlink = internal_type::safemode_or_autounlink;
//Constant-time size is incompatible with auto-unlink hooks!
BOOST_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink)));
@@ -1293,14 +1689,19 @@ class hashtable_impl
BOOST_STATIC_ASSERT(!(cache_begin && ((int)value_traits::link_mode == (int)auto_unlink)));
template<class Disposer>
- node_cast_adaptor< detail::node_disposer<Disposer, value_traits, CircularSListAlgorithms>
- , slist_node_ptr, node_ptr >
+ struct typeof_node_disposer
+ {
+ typedef node_cast_adaptor
+ < detail::node_disposer< Disposer, value_traits, CircularSListAlgorithms>
+ , slist_node_ptr, node_ptr > type;
+ };
+
+ template<class Disposer>
+ typename typeof_node_disposer<Disposer>::type
make_node_disposer(const Disposer &disposer) const
{
- return node_cast_adaptor
- < detail::node_disposer<Disposer, value_traits, CircularSListAlgorithms>
- , slist_node_ptr, node_ptr >
- (disposer, &this->priv_value_traits());
+ typedef typename typeof_node_disposer<Disposer>::type return_t;
+ return return_t(disposer, &this->priv_value_traits());
}
/// @endcond
@@ -1308,17 +1709,6 @@ class hashtable_impl
public:
typedef detail::insert_commit_data_impl insert_commit_data;
- typedef detail::transform_iterator
- < typename slist_impl::iterator
- , downcast_node_to_value_t
- < value_traits
- , false> > local_iterator;
-
- typedef detail::transform_iterator
- < typename slist_impl::iterator
- , downcast_node_to_value_t
- < value_traits
- , true> > const_local_iterator;
public:
@@ -1339,9 +1729,42 @@ class hashtable_impl
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
, const value_traits &v_traits = value_traits())
- : data_type(b_traits, hash_func, equal_func, v_traits)
+ : internal_type(v_traits, b_traits, hash_func, equal_func)
{
- this->data_type::internal.priv_initialize_buckets_and_cache();
+ this->priv_initialize_buckets_and_cache();
+ this->priv_size_traits().set_size(size_type(0));
+ size_type bucket_sz = this->priv_bucket_count();
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(bucket_sz != 0);
+ //Check power of two bucket array if the option is activated
+ BOOST_INTRUSIVE_INVARIANT_ASSERT
+ (!power_2_buckets || (0 == (bucket_sz & (bucket_sz-1))));
+ this->priv_split_traits().set_size(bucket_sz>>1);
+ }
+
+ //! <b>Requires</b>: buckets must not be being used by any other resource
+ //! and dereferencing iterator must yield an lvalue of type value_type.
+ //!
+ //! <b>Effects</b>: Constructs an empty container and inserts elements from
+ //! [b, e).
+ //!
+ //! <b>Complexity</b>: If N is distance(b, e): Average case is O(N)
+ //! (with a good hash function and with buckets_len >= N),worst case O(N^2).
+ //!
+ //! <b>Throws</b>: If value_traits::node_traits::node
+ //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+ //! or the copy constructor or invocation of hasher or key_equal throws.
+ //!
+ //! <b>Notes</b>: buckets array must be disposed only after
+ //! *this is disposed.
+ template<class Iterator>
+ hashtable_impl ( bool unique, Iterator b, Iterator e
+ , const bucket_traits &b_traits
+ , const hasher & hash_func = hasher()
+ , const key_equal &equal_func = key_equal()
+ , const value_traits &v_traits = value_traits())
+ : internal_type(v_traits, b_traits, hash_func, equal_func)
+ {
+ this->priv_initialize_buckets_and_cache();
this->priv_size_traits().set_size(size_type(0));
size_type bucket_sz = this->priv_bucket_count();
BOOST_INTRUSIVE_INVARIANT_ASSERT(bucket_sz != 0);
@@ -1349,16 +1772,21 @@ class hashtable_impl
BOOST_INTRUSIVE_INVARIANT_ASSERT
(!power_2_buckets || (0 == (bucket_sz & (bucket_sz-1))));
this->priv_split_traits().set_size(bucket_sz>>1);
+ //Now insert
+ if(unique)
+ this->insert_unique(b, e);
+ else
+ this->insert_equal(b, e);
}
//! <b>Effects</b>: to-do
//!
hashtable_impl(BOOST_RV_REF(hashtable_impl) x)
- : data_type( ::boost::move(x.priv_bucket_traits())
- , ::boost::move(x.priv_hasher())
- , ::boost::move(x.priv_equal())
- , ::boost::move(x.priv_value_traits())
- )
+ : internal_type( ::boost::move(x.priv_value_traits())
+ , ::boost::move(x.priv_bucket_traits())
+ , ::boost::move(x.priv_hasher())
+ , ::boost::move(x.priv_equal())
+ )
{
this->priv_swap_cache(x);
x.priv_initialize_cache();
@@ -1387,7 +1815,6 @@ class hashtable_impl
//!
//! <b>Throws</b>: Nothing.
~hashtable_impl();
- #endif
//! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_set.
//!
@@ -1395,8 +1822,7 @@ class hashtable_impl
//! Worst case (empty unordered_set): O(this->bucket_count())
//!
//! <b>Throws</b>: Nothing.
- iterator begin()
- { return iterator(this->priv_begin(), &this->get_bucket_value_traits()); }
+ iterator begin();
//! <b>Effects</b>: Returns a const_iterator pointing to the beginning
//! of the unordered_set.
@@ -1405,8 +1831,7 @@ class hashtable_impl
//! Worst case (empty unordered_set): O(this->bucket_count())
//!
//! <b>Throws</b>: Nothing.
- const_iterator begin() const
- { return this->cbegin(); }
+ const_iterator begin() const;
//! <b>Effects</b>: Returns a const_iterator pointing to the beginning
//! of the unordered_set.
@@ -1415,48 +1840,44 @@ class hashtable_impl
//! Worst case (empty unordered_set): O(this->bucket_count())
//!
//! <b>Throws</b>: Nothing.
- const_iterator cbegin() const
- { return const_iterator(this->priv_begin(), &this->get_bucket_value_traits()); }
+ const_iterator cbegin() const;
//! <b>Effects</b>: Returns an iterator pointing to the end of the unordered_set.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- iterator end()
- { return iterator(this->priv_invalid_local_it(), 0); }
+ iterator end();
//! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- const_iterator end() const
- { return this->cend(); }
+ const_iterator end() const;
//! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- const_iterator cend() const
- { return const_iterator(this->priv_invalid_local_it(), 0); }
+ const_iterator cend() const;
//! <b>Effects</b>: Returns the hasher object used by the unordered_set.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: If hasher copy-constructor throws.
- hasher hash_function() const
- { return this->priv_hasher(); }
+ hasher hash_function() const;
//! <b>Effects</b>: Returns the key_equal object used by the unordered_set.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: If key_equal copy-constructor throws.
- key_equal key_eq() const
- { return this->priv_equal(); }
+ key_equal key_eq() const;
+
+ #endif
//! <b>Effects</b>: Returns true if the container is empty.
//!
@@ -1525,16 +1946,8 @@ class hashtable_impl
::boost::adl_move_swap(this->priv_bucket_traits(), other.priv_bucket_traits());
::boost::adl_move_swap(this->priv_value_traits(), other.priv_value_traits());
this->priv_swap_cache(other);
- if(constant_time_size){
- size_type backup = this->priv_size_traits().get_size();
- this->priv_size_traits().set_size(other.priv_size_traits().get_size());
- other.priv_size_traits().set_size(backup);
- }
- if(incremental){
- size_type backup = this->priv_split_traits().get_size();
- this->priv_split_traits().set_size(other.priv_split_traits().get_size());
- other.priv_split_traits().set_size(backup);
- }
+ ::boost::adl_move_swap(this->priv_size_traits(), other.priv_size_traits());
+ ::boost::adl_move_swap(this->priv_split_traits(), other.priv_split_traits());
}
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw
@@ -1558,87 +1971,30 @@ class hashtable_impl
//! throws. Basic guarantee.
template <class Cloner, class Disposer>
void clone_from(const hashtable_impl &src, Cloner cloner, Disposer disposer)
- {
- this->clear_and_dispose(disposer);
- if(!constant_time_size || !src.empty()){
- const size_type src_bucket_count = src.bucket_count();
- const size_type dst_bucket_count = this->bucket_count();
- //Check power of two bucket array if the option is activated
- BOOST_INTRUSIVE_INVARIANT_ASSERT
- (!power_2_buckets || (0 == (src_bucket_count & (src_bucket_count-1))));
- BOOST_INTRUSIVE_INVARIANT_ASSERT
- (!power_2_buckets || (0 == (dst_bucket_count & (dst_bucket_count-1))));
+ { this->priv_clone_from(src, cloner, disposer); }
- //If src bucket count is bigger or equal, structural copy is possible
- if(!incremental && (src_bucket_count >= dst_bucket_count)){
- //First clone the first ones
- const bucket_ptr src_buckets = src.priv_bucket_pointer();
- const bucket_ptr dst_buckets = this->priv_bucket_pointer();
- size_type constructed;
-
- typedef node_cast_adaptor< detail::node_disposer<Disposer, value_traits, CircularSListAlgorithms>
- , slist_node_ptr, node_ptr > NodeDisposer;
- typedef node_cast_adaptor< detail::node_cloner <Cloner, value_traits, CircularSListAlgorithms>
- , slist_node_ptr, node_ptr > NodeCloner;
- NodeDisposer node_disp(disposer, &this->priv_value_traits());
-
- detail::exception_array_disposer<bucket_type, NodeDisposer, size_type>
- rollback(dst_buckets[0], node_disp, constructed);
- for( constructed = 0
- ; constructed < dst_bucket_count
- ; ++constructed){
- dst_buckets[constructed].clone_from
- ( src_buckets[constructed]
- , NodeCloner(cloner, &this->priv_value_traits()), node_disp);
- }
- if(src_bucket_count != dst_bucket_count){
- //Now insert the remaining ones using the modulo trick
- for(//"constructed" comes from the previous loop
- ; constructed < src_bucket_count
- ; ++constructed){
- bucket_type &dst_b =
- dst_buckets[detail::hash_to_bucket_split<power_2_buckets, incremental>(constructed, dst_bucket_count, dst_bucket_count)];
- bucket_type &src_b = src_buckets[constructed];
- for( siterator b(src_b.begin()), e(src_b.end())
- ; b != e
- ; ++b){
- dst_b.push_front(*(NodeCloner(cloner, &this->priv_value_traits())(*b.pointed_node())));
- }
- }
- }
- this->priv_hasher() = src.priv_hasher();
- this->priv_equal() = src.priv_equal();
- rollback.release();
- this->priv_size_traits().set_size(src.priv_size_traits().get_size());
- this->priv_split_traits().set_size(dst_bucket_count);
- this->priv_insertion_update_cache(0u);
- this->priv_erasure_update_cache();
- }
- else if(store_hash){
- //Unlike previous cloning algorithm, this can throw
- //if cloner, hasher or comparison functor throw
- const_iterator b(src.cbegin()), e(src.cend());
- detail::exception_disposer<hashtable_impl, Disposer>
- rollback(*this, disposer);
- for(; b != e; ++b){
- std::size_t hash_value = this->priv_stored_or_compute_hash(*b, store_hash_t());;
- this->priv_insert_equal_with_hash(*cloner(*b), hash_value);
- }
- rollback.release();
- }
- else{
- //Unlike previous cloning algorithm, this can throw
- //if cloner, hasher or comparison functor throw
- const_iterator b(src.cbegin()), e(src.cend());
- detail::exception_disposer<hashtable_impl, Disposer>
- rollback(*this, disposer);
- for(; b != e; ++b){
- this->insert_equal(*cloner(*b));
- }
- rollback.release();
- }
- }
- }
+ //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw
+ //! Cloner should yield to nodes that compare equal and produce the same
+ //! hash than the original node.
+ //!
+ //! <b>Effects</b>: Erases all the elements from *this
+ //! calling Disposer::operator()(pointer), clones all the
+ //! elements from src calling Cloner::operator()(reference)
+ //! and inserts them on *this. The hash function and the equality
+ //! predicate are copied from the source.
+ //!
+ //! If store_hash option is true, this method does not use the hash function.
+ //!
+ //! If any operation throws, all cloned elements are unlinked and disposed
+ //! calling Disposer::operator()(pointer).
+ //!
+ //! <b>Complexity</b>: Linear to erased plus inserted elements.
+ //!
+ //! <b>Throws</b>: If cloner or hasher throw or hash or equality predicate copying
+ //! throws. Basic guarantee.
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(hashtable_impl) src, Cloner cloner, Disposer disposer)
+ { this->priv_clone_from(static_cast<hashtable_impl&>(src), cloner, disposer); }
//! <b>Requires</b>: value must be an lvalue
//!
@@ -1657,9 +2013,10 @@ class hashtable_impl
size_type bucket_num;
std::size_t hash_value;
siterator prev;
- siterator it = this->priv_find
- (value, this->priv_hasher(), this->priv_equal(), bucket_num, hash_value, prev);
- return this->priv_insert_equal_find(value, bucket_num, hash_value, it);
+ siterator const it = this->priv_find
+ (key_of_value()(value), this->priv_hasher(), this->priv_equal(), bucket_num, hash_value, prev);
+ bool const next_is_in_group = optimize_multikey && it != this->priv_invalid_local_it();
+ return this->priv_insert_equal_after_find(value, bucket_num, hash_value, prev, next_is_in_group);
}
//! <b>Requires</b>: Dereferencing iterator must yield an lvalue
@@ -1701,11 +2058,11 @@ class hashtable_impl
{
insert_commit_data commit_data;
std::pair<iterator, bool> ret = this->insert_unique_check
- (value, this->priv_hasher(), this->priv_equal(), commit_data);
- if(!ret.second)
- return ret;
- return std::pair<iterator, bool>
- (this->insert_unique_commit(value, commit_data), true);
+ (key_of_value()(value), this->priv_hasher(), this->priv_equal(), commit_data);
+ if(ret.second){
+ ret.first = this->insert_unique_commit(value, commit_data);
+ }
+ return ret;
}
//! <b>Requires</b>: Dereferencing iterator must yield an lvalue
@@ -1762,22 +2119,19 @@ class hashtable_impl
//! objects are inserted or erased from the unordered_set.
//!
//! After a successful rehashing insert_commit_data remains valid.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
+ template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<iterator, bool> insert_unique_check
( const KeyType &key
, KeyHasher hash_func
- , KeyValueEqual equal_func
+ , KeyEqual equal_func
, insert_commit_data &commit_data)
{
size_type bucket_num;
siterator prev;
- siterator prev_pos =
- this->priv_find(key, hash_func, equal_func, bucket_num, commit_data.hash, prev);
- bool success = prev_pos == this->priv_invalid_local_it();
- if(success){
- prev_pos = prev;
- }
- return std::pair<iterator, bool>(iterator(prev_pos, &this->get_bucket_value_traits()),success);
+ siterator const pos = this->priv_find(key, hash_func, equal_func, bucket_num, commit_data.hash, prev);
+ return std::pair<iterator, bool>
+ ( iterator(pos, &this->get_bucket_value_traits())
+ , pos == this->priv_invalid_local_it());
}
//! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
@@ -1804,12 +2158,11 @@ class hashtable_impl
size_type bucket_num = this->priv_hash_to_bucket(commit_data.hash);
bucket_type &b = this->priv_bucket_pointer()[bucket_num];
this->priv_size_traits().increment();
- node_ptr n = pointer_traits<node_ptr>::pointer_to(this->priv_value_to_node(value));
+ node_ptr const n = pointer_traits<node_ptr>::pointer_to(this->priv_value_to_node(value));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(n));
node_functions_t::store_hash(n, commit_data.hash, store_hash_t());
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
this->priv_insertion_update_cache(bucket_num);
- group_functions_t::insert_in_group(node_ptr(), n, optimize_multikey_t());
+ group_functions_t::insert_in_group(n, n, optimize_multikey_t());
return iterator(b.insert_after(b.before_begin(), *n), &this->get_bucket_value_traits());
}
@@ -1848,8 +2201,8 @@ class hashtable_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- size_type erase(const_reference value)
- { return this->erase(value, this->priv_hasher(), this->priv_equal()); }
+ size_type erase(const key_type &key)
+ { return this->erase(key, this->priv_hasher(), this->priv_equal()); }
//! <b>Requires</b>: "hash_func" must be a hash function that induces
//! the same hash values as the stored hasher. The difference is that
@@ -1871,8 +2224,8 @@ class hashtable_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- size_type erase(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ size_type erase(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func)
{ return this->erase_and_dispose(key, hash_func, equal_func, detail::null_disposer()); }
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1887,15 +2240,16 @@ class hashtable_impl
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class Disposer>
- void erase_and_dispose(const_iterator i, Disposer disposer
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0
- /// @endcond
- )
- {
- this->priv_erase(i, disposer, optimize_multikey_t());
+ BOOST_INTRUSIVE_DOC1ST(void
+ , typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
+ erase_and_dispose(const_iterator i, Disposer disposer)
+ {
+ //Get the bucket number and local iterator for both iterators
+ siterator const first_local_it(i.slist_it());
+ size_type const first_bucket_num = this->priv_get_bucket_num(first_local_it);
+ this->priv_erase_node(this->priv_bucket_pointer()[first_bucket_num], first_local_it, make_node_disposer(disposer), optimize_multikey_t());
this->priv_size_traits().decrement();
- this->priv_erasure_update_cache();
+ this->priv_erasure_update_cache_range(first_bucket_num, first_bucket_num);
}
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1934,7 +2288,10 @@ class hashtable_impl
last_local_it = e.slist_it();
last_bucket_num = this->priv_get_bucket_num(last_local_it);
}
- this->priv_erase_range(before_first_local_it, first_bucket_num, last_local_it, last_bucket_num, disposer);
+ size_type const num_erased = this->priv_erase_node_range
+ ( before_first_local_it, first_bucket_num, last_local_it, last_bucket_num
+ , make_node_disposer(disposer), optimize_multikey_t());
+ this->priv_size_traits().set_size(this->priv_size_traits().get_size()-num_erased);
this->priv_erasure_update_cache_range(first_bucket_num, last_bucket_num);
}
}
@@ -1955,8 +2312,8 @@ class hashtable_impl
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer)
- { return this->erase_and_dispose(value, this->priv_hasher(), this->priv_equal(), disposer); }
+ size_type erase_and_dispose(const key_type &key, Disposer disposer)
+ { return this->erase_and_dispose(key, this->priv_hasher(), this->priv_equal(), disposer); }
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//!
@@ -1973,45 +2330,37 @@ class hashtable_impl
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
- template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
+ template<class KeyType, class KeyHasher, class KeyEqual, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func
- ,KeyValueEqual equal_func, Disposer disposer)
+ ,KeyEqual equal_func, Disposer disposer)
{
size_type bucket_num;
std::size_t h;
siterator prev;
siterator it = this->priv_find(key, hash_func, equal_func, bucket_num, h, prev);
- bool success = it != this->priv_invalid_local_it();
+ bool const success = it != this->priv_invalid_local_it();
+
size_type cnt(0);
- if(!success){
- return 0;
- }
- else if(optimize_multikey){
- siterator last = bucket_type::s_iterator_to
- (*node_traits::get_next(group_functions_t::get_last_in_group
- (detail::dcast_bucket_ptr<node>(it.pointed_node()), optimize_multikey_t())));
- this->priv_erase_range_impl(bucket_num, prev, last, disposer, cnt);
- }
- else{
- //If found erase all equal values
- bucket_type &b = this->priv_bucket_pointer()[bucket_num];
- for(siterator end_sit = b.end(); it != end_sit; ++cnt, ++it){
- slist_node_ptr n(it.pointed_node());
- const value_type &v = this->priv_value_from_slist_node(n);
- if(compare_hash){
- std::size_t vh = this->priv_stored_or_compute_hash(v, store_hash_t());
- if(h != vh || !equal_func(key, v)){
- break;
- }
- }
- else if(!equal_func(key, v)){
- break;
- }
- this->priv_size_traits().decrement();
+ if(success){
+ if(optimize_multikey){
+ cnt = this->priv_erase_from_single_bucket
+ (this->priv_bucket_pointer()[bucket_num], prev, ++(priv_last_in_group)(it), make_node_disposer(disposer), optimize_multikey_t());
}
- b.erase_after_and_dispose(prev, it, make_node_disposer(disposer));
+ else{
+ bucket_type &b = this->priv_bucket_pointer()[bucket_num];
+ siterator const end_sit = b.end();
+ do{
+ ++cnt;
+ ++it;
+ }while(it != end_sit &&
+ this->priv_is_value_equal_to_key
+ (this->priv_value_from_slist_node(it.pointed_node()), h, key, equal_func));
+ bucket_type::s_erase_after_and_dispose(prev, it, make_node_disposer(disposer));
+ }
+ this->priv_size_traits().set_size(this->priv_size_traits().get_size()-cnt);
+ this->priv_erasure_update_cache();
}
- this->priv_erasure_update_cache();
+
return cnt;
}
@@ -2026,7 +2375,7 @@ class hashtable_impl
//! to the erased elements. No destructors are called.
void clear()
{
- this->data_type::internal.priv_clear_buckets_and_cache();
+ this->priv_clear_buckets_and_cache();
this->priv_size_traits().set_size(size_type(0));
}
@@ -2047,8 +2396,9 @@ class hashtable_impl
if(!constant_time_size || !this->empty()){
size_type num_buckets = this->bucket_count();
bucket_ptr b = this->priv_bucket_pointer();
+ typename typeof_node_disposer<Disposer>::type d(disposer, &this->priv_value_traits());
for(; num_buckets--; ++b){
- b->clear_and_dispose(make_node_disposer(disposer));
+ b->clear_and_dispose(d);
}
this->priv_size_traits().set_size(size_type(0));
}
@@ -2060,8 +2410,8 @@ class hashtable_impl
//! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
//!
//! <b>Throws</b>: If the internal hasher or the equality functor throws.
- size_type count(const_reference value) const
- { return this->count(value, this->priv_hasher(), this->priv_equal()); }
+ size_type count(const key_type &key) const
+ { return this->count(key, this->priv_hasher(), this->priv_equal()); }
//! <b>Requires</b>: "hash_func" must be a hash function that induces
//! the same hash values as the stored hasher. The difference is that
@@ -2076,11 +2426,12 @@ class hashtable_impl
//! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
//!
//! <b>Throws</b>: If hash_func or equal throw.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- size_type count(const KeyType &key, const KeyHasher &hash_func, const KeyValueEqual &equal_func) const
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ size_type count(const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) const
{
- size_type bucket_n1, bucket_n2, cnt;
- this->priv_equal_range(key, hash_func, equal_func, bucket_n1, bucket_n2, cnt);
+ size_type cnt;
+ size_type n_bucket;
+ this->priv_local_equal_range(key, hash_func, equal_func, n_bucket, cnt);
return cnt;
}
@@ -2090,8 +2441,8 @@ class hashtable_impl
//! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
//!
//! <b>Throws</b>: If the internal hasher or the equality functor throws.
- iterator find(const_reference value)
- { return this->find(value, this->priv_hasher(), this->priv_equal()); }
+ iterator find(const key_type &key)
+ { return this->find(key, this->priv_hasher(), this->priv_equal()); }
//! <b>Requires</b>: "hash_func" must be a hash function that induces
//! the same hash values as the stored hasher. The difference is that
@@ -2112,14 +2463,14 @@ class hashtable_impl
//! <b>Note</b>: This function is used when constructing a value_type
//! is expensive and the value_type can be compared with a cheaper
//! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- iterator find(const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ iterator find(const KeyType &key, KeyHasher hash_func, KeyEqual equal_func)
{
size_type bucket_n;
std::size_t hash;
siterator prev;
- siterator local_it = this->priv_find(key, hash_func, equal_func, bucket_n, hash, prev);
- return iterator(local_it, &this->get_bucket_value_traits());
+ return iterator( this->priv_find(key, hash_func, equal_func, bucket_n, hash, prev)
+ , &this->get_bucket_value_traits());
}
//! <b>Effects</b>: Finds a const_iterator to the first element whose key is
@@ -2128,8 +2479,8 @@ class hashtable_impl
//! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
//!
//! <b>Throws</b>: If the internal hasher or the equality functor throws.
- const_iterator find(const_reference value) const
- { return this->find(value, this->priv_hasher(), this->priv_equal()); }
+ const_iterator find(const key_type &key) const
+ { return this->find(key, this->priv_hasher(), this->priv_equal()); }
//! <b>Requires</b>: "hash_func" must be a hash function that induces
//! the same hash values as the stored hasher. The difference is that
@@ -2150,15 +2501,15 @@ class hashtable_impl
//! <b>Note</b>: This function is used when constructing a value_type
//! is expensive and the value_type can be compared with a cheaper
//! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
+ template<class KeyType, class KeyHasher, class KeyEqual>
const_iterator find
- (const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func) const
+ (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) const
{
size_type bucket_n;
std::size_t hash_value;
siterator prev;
- siterator sit = this->priv_find(key, hash_func, equal_func, bucket_n, hash_value, prev);
- return const_iterator(sit, &this->get_bucket_value_traits());
+ return const_iterator( this->priv_find(key, hash_func, equal_func, bucket_n, hash_value, prev)
+ , &this->get_bucket_value_traits());
}
//! <b>Effects</b>: Returns a range containing all elements with values equivalent
@@ -2168,8 +2519,8 @@ class hashtable_impl
//! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
//!
//! <b>Throws</b>: If the internal hasher or the equality functor throws.
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->equal_range(value, this->priv_hasher(), this->priv_equal()); }
+ std::pair<iterator,iterator> equal_range(const key_type &key)
+ { return this->equal_range(key, this->priv_hasher(), this->priv_equal()); }
//! <b>Requires</b>: "hash_func" must be a hash function that induces
//! the same hash values as the stored hasher. The difference is that
@@ -2191,15 +2542,15 @@ class hashtable_impl
//! <b>Note</b>: This function is used when constructing a value_type
//! is expensive and the value_type can be compared with a cheaper
//! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
+ template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<iterator,iterator> equal_range
- (const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func)
+ (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func)
{
- size_type bucket_n1, bucket_n2, cnt;
- std::pair<siterator, siterator> ret = this->priv_equal_range
- (key, hash_func, equal_func, bucket_n1, bucket_n2, cnt);
+ std::pair<siterator, siterator> ret =
+ this->priv_equal_range(key, hash_func, equal_func);
return std::pair<iterator, iterator>
- (iterator(ret.first, &this->get_bucket_value_traits()), iterator(ret.second, &this->get_bucket_value_traits()));
+ ( iterator(ret.first, &this->get_bucket_value_traits())
+ , iterator(ret.second, &this->get_bucket_value_traits()));
}
//! <b>Effects</b>: Returns a range containing all elements with values equivalent
@@ -2210,8 +2561,8 @@ class hashtable_impl
//!
//! <b>Throws</b>: If the internal hasher or the equality functor throws.
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->equal_range(value, this->priv_hasher(), this->priv_equal()); }
+ equal_range(const key_type &key) const
+ { return this->equal_range(key, this->priv_hasher(), this->priv_equal()); }
//! <b>Requires</b>: "hash_func" must be a hash function that induces
//! the same hash values as the stored hasher. The difference is that
@@ -2233,18 +2584,19 @@ class hashtable_impl
//! <b>Note</b>: This function is used when constructing a value_type
//! is expensive and the value_type can be compared with a cheaper
//! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
+ template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<const_iterator,const_iterator> equal_range
- (const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func) const
+ (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) const
{
- size_type bucket_n1, bucket_n2, cnt;
std::pair<siterator, siterator> ret =
- this->priv_equal_range(key, hash_func, equal_func, bucket_n1, bucket_n2, cnt);
+ this->priv_equal_range(key, hash_func, equal_func);
return std::pair<const_iterator, const_iterator>
( const_iterator(ret.first, &this->get_bucket_value_traits())
, const_iterator(ret.second, &this->get_bucket_value_traits()));
}
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+
//! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
//! appropriate type. Otherwise the behavior is undefined.
//!
@@ -2254,11 +2606,7 @@ class hashtable_impl
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: If the internal hash function throws.
- iterator iterator_to(reference value)
- {
- return iterator(bucket_type::s_iterator_to
- (this->priv_value_to_node(value)), &this->get_bucket_value_traits());
- }
+ iterator iterator_to(reference value);
//! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
//! appropriate type. Otherwise the behavior is undefined.
@@ -2269,13 +2617,7 @@ class hashtable_impl
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: If the internal hash function throws.
- const_iterator iterator_to(const_reference value) const
- {
- node_reference r = *pointer_traits<node_ptr>::const_cast_from
- (pointer_traits<const_node_ptr>::pointer_to(this->priv_value_to_node(value)));
- siterator sit = bucket_type::s_iterator_to(r);
- return const_iterator(sit, &this->get_bucket_value_traits());
- }
+ const_iterator iterator_to(const_reference value) const;
//! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
//! appropriate type. Otherwise the behavior is undefined.
@@ -2289,12 +2631,7 @@ class hashtable_impl
//!
//! <b>Note</b>: This static function is available only if the <i>value traits</i>
//! is stateless.
- static local_iterator s_local_iterator_to(reference value)
- {
- BOOST_STATIC_ASSERT((!stateful_value_traits));
- siterator sit = bucket_type::s_iterator_to(*value_traits::to_node_ptr(value));
- return local_iterator(sit, const_value_traits_ptr());
- }
+ static local_iterator s_local_iterator_to(reference value);
//! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
//! appropriate type. Otherwise the behavior is undefined.
@@ -2308,14 +2645,7 @@ class hashtable_impl
//!
//! <b>Note</b>: This static function is available only if the <i>value traits</i>
//! is stateless.
- static const_local_iterator s_local_iterator_to(const_reference value)
- {
- BOOST_STATIC_ASSERT((!stateful_value_traits));
- node_reference r = *pointer_traits<node_ptr>::const_cast_from
- (value_traits::to_node_ptr(value));
- siterator sit = bucket_type::s_iterator_to(r);
- return const_local_iterator(sit, const_value_traits_ptr());
- }
+ static const_local_iterator s_local_iterator_to(const_reference value);
//! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
//! appropriate type. Otherwise the behavior is undefined.
@@ -2326,11 +2656,7 @@ class hashtable_impl
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- local_iterator local_iterator_to(reference value)
- {
- siterator sit = bucket_type::s_iterator_to(this->priv_value_to_node(value));
- return local_iterator(sit, this->priv_value_traits_ptr());
- }
+ local_iterator local_iterator_to(reference value);
//! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
//! appropriate type. Otherwise the behavior is undefined.
@@ -2341,13 +2667,7 @@ class hashtable_impl
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- const_local_iterator local_iterator_to(const_reference value) const
- {
- node_reference r = *pointer_traits<node_ptr>::const_cast_from
- (pointer_traits<const_node_ptr>::pointer_to(this->priv_value_to_node(value)));
- siterator sit = bucket_type::s_iterator_to(r);
- return const_local_iterator(sit, this->priv_value_traits_ptr());
- }
+ const_local_iterator local_iterator_to(const_reference value) const;
//! <b>Effects</b>: Returns the number of buckets passed in the constructor
//! or the last rehash function.
@@ -2355,8 +2675,7 @@ class hashtable_impl
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- size_type bucket_count() const
- { return this->priv_bucket_count(); }
+ size_type bucket_count() const;
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
//!
@@ -2365,8 +2684,8 @@ class hashtable_impl
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- size_type bucket_size(size_type n) const
- { return this->priv_bucket_pointer()[n].size(); }
+ size_type bucket_size(size_type n) const;
+ #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Effects</b>: Returns the index of the bucket in which elements
//! with keys equivalent to k would be found, if any such element existed.
@@ -2392,17 +2711,17 @@ class hashtable_impl
//!
//! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
template<class KeyType, class KeyHasher>
- size_type bucket(const KeyType& k, const KeyHasher &hash_func) const
+ size_type bucket(const KeyType& k, KeyHasher hash_func) const
{ return this->priv_hash_to_bucket(hash_func(k)); }
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
//! or the last rehash function.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- bucket_ptr bucket_pointer() const
- { return this->priv_bucket_pointer(); }
+ bucket_ptr bucket_pointer() const;
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
//!
@@ -2415,8 +2734,7 @@ class hashtable_impl
//!
//! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
//! containing all of the elements in the nth bucket.
- local_iterator begin(size_type n)
- { return local_iterator(this->priv_bucket_pointer()[n].begin(), this->priv_value_traits_ptr()); }
+ local_iterator begin(size_type n);
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
//!
@@ -2429,8 +2747,7 @@ class hashtable_impl
//!
//! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
//! containing all of the elements in the nth bucket.
- const_local_iterator begin(size_type n) const
- { return this->cbegin(n); }
+ const_local_iterator begin(size_type n) const;
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
//!
@@ -2443,11 +2760,7 @@ class hashtable_impl
//!
//! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
//! containing all of the elements in the nth bucket.
- const_local_iterator cbegin(size_type n) const
- {
- bucket_reference br = pointer_traits<bucket_ptr>::const_cast_from(this->priv_bucket_pointer())[n];
- return const_local_iterator(br.begin(), this->priv_value_traits_ptr());
- }
+ const_local_iterator cbegin(size_type n) const;
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
//!
@@ -2460,8 +2773,7 @@ class hashtable_impl
//!
//! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
//! containing all of the elements in the nth bucket.
- local_iterator end(size_type n)
- { return local_iterator(this->priv_bucket_pointer()[n].end(), this->priv_value_traits_ptr()); }
+ local_iterator end(size_type n);
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
//!
@@ -2474,8 +2786,7 @@ class hashtable_impl
//!
//! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
//! containing all of the elements in the nth bucket.
- const_local_iterator end(size_type n) const
- { return this->cend(n); }
+ const_local_iterator end(size_type n) const;
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
//!
@@ -2488,11 +2799,8 @@ class hashtable_impl
//!
//! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
//! containing all of the elements in the nth bucket.
- const_local_iterator cend(size_type n) const
- {
- bucket_reference br = pointer_traits<bucket_ptr>::const_cast_from(this->priv_bucket_pointer())[n];
- return const_local_iterator ( br.end(), this->priv_value_traits_ptr());
- }
+ const_local_iterator cend(size_type n) const;
+ #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Requires</b>: new_bucket_traits can hold a pointer to a new bucket array
//! or the same as the old bucket array with a different length. new_size is the length of the
@@ -2520,36 +2828,33 @@ class hashtable_impl
//Check power of two bucket array if the option is activated
BOOST_INTRUSIVE_INVARIANT_ASSERT
- (!power_2_buckets || (0 == (new_bucket_count & (new_bucket_count-1u))));
+ (!power_2_buckets || (0 == (new_bucket_count & (new_bucket_count-1u))));
size_type n = this->priv_get_cache_bucket_num();
const bool same_buffer = old_buckets == new_buckets;
//If the new bucket length is a common factor
//of the old one we can avoid hash calculations.
- const bool fast_shrink = (!incremental) && (old_bucket_count > new_bucket_count) &&
- (power_2_buckets ||(old_bucket_count % new_bucket_count) == 0);
+ const bool fast_shrink = (!incremental) && (old_bucket_count >= new_bucket_count) &&
+ (power_2_buckets || (old_bucket_count % new_bucket_count) == 0);
//If we are shrinking the same bucket array and it's
//is a fast shrink, just rehash the last nodes
size_type new_first_bucket_num = new_bucket_count;
if(same_buffer && fast_shrink && (n < new_bucket_count)){
+ new_first_bucket_num = n;
n = new_bucket_count;
- new_first_bucket_num = this->priv_get_cache_bucket_num();
}
//Anti-exception stuff: they destroy the elements if something goes wrong.
//If the source and destination buckets are the same, the second rollback function
//is harmless, because all elements have been already unlinked and destroyed
typedef detail::init_disposer<node_algorithms> NodeDisposer;
+ typedef detail::exception_array_disposer<bucket_type, NodeDisposer, size_type> ArrayDisposer;
NodeDisposer node_disp;
- bucket_type & newbuck = new_buckets[0];
- bucket_type & oldbuck = old_buckets[0];
- detail::exception_array_disposer<bucket_type, NodeDisposer, size_type>
- rollback1(newbuck, node_disp, new_bucket_count);
- detail::exception_array_disposer<bucket_type, NodeDisposer, size_type>
- rollback2(oldbuck, node_disp, old_bucket_count);
+ ArrayDisposer rollback1(new_buckets[0], node_disp, new_bucket_count);
+ ArrayDisposer rollback2(old_buckets[0], node_disp, old_bucket_count);
//Put size in a safe value for rollback exception
- size_type size_backup = this->priv_size_traits().get_size();
+ size_type const size_backup = this->priv_size_traits().get_size();
this->priv_size_traits().set_size(0);
//Put cache to safe position
this->priv_initialize_cache();
@@ -2558,20 +2863,17 @@ class hashtable_impl
//Iterate through nodes
for(; n < old_bucket_count; ++n){
bucket_type &old_bucket = old_buckets[n];
-
if(!fast_shrink){
- siterator before_i(old_bucket.before_begin());
- siterator end_sit(old_bucket.end());
- siterator i(old_bucket.begin());
- for(;i != end_sit; ++i){
+ for( siterator before_i(old_bucket.before_begin()), i(old_bucket.begin()), end_sit(old_bucket.end())
+ ; i != end_sit
+ ; i = before_i, ++i){
const value_type &v = this->priv_value_from_slist_node(i.pointed_node());
const std::size_t hash_value = this->priv_stored_or_compute_hash(v, store_hash_t());
- const size_type new_n = detail::hash_to_bucket_split<power_2_buckets, incremental>(hash_value, new_bucket_count, new_bucket_count);
+ const size_type new_n = detail::hash_to_bucket_split<power_2_buckets, incremental>
+ (hash_value, new_bucket_count, new_bucket_count);
if(cache_begin && new_n < new_first_bucket_num)
new_first_bucket_num = new_n;
- siterator last = bucket_type::s_iterator_to
- (*group_functions_t::get_last_in_group
- (detail::dcast_bucket_ptr<node>(i.pointed_node()), optimize_multikey_t()));
+ siterator const last = (priv_last_in_group)(i);
if(same_buffer && new_n == n){
before_i = last;
}
@@ -2579,7 +2881,6 @@ class hashtable_impl
bucket_type &new_b = new_buckets[new_n];
new_b.splice_after(new_b.before_begin(), old_bucket, before_i, last);
}
- i = before_i;
}
}
else{
@@ -2587,12 +2888,10 @@ class hashtable_impl
if(cache_begin && new_n < new_first_bucket_num)
new_first_bucket_num = new_n;
bucket_type &new_b = new_buckets[new_n];
- if(!old_bucket.empty()){
- new_b.splice_after( new_b.before_begin()
- , old_bucket
- , old_bucket.before_begin()
- , hashtable_impl::priv_get_last(old_bucket));
- }
+ new_b.splice_after( new_b.before_begin()
+ , old_bucket
+ , old_bucket.before_begin()
+ , bucket_plus_vtraits_t::priv_get_last(old_bucket, optimize_multikey_t()));
}
}
@@ -2621,56 +2920,47 @@ class hashtable_impl
const size_type split_idx = this->priv_split_traits().get_size();
const size_type bucket_cnt = this->priv_bucket_count();
const bucket_ptr buck_ptr = this->priv_bucket_pointer();
+ bool ret = false;
if(grow){
//Test if the split variable can be changed
- if(split_idx >= bucket_cnt)
- return false;
-
- const size_type bucket_to_rehash = split_idx - bucket_cnt/2;
- bucket_type &old_bucket = buck_ptr[bucket_to_rehash];
- siterator before_i(old_bucket.before_begin());
- const siterator end_sit(old_bucket.end());
- siterator i(old_bucket.begin());
- this->priv_split_traits().increment();
-
- //Anti-exception stuff: if an exception is thrown while
- //moving elements from old_bucket to the target bucket, all moved
- //elements are moved back to the original one.
- detail::incremental_rehash_rollback<bucket_type, split_traits> rollback
- ( buck_ptr[split_idx], old_bucket, this->priv_split_traits());
- for(;i != end_sit; ++i){
- const value_type &v = this->priv_value_from_slist_node(i.pointed_node());
- const std::size_t hash_value = this->priv_stored_or_compute_hash(v, store_hash_t());
- const size_type new_n = this->priv_hash_to_bucket(hash_value);
- siterator last = bucket_type::s_iterator_to
- (*group_functions_t::get_last_in_group
- (detail::dcast_bucket_ptr<node>(i.pointed_node()), optimize_multikey_t()));
- if(new_n == bucket_to_rehash){
- before_i = last;
- }
- else{
- bucket_type &new_b = buck_ptr[new_n];
- new_b.splice_after(new_b.before_begin(), old_bucket, before_i, last);
+ if((ret = split_idx < bucket_cnt)){
+ const size_type bucket_to_rehash = split_idx - bucket_cnt/2;
+ bucket_type &old_bucket = buck_ptr[bucket_to_rehash];
+ this->priv_split_traits().increment();
+
+ //Anti-exception stuff: if an exception is thrown while
+ //moving elements from old_bucket to the target bucket, all moved
+ //elements are moved back to the original one.
+ detail::incremental_rehash_rollback<bucket_type, split_traits> rollback
+ ( buck_ptr[split_idx], old_bucket, this->priv_split_traits());
+ for( siterator before_i(old_bucket.before_begin()), i(old_bucket.begin()), end_sit(old_bucket.end())
+ ; i != end_sit; i = before_i, ++i){
+ const value_type &v = this->priv_value_from_slist_node(i.pointed_node());
+ const std::size_t hash_value = this->priv_stored_or_compute_hash(v, store_hash_t());
+ const size_type new_n = this->priv_hash_to_bucket(hash_value);
+ siterator const last = (priv_last_in_group)(i);
+ if(new_n == bucket_to_rehash){
+ before_i = last;
+ }
+ else{
+ bucket_type &new_b = buck_ptr[new_n];
+ new_b.splice_after(new_b.before_begin(), old_bucket, before_i, last);
+ }
}
- i = before_i;
+ rollback.release();
+ this->priv_erasure_update_cache();
}
- rollback.release();
- this->priv_erasure_update_cache();
- return true;
}
- else{
- //Test if the split variable can be changed
- if(split_idx <= bucket_cnt/2)
- return false;
+ else if((ret = split_idx > bucket_cnt/2)){ //!grow
const size_type target_bucket_num = split_idx - 1 - bucket_cnt/2;
bucket_type &target_bucket = buck_ptr[target_bucket_num];
bucket_type &source_bucket = buck_ptr[split_idx-1];
target_bucket.splice_after(target_bucket.cbefore_begin(), source_bucket);
this->priv_split_traits().decrement();
this->priv_insertion_update_cache(target_bucket_num);
- return true;
}
+ return ret;
}
//! <b>Effects</b>: If new_bucket_traits.bucket_count() is not
@@ -2690,24 +2980,22 @@ class hashtable_impl
{
//This function is only available for containers with incremental hashing
BOOST_STATIC_ASSERT(( incremental && power_2_buckets ));
- size_type new_bucket_traits_size = new_bucket_traits.bucket_count();
- size_type cur_bucket_traits = this->priv_bucket_count();
- if(new_bucket_traits_size/2 != cur_bucket_traits && new_bucket_traits_size != cur_bucket_traits/2){
- return false;
- }
-
+ size_type const new_bucket_traits_size = new_bucket_traits.bucket_count();
+ size_type const cur_bucket_traits = this->priv_bucket_count();
const size_type split_idx = this->split_count();
+ //Test new bucket size is consistent with internal bucket size and split count
if(new_bucket_traits_size/2 == cur_bucket_traits){
- //Test if the split variable can be changed
if(!(split_idx >= cur_bucket_traits))
return false;
}
- else{
- //Test if the split variable can be changed
- if(!(split_idx <= cur_bucket_traits/2))
+ else if(new_bucket_traits_size == cur_bucket_traits/2){
+ if(!(split_idx <= new_bucket_traits_size))
return false;
}
+ else{
+ return false;
+ }
const size_type ini_n = this->priv_get_cache_bucket_num();
const bucket_ptr old_buckets = this->priv_bucket_pointer();
@@ -2725,19 +3013,16 @@ class hashtable_impl
return true;
}
- //! <b>Requires</b>:
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+
+ //! <b>Requires</b>: incremental<> option must be set
//!
- //! <b>Effects</b>:
+ //! <b>Effects</b>: returns the current split count
//!
- //! <b>Complexity</b>:
+ //! <b>Complexity</b>: Constant
//!
- //! <b>Throws</b>:
- size_type split_count() const
- {
- //This function is only available if incremental hashing is activated
- BOOST_STATIC_ASSERT(( incremental && power_2_buckets ));
- return this->priv_split_traits().get_size();
- }
+ //! <b>Throws</b>: Nothing
+ size_type split_count() const;
//! <b>Effects</b>: Returns the nearest new bucket count optimized for
//! the container that is bigger or equal than n. This suggestion can be
@@ -2748,14 +3033,7 @@ class hashtable_impl
//! <b>Complexity</b>: Amortized constant time.
//!
//! <b>Throws</b>: Nothing.
- static size_type suggested_upper_bucket_count(size_type n)
- {
- const std::size_t *primes = &prime_list_holder<0>::prime_list[0];
- const std::size_t *primes_end = primes + prime_list_holder<0>::prime_list_size;
- std::size_t const* bound = std::lower_bound(primes, primes_end, n);
- bound -= (bound == primes_end);
- return size_type(*bound);
- }
+ static size_type suggested_upper_bucket_count(size_type n);
//! <b>Effects</b>: Returns the nearest new bucket count optimized for
//! the container that is smaller or equal than n. This suggestion can be
@@ -2766,403 +3044,306 @@ class hashtable_impl
//! <b>Complexity</b>: Amortized constant time.
//!
//! <b>Throws</b>: Nothing.
- static size_type suggested_lower_bucket_count(size_type n)
- {
- const std::size_t *primes = &prime_list_holder<0>::prime_list[0];
- const std::size_t *primes_end = primes + prime_list_holder<0>::prime_list_size;
- size_type const* bound = std::upper_bound(primes, primes_end, n);
- bound -= (bound != primes);
- return size_type(*bound);
- }
- /// @cond
- void check() const {}
- private:
- size_traits &priv_size_traits()
- { return static_cast<size_traits&>(static_cast<data_type&>(*this)); }
-
- const size_traits &priv_size_traits() const
- { return static_cast<const size_traits&>(static_cast<const data_type&>(*this)); }
-
- bucket_ptr priv_bucket_pointer() const
- { return this->data_type::internal.internal.internal.internal.priv_bucket_pointer(); }
-
- SizeType priv_bucket_count() const
- { return this->data_type::internal.internal.internal.internal.priv_bucket_count(); }
-
- const bucket_plus_vtraits<ValueTraits, BucketTraits> &get_bucket_value_traits() const
- { return this->data_type::internal.internal.internal.internal.get_bucket_value_traits(); }
-
- bucket_plus_vtraits<ValueTraits, BucketTraits> &get_bucket_value_traits()
- { return this->data_type::internal.internal.internal.internal.get_bucket_value_traits(); }
-
- bucket_traits &priv_bucket_traits()
- { return this->data_type::internal.internal.internal.internal.priv_bucket_traits(); }
+ static size_type suggested_lower_bucket_count(size_type n);
+ #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
- const bucket_traits &priv_bucket_traits() const
- { return this->data_type::internal.internal.internal.internal.priv_bucket_traits(); }
-
- value_traits &priv_value_traits()
- { return this->data_type::internal.internal.internal.internal.priv_value_traits(); }
-
- const value_traits &priv_value_traits() const
- { return this->data_type::internal.internal.internal.internal.priv_value_traits(); }
-
- const_value_traits_ptr priv_value_traits_ptr() const
- { return this->data_type::internal.internal.internal.internal.priv_value_traits_ptr(); }
-
- siterator priv_invalid_local_it() const
- { return this->data_type::internal.internal.internal.internal.priv_invalid_local_it(); }
-
- split_traits &priv_split_traits()
- { return this->data_type::internal.priv_split_traits(); }
-
- const split_traits &priv_split_traits() const
- { return this->data_type::internal.priv_split_traits(); }
- bucket_ptr priv_get_cache()
- { return this->data_type::internal.internal.priv_get_cache(); }
-
- void priv_initialize_cache()
- { return this->data_type::internal.internal.priv_initialize_cache(); }
-
- siterator priv_begin() const
- { return this->data_type::internal.internal.priv_begin(); }
-
- const value_equal &priv_equal() const
- { return this->data_type::internal.internal.priv_equal(); }
-
- value_equal &priv_equal()
- { return this->data_type::internal.internal.priv_equal(); }
-
- const hasher &priv_hasher() const
- { return this->data_type::internal.internal.internal.priv_hasher(); }
-
- hasher &priv_hasher()
- { return this->data_type::internal.internal.internal.priv_hasher(); }
-
- void priv_swap_cache(hashtable_impl &h)
- { this->data_type::internal.internal.priv_swap_cache(h.data_type::internal.internal); }
-
- node &priv_value_to_node(value_type &v)
- { return this->data_type::internal.internal.internal.internal.priv_value_to_node(v); }
-
- const node &priv_value_to_node(const value_type &v) const
- { return this->data_type::internal.internal.internal.internal.priv_value_to_node(v); }
-
- SizeType priv_get_cache_bucket_num()
- { return this->data_type::internal.internal.priv_get_cache_bucket_num(); }
-
- void priv_insertion_update_cache(SizeType n)
- { return this->data_type::internal.internal.priv_insertion_update_cache(n); }
-
- template<bool Boolean>
- std::size_t priv_stored_or_compute_hash(const value_type &v, detail::bool_<Boolean> b) const
- { return this->data_type::internal.internal.internal.priv_stored_or_compute_hash(v, b); }
-
- value_type &priv_value_from_slist_node(slist_node_ptr n)
- { return this->data_type::internal.internal.internal.internal.priv_value_from_slist_node(n); }
+ friend bool operator==(const hashtable_impl &x, const hashtable_impl &y)
+ {
+ //Taken from N3068
+ if(constant_time_size && x.size() != y.size()){
+ return false;
+ }
+ for (const_iterator ix = x.cbegin(), ex = x.cend(); ix != ex; ++ix){
+ std::pair<const_iterator, const_iterator> eqx(x.equal_range(key_of_value()(*ix))),
+ eqy(y.equal_range(key_of_value()(*ix)));
+ if (boost::intrusive::iterator_distance(eqx.first, eqx.second) !=
+ boost::intrusive::iterator_distance(eqy.first, eqy.second) ||
+ !(priv_algo_is_permutation)(eqx.first, eqx.second, eqy.first) ){
+ return false;
+ }
+ ix = eqx.second;
+ }
+ return true;
+ }
- const value_type &priv_value_from_slist_node(slist_node_ptr n) const
- { return this->data_type::internal.internal.internal.internal.priv_value_from_slist_node(n); }
+ friend bool operator!=(const hashtable_impl &x, const hashtable_impl &y)
+ { return !(x == y); }
- void priv_erasure_update_cache_range(SizeType first_bucket_num, SizeType last_bucket_num)
- { return this->data_type::internal.internal.priv_erasure_update_cache_range(first_bucket_num, last_bucket_num); }
+ friend bool operator<(const hashtable_impl &x, const hashtable_impl &y)
+ { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
- void priv_erasure_update_cache()
- { return this->data_type::internal.internal.priv_erasure_update_cache(); }
+ friend bool operator>(const hashtable_impl &x, const hashtable_impl &y)
+ { return y < x; }
- static std::size_t priv_stored_hash(slist_node_ptr n, detail::true_ true_value)
- { return bucket_plus_vtraits<ValueTraits, BucketTraits>::priv_stored_hash(n, true_value); }
+ friend bool operator<=(const hashtable_impl &x, const hashtable_impl &y)
+ { return !(y < x); }
- static std::size_t priv_stored_hash(slist_node_ptr n, detail::false_ false_value)
- { return bucket_plus_vtraits<ValueTraits, BucketTraits>::priv_stored_hash(n, false_value); }
+ friend bool operator>=(const hashtable_impl &x, const hashtable_impl &y)
+ { return !(x < y); }
- std::size_t priv_hash_to_bucket(std::size_t hash_value) const
- {
- return detail::hash_to_bucket_split<power_2_buckets, incremental>
- (hash_value, this->priv_bucket_traits().bucket_count(), this->priv_split_traits().get_size());
- }
+ /// @cond
+ void check() const {}
+ private:
- template<class Disposer>
- void priv_erase_range_impl
- (size_type bucket_num, siterator before_first_it, siterator end_sit, Disposer disposer, size_type &num_erased)
+ template <class MaybeConstHashtableImpl, class Cloner, class Disposer>
+ void priv_clone_from(MaybeConstHashtableImpl &src, Cloner cloner, Disposer disposer)
{
- const bucket_ptr buckets = this->priv_bucket_pointer();
- bucket_type &b = buckets[bucket_num];
-
- if(before_first_it == b.before_begin() && end_sit == b.end()){
- this->priv_erase_range_impl(bucket_num, 1, disposer, num_erased);
- }
- else{
- num_erased = 0;
- siterator to_erase(before_first_it);
- ++to_erase;
- slist_node_ptr end_ptr = end_sit.pointed_node();
- while(to_erase != end_sit){
- group_functions_t::erase_from_group(end_ptr, detail::dcast_bucket_ptr<node>(to_erase.pointed_node()), optimize_multikey_t());
- to_erase = b.erase_after_and_dispose(before_first_it, make_node_disposer(disposer));
- ++num_erased;
+ this->clear_and_dispose(disposer);
+ if(!constant_time_size || !src.empty()){
+ const size_type src_bucket_count = src.bucket_count();
+ const size_type dst_bucket_count = this->bucket_count();
+ //Check power of two bucket array if the option is activated
+ BOOST_INTRUSIVE_INVARIANT_ASSERT
+ (!power_2_buckets || (0 == (src_bucket_count & (src_bucket_count-1))));
+ BOOST_INTRUSIVE_INVARIANT_ASSERT
+ (!power_2_buckets || (0 == (dst_bucket_count & (dst_bucket_count-1))));
+ //If src bucket count is bigger or equal, structural copy is possible
+ const bool structural_copy = (!incremental) && (src_bucket_count >= dst_bucket_count) &&
+ (power_2_buckets || (src_bucket_count % dst_bucket_count) == 0);
+ if(structural_copy){
+ this->priv_structural_clone_from(src, cloner, disposer);
+ }
+ else{
+ //Unlike previous cloning algorithm, this can throw
+ //if cloner, hasher or comparison functor throw
+ typedef typename detail::if_c< detail::is_const<MaybeConstHashtableImpl>::value
+ , typename MaybeConstHashtableImpl::const_iterator
+ , typename MaybeConstHashtableImpl::iterator
+ >::type clone_iterator;
+ clone_iterator b(src.begin()), e(src.end());
+ detail::exception_disposer<hashtable_impl, Disposer> rollback(*this, disposer);
+ for(; b != e; ++b){
+ //No need to check for duplicates and insert it in the first position
+ //as this is an unordered container. So use minimal insertion code
+ std::size_t const hash_to_store = this->priv_stored_or_compute_hash(*b, store_hash_t());;
+ size_type const bucket_number = this->priv_hash_to_bucket(hash_to_store);
+ typedef typename detail::if_c
+ <detail::is_const<MaybeConstHashtableImpl>::value, const_reference, reference>::type reference_type;
+ reference_type r = *b;
+ this->priv_clone_front_in_bucket<reference_type>(bucket_number, r, hash_to_store, cloner);
+ }
+ rollback.release();
}
- this->priv_size_traits().set_size(this->priv_size_traits().get_size()-num_erased);
}
}
- template<class Disposer>
- void priv_erase_range_impl
- (size_type first_bucket_num, size_type num_buckets, Disposer disposer, size_type &num_erased)
- {
- //Now fully clear the intermediate buckets
- const bucket_ptr buckets = this->priv_bucket_pointer();
- num_erased = 0;
- for(size_type i = first_bucket_num; i < (num_buckets + first_bucket_num); ++i){
- bucket_type &b = buckets[i];
- siterator b_begin(b.before_begin());
- siterator nxt(b_begin);
- ++nxt;
- siterator end_sit(b.end());
- while(nxt != end_sit){
- group_functions_t::init_group(detail::dcast_bucket_ptr<node>(nxt.pointed_node()), optimize_multikey_t());
- nxt = b.erase_after_and_dispose
- (b_begin, make_node_disposer(disposer));
- this->priv_size_traits().decrement();
- ++num_erased;
+ template<class ValueReference, class Cloner>
+ void priv_clone_front_in_bucket( size_type const bucket_number
+ , typename detail::identity<ValueReference>::type src_ref
+ , std::size_t const hash_to_store, Cloner cloner)
+ {
+ //No need to check for duplicates and insert it in the first position
+ //as this is an unordered container. So use minimal insertion code
+ //std::size_t const hash_value = this->priv_stored_or_compute_hash(src_ref, store_hash_t());;
+ //size_type const bucket_number = this->priv_hash_to_bucket(hash_value);
+ bucket_type &cur_bucket = this->priv_bucket_pointer()[bucket_number];
+ siterator const prev(cur_bucket.before_begin());
+ //Just check if the cloned node is equal to the first inserted value in the new bucket
+ //as equal src values were contiguous and they should be already inserted in the
+ //destination bucket.
+ bool const next_is_in_group = optimize_multikey && !cur_bucket.empty() &&
+ this->priv_equal()( key_of_value()(src_ref)
+ , key_of_value()(this->priv_value_from_slist_node((++siterator(prev)).pointed_node())));
+ this->priv_insert_equal_after_find(*cloner(src_ref), bucket_number, hash_to_store, prev, next_is_in_group);
+ }
+
+ template <class MaybeConstHashtableImpl, class Cloner, class Disposer>
+ void priv_structural_clone_from(MaybeConstHashtableImpl &src, Cloner cloner, Disposer disposer)
+ {
+ //First clone the first ones
+ const size_type src_bucket_count = src.bucket_count();
+ const size_type dst_bucket_count = this->bucket_count();
+ const bucket_ptr src_buckets = src.priv_bucket_pointer();
+ const bucket_ptr dst_buckets = this->priv_bucket_pointer();
+ size_type constructed = 0;
+ typedef node_cast_adaptor< detail::node_disposer<Disposer, value_traits, CircularSListAlgorithms>
+ , slist_node_ptr, node_ptr > NodeDisposer;
+ NodeDisposer node_disp(disposer, &this->priv_value_traits());
+
+ detail::exception_array_disposer<bucket_type, NodeDisposer, size_type>
+ rollback(dst_buckets[0], node_disp, constructed);
+ //Now insert the remaining ones using the modulo trick
+ for( //"constructed" already initialized
+ ; constructed < src_bucket_count
+ ; ++constructed){
+ //Since incremental hashing can't be structurally copied, avoid hash_to_bucket_split
+ const std::size_t new_n = detail::hash_to_bucket(constructed, dst_bucket_count, detail::bool_<power_2_buckets>());
+ bucket_type &src_b = src_buckets[constructed];
+ for( siterator b(src_b.begin()), e(src_b.end()); b != e; ++b){
+ slist_node_ptr const n(b.pointed_node());
+ typedef typename detail::if_c
+ <detail::is_const<MaybeConstHashtableImpl>::value, const_reference, reference>::type reference_type;
+ reference_type r = this->priv_value_from_slist_node(n);
+ this->priv_clone_front_in_bucket<reference_type>
+ (new_n, r, this->priv_stored_hash(n, store_hash_t()), cloner);
}
}
+ this->priv_hasher() = src.priv_hasher();
+ this->priv_equal() = src.priv_equal();
+ rollback.release();
+ this->priv_size_traits().set_size(src.priv_size_traits().get_size());
+ this->priv_split_traits().set_size(dst_bucket_count);
+ this->priv_insertion_update_cache(0u);
+ this->priv_erasure_update_cache();
}
- template<class Disposer>
- void priv_erase_range( siterator before_first_it, size_type first_bucket
- , siterator last_it, size_type last_bucket
- , Disposer disposer)
+ std::size_t priv_hash_to_bucket(std::size_t hash_value) const
{
- size_type num_erased;
- if (first_bucket == last_bucket){
- this->priv_erase_range_impl(first_bucket, before_first_it, last_it, disposer, num_erased);
- }
- else {
- bucket_type *b = (&this->priv_bucket_pointer()[0]);
- this->priv_erase_range_impl(first_bucket, before_first_it, b[first_bucket].end(), disposer, num_erased);
- if(size_type n = (last_bucket - first_bucket - 1))
- this->priv_erase_range_impl(first_bucket + 1, n, disposer, num_erased);
- this->priv_erase_range_impl(last_bucket, b[last_bucket].before_begin(), last_it, disposer, num_erased);
- }
+ return detail::hash_to_bucket_split<power_2_buckets, incremental>
+ (hash_value, this->priv_bucket_traits().bucket_count(), this->priv_split_traits().get_size());
}
- std::size_t priv_get_bucket_num(siterator it)
- { return this->priv_get_bucket_num_hash_dispatch(it, store_hash_t()); }
-
- std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::true_) //store_hash
+ iterator priv_insert_equal_after_find(reference value, size_type bucket_num, std::size_t hash_value, siterator prev, bool const next_is_in_group)
{
- return this->priv_hash_to_bucket
- (this->priv_stored_hash(it.pointed_node(), store_hash_t()));
+ //Now store hash if needed
+ node_ptr n = pointer_traits<node_ptr>::pointer_to(this->priv_value_to_node(value));
+ node_functions_t::store_hash(n, hash_value, store_hash_t());
+ //Checks for some modes
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(n));
+ //Shortcut to optimize_multikey cases
+ group_functions_t::insert_in_group
+ ( next_is_in_group ? detail::dcast_bucket_ptr<node>((++siterator(prev)).pointed_node()) : n
+ , n, optimize_multikey_t());
+ //Update cache and increment size if needed
+ this->priv_insertion_update_cache(bucket_num);
+ this->priv_size_traits().increment();
+ //Insert the element in the bucket after it
+ return iterator(bucket_type::s_insert_after(prev, *n), &this->get_bucket_value_traits());
}
- std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::false_) //NO store_hash
- { return this->data_type::internal.internal.internal.internal.priv_get_bucket_num_no_hash_store(it, optimize_multikey_t()); }
-
- static siterator priv_get_previous(bucket_type &b, siterator i)
- { return bucket_plus_vtraits_t::priv_get_previous(b, i, optimize_multikey_t()); }
-
- static siterator priv_get_last(bucket_type &b)
- { return bucket_plus_vtraits_t::priv_get_last(b, optimize_multikey_t()); }
-
- template<class Disposer>
- void priv_erase(const_iterator i, Disposer disposer, detail::true_)
- {
- slist_node_ptr elem(i.slist_it().pointed_node());
- slist_node_ptr f_bucket_end, l_bucket_end;
- if(store_hash){
- f_bucket_end = l_bucket_end =
- (this->priv_bucket_pointer()
- [this->priv_hash_to_bucket
- (this->priv_stored_hash(elem, store_hash_t()))
- ]).before_begin().pointed_node();
- }
- else{
- f_bucket_end = this->priv_bucket_pointer()->cend().pointed_node();
- l_bucket_end = f_bucket_end + this->priv_bucket_count() - 1;
- }
- node_ptr nxt_in_group;
- siterator prev = bucket_type::s_iterator_to
- (*group_functions_t::get_previous_and_next_in_group
- ( elem, nxt_in_group, f_bucket_end, l_bucket_end)
- );
- bucket_type::s_erase_after_and_dispose(prev, make_node_disposer(disposer));
- if(nxt_in_group)
- group_algorithms::unlink_after(nxt_in_group);
- if(safemode_or_autounlink)
- group_algorithms::init(detail::dcast_bucket_ptr<node>(elem));
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ siterator priv_find //In case it is not found previt is bucket.before_begin()
+ ( const KeyType &key, KeyHasher hash_func
+ , KeyEqual equal_func, size_type &bucket_number, std::size_t &h, siterator &previt) const
+ {
+ h = hash_func(key);
+ return this->priv_find_with_hash(key, equal_func, bucket_number, h, previt);
}
- template <class Disposer>
- void priv_erase(const_iterator i, Disposer disposer, detail::false_)
+ template<class KeyType, class KeyEqual>
+ bool priv_is_value_equal_to_key(const value_type &v, const std::size_t h, const KeyType &key, KeyEqual equal_func) const
{
- siterator to_erase(i.slist_it());
- bucket_type &b = this->priv_bucket_pointer()[this->priv_get_bucket_num(to_erase)];
- siterator prev(this->priv_get_previous(b, to_erase));
- b.erase_after_and_dispose(prev, make_node_disposer(disposer));
+ (void)h;
+ return (!compare_hash || this->priv_stored_or_compute_hash(v, store_hash_t()) == h) && equal_func(key, key_of_value()(v));
}
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- siterator priv_find
- ( const KeyType &key, KeyHasher hash_func
- , KeyValueEqual equal_func, size_type &bucket_number, std::size_t &h, siterator &previt) const
+ //return previous iterator to the next equal range group in case
+ static siterator priv_last_in_group(const siterator &it_first_in_group)
{
- h = hash_func(key);
- return this->priv_find_with_hash(key, equal_func, bucket_number, h, previt);
+ return bucket_type::s_iterator_to
+ (*group_functions_t::get_last_in_group
+ (detail::dcast_bucket_ptr<node>(it_first_in_group.pointed_node()), optimize_multikey_t()));
}
- template<class KeyType, class KeyValueEqual>
- siterator priv_find_with_hash
- ( const KeyType &key, KeyValueEqual equal_func, size_type &bucket_number, const std::size_t h, siterator &previt) const
+ template<class KeyType, class KeyEqual>
+ siterator priv_find_with_hash //In case it is not found previt is bucket.before_begin()
+ ( const KeyType &key, KeyEqual equal_func, size_type &bucket_number, const std::size_t h, siterator &previt) const
{
bucket_number = this->priv_hash_to_bucket(h);
bucket_type &b = this->priv_bucket_pointer()[bucket_number];
previt = b.before_begin();
- if(constant_time_size && this->empty()){
- return this->priv_invalid_local_it();
- }
-
siterator it = previt;
- ++it;
-
- while(it != b.end()){
- const value_type &v = this->priv_value_from_slist_node(it.pointed_node());
- if(compare_hash){
- std::size_t vh = this->priv_stored_or_compute_hash(v, store_hash_t());
- if(h == vh && equal_func(key, v)){
- return it;
- }
- }
- else if(equal_func(key, v)){
+ siterator const endit = b.end();
+
+ while(++it != endit){
+ if(this->priv_is_value_equal_to_key(this->priv_value_from_slist_node(it.pointed_node()), h, key, equal_func)){
return it;
}
- if(optimize_multikey){
- previt = bucket_type::s_iterator_to
- (*group_functions_t::get_last_in_group
- (detail::dcast_bucket_ptr<node>(it.pointed_node()), optimize_multikey_t()));
- it = previt;
- }
- else{
- previt = it;
- }
- ++it;
+ previt = it = (priv_last_in_group)(it);
}
previt = b.before_begin();
return this->priv_invalid_local_it();
}
- iterator priv_insert_equal_with_hash(reference value, std::size_t hash_value)
- {
- size_type bucket_num;
- siterator prev;
- siterator it = this->priv_find_with_hash
- (value, this->priv_equal(), bucket_num, hash_value, prev);
- return this->priv_insert_equal_find(value, bucket_num, hash_value, it);
- }
-
- iterator priv_insert_equal_find(reference value, size_type bucket_num, std::size_t hash_value, siterator it)
- {
- bucket_type &b = this->priv_bucket_pointer()[bucket_num];
- bool found_equal = it != this->priv_invalid_local_it();
- if(!found_equal){
- it = b.before_begin();
- }
- //Now store hash if needed
- node_ptr n = pointer_traits<node_ptr>::pointer_to(this->priv_value_to_node(value));
- node_functions_t::store_hash(n, hash_value, store_hash_t());
- //Checks for some modes
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
- //Shortcut for optimize_multikey cases
- if(optimize_multikey){
- node_ptr first_in_group = found_equal ?
- detail::dcast_bucket_ptr<node>(it.pointed_node()) : node_ptr();
- group_functions_t::insert_in_group(first_in_group, n, optimize_multikey_t());
- }
- //Update cache and increment size if needed
- this->priv_insertion_update_cache(bucket_num);
- this->priv_size_traits().increment();
- //Insert the element in the bucket after it
- return iterator(b.insert_after(it, *n), &this->get_bucket_value_traits());
- }
-
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- std::pair<siterator, siterator> priv_equal_range
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ std::pair<siterator, siterator> priv_local_equal_range
( const KeyType &key
, KeyHasher hash_func
- , KeyValueEqual equal_func
- , size_type &bucket_number_first
- , size_type &bucket_number_second
+ , KeyEqual equal_func
+ , size_type &found_bucket
, size_type &cnt) const
{
- std::size_t h;
cnt = 0;
- siterator prev;
//Let's see if the element is present
+
+ siterator prev;
+ size_type n_bucket;
+ std::size_t h;
std::pair<siterator, siterator> to_return
- ( this->priv_find(key, hash_func, equal_func, bucket_number_first, h, prev)
+ ( this->priv_find(key, hash_func, equal_func, n_bucket, h, prev)
, this->priv_invalid_local_it());
- if(to_return.first == to_return.second){
- bucket_number_second = bucket_number_first;
- return to_return;
- }
- {
+
+ if(to_return.first != to_return.second){
+ found_bucket = n_bucket;
//If it's present, find the first that it's not equal in
//the same bucket
- bucket_type &b = this->priv_bucket_pointer()[bucket_number_first];
+ bucket_type &b = this->priv_bucket_pointer()[n_bucket];
siterator it = to_return.first;
+ ++cnt; //At least one is found
if(optimize_multikey){
- to_return.second = bucket_type::s_iterator_to
- (*node_traits::get_next(group_functions_t::get_last_in_group
- (detail::dcast_bucket_ptr<node>(it.pointed_node()), optimize_multikey_t())));
-
- cnt = 0;
- for(; it != to_return.second; ++it){ ++cnt; }
- if(to_return.second != b.end()){
- bucket_number_second = bucket_number_first;
- return to_return;
- }
+ to_return.second = ++(priv_last_in_group)(it);
+ cnt += boost::intrusive::iterator_distance(++it, to_return.second);
}
else{
- ++cnt;
- ++it;
- while(it != b.end()){
- const value_type &v = this->priv_value_from_slist_node(it.pointed_node());
- if(compare_hash){
- std::size_t hv = this->priv_stored_or_compute_hash(v, store_hash_t());
- if(hv != h || !equal_func(key, v)){
- to_return.second = it;
- bucket_number_second = bucket_number_first;
- return to_return;
- }
- }
- else if(!equal_func(key, v)){
- to_return.second = it;
- bucket_number_second = bucket_number_first;
- return to_return;
- }
- ++it;
+ siterator const bend = b.end();
+ while(++it != bend &&
+ this->priv_is_value_equal_to_key(this->priv_value_from_slist_node(it.pointed_node()), h, key, equal_func)){
++cnt;
}
+ to_return.second = it;
}
}
+ return to_return;
+ }
- //If we reached the end, find the first, non-empty bucket
- for(bucket_number_second = bucket_number_first+1
- ; bucket_number_second != this->priv_bucket_count()
- ; ++bucket_number_second){
- bucket_type &b = this->priv_bucket_pointer()[bucket_number_second];
- if(!b.empty()){
- to_return.second = b.begin();
- return to_return;
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ std::pair<siterator, siterator> priv_equal_range
+ ( const KeyType &key
+ , KeyHasher hash_func
+ , KeyEqual equal_func) const
+ {
+ size_type n_bucket;
+ size_type cnt;
+
+ //Let's see if the element is present
+ std::pair<siterator, siterator> to_return
+ (this->priv_local_equal_range(key, hash_func, equal_func, n_bucket, cnt));
+ //If not, find the next element as ".second" if ".second" local iterator
+ //is not pointing to an element.
+ bucket_ptr const bp = this->priv_bucket_pointer();
+ if(to_return.first != to_return.second &&
+ to_return.second == bp[n_bucket].end()){
+ to_return.second = this->priv_invalid_local_it();
+ ++n_bucket;
+ for( const size_type max_bucket = this->priv_bucket_count()
+ ; n_bucket != max_bucket
+ ; ++n_bucket){
+ bucket_type &b = bp[n_bucket];
+ if(!b.empty()){
+ to_return.second = b.begin();
+ break;
+ }
}
}
-
- //Otherwise, return the end node
- to_return.second = this->priv_invalid_local_it();
return to_return;
}
+
+ std::size_t priv_get_bucket_num(siterator it)
+ { return this->priv_get_bucket_num_hash_dispatch(it, store_hash_t()); }
+
+ std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::true_) //store_hash
+ {
+ return this->priv_hash_to_bucket
+ (this->priv_stored_hash(it.pointed_node(), store_hash_t()));
+ }
+
+ std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::false_) //NO store_hash
+ { return this->priv_get_bucket_num_no_hash_store(it, optimize_multikey_t()); }
+
+ static siterator priv_get_previous(bucket_type &b, siterator i)
+ { return bucket_plus_vtraits_t::priv_get_previous(b, i, optimize_multikey_t()); }
+
/// @endcond
};
@@ -3232,16 +3413,17 @@ struct make_hashtable
typedef hashtable_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::hash
, typename packed_options::equal
- , typename packed_options::size_type
, bucket_traits
+ , typename packed_options::size_type
, (std::size_t(false)*hash_bool_flags::unique_keys_pos)
- | (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
- | (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
- | (std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos)
- | (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
- | (std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
+ |(std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
+ |(std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
+ |(std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos)
+ |(std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
+ |(std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
> implementation_defined;
/// @endcond
@@ -3299,6 +3481,14 @@ class hashtable
hashtable& operator=(BOOST_RV_REF(hashtable) x)
{ return static_cast<hashtable&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(const hashtable &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(hashtable) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
};
#endif
diff --git a/boost/intrusive/intrusive_fwd.hpp b/boost/intrusive/intrusive_fwd.hpp
index 88cb537c6b..b6b14c0698 100644
--- a/boost/intrusive/intrusive_fwd.hpp
+++ b/boost/intrusive/intrusive_fwd.hpp
@@ -184,6 +184,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -198,6 +199,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -212,6 +214,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -251,6 +254,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -265,6 +269,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -279,6 +284,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -294,6 +300,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -308,6 +315,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -322,6 +330,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -362,6 +371,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -376,6 +386,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -390,6 +401,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -405,6 +417,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -419,6 +432,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -433,6 +447,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -447,6 +462,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -461,6 +477,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -475,6 +492,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
diff --git a/boost/intrusive/list.hpp b/boost/intrusive/list.hpp
index 906b002907..cc6d73bb43 100644
--- a/boost/intrusive/list.hpp
+++ b/boost/intrusive/list.hpp
@@ -248,8 +248,7 @@ class list_impl
void push_back(reference value)
{
node_ptr to_insert = priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert));
node_algorithms::link_before(this->get_root_node(), to_insert);
this->priv_size_traits().increment();
}
@@ -267,8 +266,7 @@ class list_impl
void push_front(reference value)
{
node_ptr to_insert = priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert));
node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert);
this->priv_size_traits().increment();
}
@@ -770,6 +768,33 @@ class list_impl
rollback.release();
}
+ //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
+ //!
+ //! <b>Effects</b>: Erases all the elements from *this
+ //! calling Disposer::operator()(pointer), clones all the
+ //! elements from src calling Cloner::operator()(reference)
+ //! and inserts them on *this.
+ //!
+ //! If cloner throws, all cloned elements are unlinked and disposed
+ //! calling Disposer::operator()(pointer).
+ //!
+ //! <b>Complexity</b>: Linear to erased plus inserted elements.
+ //!
+ //! <b>Throws</b>: If cloner throws. Basic guarantee.
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(list_impl) src, Cloner cloner, Disposer disposer)
+ {
+ this->clear_and_dispose(disposer);
+ detail::exception_disposer<list_impl, Disposer>
+ rollback(*this, disposer);
+ iterator b(src.begin()), e(src.end());
+ for(; b != e; ++b){
+ this->push_back(*cloner(*b));
+ }
+ rollback.release();
+ }
+
//! <b>Requires</b>: value must be an lvalue and p must be a valid iterator of *this.
//!
//! <b>Effects</b>: Inserts the value before the position pointed by p.
@@ -784,8 +809,7 @@ class list_impl
iterator insert(const_iterator p, reference value)
{
node_ptr to_insert = this->priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert));
node_algorithms::link_before(p.pointed_node(), to_insert);
this->priv_size_traits().increment();
return iterator(to_insert, this->priv_value_traits_ptr());
@@ -1320,6 +1344,32 @@ class list_impl
BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count);
}
+ friend bool operator==(const list_impl &x, const list_impl &y)
+ {
+ if(constant_time_size && x.size() != y.size()){
+ return false;
+ }
+ return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
+ }
+
+ friend bool operator!=(const list_impl &x, const list_impl &y)
+ { return !(x == y); }
+
+ friend bool operator<(const list_impl &x, const list_impl &y)
+ { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+
+ friend bool operator>(const list_impl &x, const list_impl &y)
+ { return y < x; }
+
+ friend bool operator<=(const list_impl &x, const list_impl &y)
+ { return !(y < x); }
+
+ friend bool operator>=(const list_impl &x, const list_impl &y)
+ { return !(x < y); }
+
+ friend void swap(list_impl &x, list_impl &y)
+ { x.swap(y); }
+
/// @cond
private:
@@ -1338,103 +1388,6 @@ class list_impl
/// @endcond
};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
-#endif
-inline bool operator<
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
-#else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
-#endif
-{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
-#endif
-bool operator==
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
-#else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
-#endif
-{
- typedef list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> list_type;
- const bool C = list_type::constant_time_size;
- if(C && x.size() != y.size()){
- return false;
- }
- return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
-}
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
-#endif
-inline bool operator!=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
-#else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
-#endif
-{ return !(x == y); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
-#endif
-inline bool operator>
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
-#else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
-#endif
-{ return y < x; }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
-#endif
-inline bool operator<=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
-#else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
-#endif
-{ return !(y < x); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
-#endif
-inline bool operator>=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
-#else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
-#endif
-{ return !(x < y); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
-#endif
-inline void swap
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(list_impl<T, Options...> &x, list_impl<T, Options...> &y)
-#else
-(list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
-#endif
-{ x.swap(y); }
//! Helper metafunction to define a \c list that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
@@ -1518,6 +1471,14 @@ class list
list& operator=(BOOST_RV_REF(list) x)
{ return static_cast<list &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const list &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(list) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static list &container_from_end_iterator(iterator end_iterator)
{ return static_cast<list &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/options.hpp b/boost/intrusive/options.hpp
index ec6e9674d9..fdcb5cb3c5 100644
--- a/boost/intrusive/options.hpp
+++ b/boost/intrusive/options.hpp
@@ -61,6 +61,15 @@ BOOST_INTRUSIVE_OPTION_TYPE(size_type, SizeType, SizeType, size_type)
//!comparison functor for the value type
BOOST_INTRUSIVE_OPTION_TYPE(compare, Compare, Compare, compare)
+//!This option setter specifies the a function object
+//!that specifies the type of the key of an associative
+//!container and an operator to obtain it from a value type.
+//!
+//!This function object must the define a `key_type` and
+//!a member with signature `const key_type & operator()(const value_type &) const`
+//!that will return the key from a value_type of an associative container
+BOOST_INTRUSIVE_OPTION_TYPE(key_of_value, KeyOfValue, KeyOfValue, key_of_value)
+
//!This option setter for scapegoat containers specifies if
//!the intrusive scapegoat container should use a non-variable
//!alpha value that does not need floating-point operations.
@@ -199,7 +208,7 @@ BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_multikey, bool, Enabled, optimize_multi
//!This allows using masks instead of the default modulo operation to determine
//!the bucket number from the hash value, leading to better performance.
//!In debug mode, if power of two buckets mode is activated, the bucket length
-//!will be checked to through assertions to assure the bucket length is power of two.
+//!will be checked with assertions.
BOOST_INTRUSIVE_OPTION_CONSTANT(power_2_buckets, bool, Enabled, power_2_buckets)
//!This option setter specifies if the container will cache a pointer to the first
diff --git a/boost/intrusive/rbtree.hpp b/boost/intrusive/rbtree.hpp
index 4ef50b4c4f..f3afd017c8 100644
--- a/boost/intrusive/rbtree.hpp
+++ b/boost/intrusive/rbtree.hpp
@@ -48,19 +48,16 @@ struct is_default_hook_tag<default_rbtree_hook_applier>
{ static const bool value = true; };
struct rbtree_defaults
+ : bstree_defaults
{
typedef default_rbtree_hook_applier proto_value_traits;
- static const bool constant_time_size = true;
- typedef std::size_t size_type;
- typedef void compare;
- typedef void header_holder_type;
};
/// @endcond
//! The class template rbtree is an intrusive red-black tree container, that
//! is used to construct intrusive set and multiset containers. The no-throw
-//! guarantee holds only, if the value_compare object
+//! guarantee holds only, if the key_compare object
//! doesn't throw.
//!
//! The template parameter \c T is the type to be managed by the container.
@@ -74,17 +71,17 @@ struct rbtree_defaults
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class rbtree_impl
/// @cond
- : public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
/// @endcond
{
public:
typedef ValueTraits value_traits;
/// @cond
- typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
+ typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
, ConstantTimeSize, RbTreeAlgorithms
, HeaderHolder> tree_type;
typedef tree_type implementation_defined;
@@ -94,6 +91,7 @@ class rbtree_impl
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
@@ -123,16 +121,16 @@ class rbtree_impl
typedef typename implementation_defined::insert_commit_data insert_commit_data;
- //! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &)
- explicit rbtree_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
+ explicit rbtree_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
rbtree_impl( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(unique, b, e, cmp, v_traits)
{}
@@ -213,13 +211,26 @@ class rbtree_impl
//! @copydoc ::boost::intrusive::bstree::swap
void swap(rbtree_impl& other);
- //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree &src, cloner, Disposer)
+ //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const rbtree_impl &src, Cloner cloner, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::clone_from(bstree &src, cloner, Disposer)
+ #else //BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
template <class Cloner, class Disposer>
- void clone_from(rbtree_impl &src, Cloner cloner, Disposer disposer);
+ void clone_from(BOOST_RV_REF(rbtree_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
+
+ #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(rbtree_impl &&src, Cloner cloner, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
iterator insert_equal(reference value);
@@ -237,16 +248,16 @@ class rbtree_impl
//! @copydoc ::boost::intrusive::bstree::insert_unique(const_iterator,reference)
iterator insert_unique(const_iterator hint, reference value);
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data);
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_commit
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data);
@@ -270,12 +281,12 @@ class rbtree_impl
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::bstree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::erase(const key_type &key)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -285,13 +296,13 @@ class rbtree_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::clear
void clear();
@@ -300,88 +311,88 @@ class rbtree_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -406,33 +417,23 @@ class rbtree_impl
//! @copydoc ::boost::intrusive::bstree::remove_node
void remove_node(reference value);
- #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
-};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ friend bool operator< (const rbtree_impl &x, const rbtree_impl &y);
-template<class T, class ...Options>
-bool operator< (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
+ friend bool operator==(const rbtree_impl &x, const rbtree_impl &y);
-template<class T, class ...Options>
-bool operator==(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
+ friend bool operator!= (const rbtree_impl &x, const rbtree_impl &y);
-template<class T, class ...Options>
-bool operator!= (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator>(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
+ friend bool operator>(const rbtree_impl &x, const rbtree_impl &y);
-template<class T, class ...Options>
-bool operator<=(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
+ friend bool operator<=(const rbtree_impl &x, const rbtree_impl &y);
-template<class T, class ...Options>
-bool operator>=(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
+ friend bool operator>=(const rbtree_impl &x, const rbtree_impl &y);
-template<class T, class ...Options>
-void swap(rbtree_impl<T, Options...> &x, rbtree_impl<T, Options...> &y);
+ friend void swap(rbtree_impl &x, rbtree_impl &y);
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+};
-#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! Helper metafunction to define a \c rbtree that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
@@ -441,7 +442,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_rbtree
{
@@ -449,7 +450,7 @@ struct make_rbtree
typedef typename pack_options
< rbtree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -460,6 +461,7 @@ struct make_rbtree
typedef rbtree_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -473,14 +475,14 @@ struct make_rbtree
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class rbtree
: public make_rbtree<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -489,7 +491,7 @@ class rbtree
typedef typename make_rbtree
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -497,7 +499,7 @@ class rbtree
BOOST_MOVABLE_BUT_NOT_COPYABLE(rbtree)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -507,14 +509,14 @@ class rbtree
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit rbtree( const value_compare &cmp = value_compare()
+ explicit rbtree( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
rbtree( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, v_traits)
{}
@@ -526,6 +528,14 @@ class rbtree
rbtree& operator=(BOOST_RV_REF(rbtree) x)
{ return static_cast<rbtree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const rbtree &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(rbtree) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static rbtree &container_from_end_iterator(iterator end_iterator)
{ return static_cast<rbtree &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/rbtree_algorithms.hpp b/boost/intrusive/rbtree_algorithms.hpp
index ad9c7658e3..00d9fe3b18 100644
--- a/boost/intrusive/rbtree_algorithms.hpp
+++ b/boost/intrusive/rbtree_algorithms.hpp
@@ -92,8 +92,8 @@ struct rbtree_node_checker
if (node_traits::get_color(p) == node_traits::red()){
//Red nodes have black children
- const node_ptr p_left(node_traits::get_left(p));
- const node_ptr p_right(node_traits::get_right(p));
+ const node_ptr p_left(node_traits::get_left(p)); (void)p_left;
+ const node_ptr p_right(node_traits::get_right(p)); (void)p_right;
BOOST_INTRUSIVE_INVARIANT_ASSERT(!p_left || node_traits::get_color(p_left) == node_traits::black());
BOOST_INTRUSIVE_INVARIANT_ASSERT(!p_right || node_traits::get_color(p_right) == node_traits::black());
//Red node can't be root
diff --git a/boost/intrusive/set.hpp b/boost/intrusive/set.hpp
index 1048429005..ae6a7a0812 100644
--- a/boost/intrusive/set.hpp
+++ b/boost/intrusive/set.hpp
@@ -42,15 +42,15 @@ namespace intrusive {
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class set_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
#endif
{
/// @cond
- typedef bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder> tree_type;
+ typedef bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(set_impl)
typedef tree_type implementation_defined;
@@ -58,6 +58,8 @@ class set_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -81,16 +83,16 @@ class set_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::rbtree::rbtree(const value_compare &,const value_traits &)
- explicit set_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::rbtree::rbtree(const key_compare &,const value_traits &)
+ explicit set_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::rbtree::rbtree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::rbtree::rbtree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
set_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(true, b, e, cmp, v_traits)
{}
@@ -171,11 +173,20 @@ class set_impl
//! @copydoc ::boost::intrusive::rbtree::swap
void swap(set_impl& other);
- //! @copydoc ::boost::intrusive::rbtree::clone_from
+ //! @copydoc ::boost::intrusive::rbtree::clone_from(const rbtree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const set_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::rbtree::clone_from(rbtree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(set_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::rbtree::insert_unique(reference)
std::pair<iterator, bool> insert(reference value)
@@ -185,18 +196,18 @@ class set_impl
iterator insert(const_iterator hint, reference value)
{ return tree_type::insert_unique(hint, value); }
- //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(key, key_value_comp, commit_data); }
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(key, comp, commit_data); }
- //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(hint, key, key_value_comp, commit_data); }
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(hint, key, comp, commit_data); }
//! @copydoc ::boost::intrusive::rbtree::insert_unique(Iterator,Iterator)
template<class Iterator>
@@ -223,12 +234,12 @@ class set_impl
//! @copydoc ::boost::intrusive::rbtree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::rbtree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -238,13 +249,13 @@ class set_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::rbtree::clear
void clear();
@@ -255,100 +266,100 @@ class set_impl
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::count(const_reference)const
- size_type count(const_reference value) const
- { return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
+ //! @copydoc ::boost::intrusive::rbtree::count(const key_type &)const
+ size_type count(const key_type &key) const
+ { return static_cast<size_type>(this->tree_type::find(key) != this->tree_type::cend()); }
- //! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const
+ //! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::rbtree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::rbtree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::rbtree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->tree_type::lower_bound_range(value); }
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key)
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp)
{ return this->tree_type::lower_bound_range(key, comp); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->tree_type::lower_bound_range(value); }
+ equal_range(const key_type &key) const
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const
{ return this->tree_type::lower_bound_range(key, comp); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::rbtree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -402,7 +413,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_set
{
@@ -410,7 +421,7 @@ struct make_set
typedef typename pack_options
< rbtree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -421,6 +432,7 @@ struct make_set
typedef set_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -432,14 +444,14 @@ struct make_set
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class set
: public make_set<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -448,7 +460,7 @@ class set
typedef typename make_set
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -456,7 +468,7 @@ class set
BOOST_MOVABLE_BUT_NOT_COPYABLE(set)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -464,14 +476,14 @@ class set
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit set( const value_compare &cmp = value_compare()
+ explicit set( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
set( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -483,6 +495,14 @@ class set
set& operator=(BOOST_RV_REF(set) x)
{ return static_cast<set &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const set &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(set) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static set &container_from_end_iterator(iterator end_iterator)
{ return static_cast<set &>(Base::container_from_end_iterator(end_iterator)); }
@@ -512,15 +532,15 @@ class set
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class multiset_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
#endif
{
/// @cond
- typedef bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder> tree_type;
+ typedef bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(multiset_impl)
typedef tree_type implementation_defined;
@@ -528,6 +548,8 @@ class multiset_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -551,16 +573,16 @@ class multiset_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::rbtree::rbtree(const value_compare &,const value_traits &)
- explicit multiset_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::rbtree::rbtree(const key_compare &,const value_traits &)
+ explicit multiset_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::rbtree::rbtree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::rbtree::rbtree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
multiset_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(false, b, e, cmp, v_traits)
{}
@@ -641,11 +663,20 @@ class multiset_impl
//! @copydoc ::boost::intrusive::rbtree::swap
void swap(multiset_impl& other);
- //! @copydoc ::boost::intrusive::rbtree::clone_from
+ //! @copydoc ::boost::intrusive::rbtree::clone_from(const rbtree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const multiset_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::rbtree::clone_from(rbtree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(multiset_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::rbtree::insert_equal(reference)
iterator insert(reference value)
@@ -676,12 +707,12 @@ class multiset_impl
//! @copydoc ::boost::intrusive::rbtree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::rbtree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -691,13 +722,13 @@ class multiset_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::rbtree::clear
void clear();
@@ -706,88 +737,88 @@ class multiset_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::rbtree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::rbtree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::rbtree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::rbtree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::rbtree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::rbtree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -841,7 +872,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_multiset
{
@@ -849,7 +880,7 @@ struct make_multiset
typedef typename pack_options
< rbtree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -860,6 +891,7 @@ struct make_multiset
typedef multiset_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -872,14 +904,14 @@ struct make_multiset
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class multiset
: public make_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -887,7 +919,7 @@ class multiset
{
typedef typename make_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -896,7 +928,7 @@ class multiset
BOOST_MOVABLE_BUT_NOT_COPYABLE(multiset)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -904,14 +936,14 @@ class multiset
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- multiset( const value_compare &cmp = value_compare()
+ multiset( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
multiset( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -923,6 +955,14 @@ class multiset
multiset& operator=(BOOST_RV_REF(multiset) x)
{ return static_cast<multiset &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const multiset &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(multiset) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static multiset &container_from_end_iterator(iterator end_iterator)
{ return static_cast<multiset &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/sg_set.hpp b/boost/intrusive/sg_set.hpp
index 7e250cb6a0..560845e7a2 100644
--- a/boost/intrusive/sg_set.hpp
+++ b/boost/intrusive/sg_set.hpp
@@ -40,15 +40,15 @@ namespace intrusive {
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool FloatingPoint, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool FloatingPoint, typename HeaderHolder>
#endif
class sg_set_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public sgtree_impl<ValueTraits, Compare, SizeType, FloatingPoint, HeaderHolder>
+ : public sgtree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, FloatingPoint, HeaderHolder>
#endif
{
/// @cond
- typedef sgtree_impl<ValueTraits, Compare, SizeType, FloatingPoint, HeaderHolder> tree_type;
+ typedef sgtree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, FloatingPoint, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(sg_set_impl)
typedef tree_type implementation_defined;
@@ -56,6 +56,8 @@ class sg_set_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -79,16 +81,16 @@ class sg_set_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::sgtree::sgtree(const value_compare &,const value_traits &)
- explicit sg_set_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::sgtree::sgtree(const key_compare &,const value_traits &)
+ explicit sg_set_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::sgtree::sgtree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::sgtree::sgtree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
sg_set_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(true, b, e, cmp, v_traits)
{}
@@ -169,11 +171,20 @@ class sg_set_impl
//! @copydoc ::boost::intrusive::sgtree::swap
void swap(sg_set_impl& other);
- //! @copydoc ::boost::intrusive::sgtree::clone_from
+ //! @copydoc ::boost::intrusive::sgtree::clone_from(const sgtree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const sg_set_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::sgtree::clone_from(sgtree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(sg_set_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::sgtree::insert_unique(reference)
std::pair<iterator, bool> insert(reference value)
@@ -183,18 +194,18 @@ class sg_set_impl
iterator insert(const_iterator hint, reference value)
{ return tree_type::insert_unique(hint, value); }
- //! @copydoc ::boost::intrusive::sgtree::insert_unique_check(const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::sgtree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(key, key_value_comp, commit_data); }
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(key, comp, commit_data); }
- //! @copydoc ::boost::intrusive::sgtree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::sgtree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(hint, key, key_value_comp, commit_data); }
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(hint, key, comp, commit_data); }
//! @copydoc ::boost::intrusive::sgtree::insert_unique(Iterator,Iterator)
template<class Iterator>
@@ -221,12 +232,12 @@ class sg_set_impl
//! @copydoc ::boost::intrusive::sgtree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::sgtree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -236,13 +247,13 @@ class sg_set_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::sgtree::clear
void clear();
@@ -253,100 +264,100 @@ class sg_set_impl
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::sgtree::count(const_reference)const
- size_type count(const_reference value) const
- { return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
+ //! @copydoc ::boost::intrusive::sgtree::count(const key_type &)const
+ size_type count(const key_type &key) const
+ { return static_cast<size_type>(this->tree_type::find(key) != this->tree_type::cend()); }
- //! @copydoc ::boost::intrusive::sgtree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const
+ //! @copydoc ::boost::intrusive::sgtree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::sgtree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::sgtree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::sgtree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->tree_type::lower_bound_range(value); }
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key)
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp)
{ return this->tree_type::lower_bound_range(key, comp); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->tree_type::lower_bound_range(value); }
+ equal_range(const key_type &key) const
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const
{ return this->tree_type::lower_bound_range(key, comp); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::sgtree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -413,7 +424,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_sg_set
{
@@ -421,7 +432,7 @@ struct make_sg_set
typedef typename pack_options
< sgtree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -432,6 +443,7 @@ struct make_sg_set
typedef sg_set_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::floating_point
@@ -443,14 +455,14 @@ struct make_sg_set
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class sg_set
: public make_sg_set<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -459,7 +471,7 @@ class sg_set
typedef typename make_sg_set
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -467,7 +479,7 @@ class sg_set
BOOST_MOVABLE_BUT_NOT_COPYABLE(sg_set)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -475,14 +487,14 @@ class sg_set
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit sg_set( const value_compare &cmp = value_compare()
+ explicit sg_set( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
sg_set( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -494,6 +506,14 @@ class sg_set
sg_set& operator=(BOOST_RV_REF(sg_set) x)
{ return static_cast<sg_set &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const sg_set &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(sg_set) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static sg_set &container_from_end_iterator(iterator end_iterator)
{ return static_cast<sg_set &>(Base::container_from_end_iterator(end_iterator)); }
@@ -523,15 +543,15 @@ class sg_set
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool FloatingPoint, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool FloatingPoint, typename HeaderHolder>
#endif
class sg_multiset_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public sgtree_impl<ValueTraits, Compare, SizeType, FloatingPoint, HeaderHolder>
+ : public sgtree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, FloatingPoint, HeaderHolder>
#endif
{
/// @cond
- typedef sgtree_impl<ValueTraits, Compare, SizeType, FloatingPoint, HeaderHolder> tree_type;
+ typedef sgtree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, FloatingPoint, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(sg_multiset_impl)
typedef tree_type implementation_defined;
@@ -539,6 +559,8 @@ class sg_multiset_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -562,16 +584,16 @@ class sg_multiset_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::sgtree::sgtree(const value_compare &,const value_traits &)
- explicit sg_multiset_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::sgtree::sgtree(const key_compare &,const value_traits &)
+ explicit sg_multiset_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::sgtree::sgtree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::sgtree::sgtree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
sg_multiset_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(false, b, e, cmp, v_traits)
{}
@@ -652,11 +674,20 @@ class sg_multiset_impl
//! @copydoc ::boost::intrusive::sgtree::swap
void swap(sg_multiset_impl& other);
- //! @copydoc ::boost::intrusive::sgtree::clone_from
+ //! @copydoc ::boost::intrusive::sgtree::clone_from(const sgtree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const sg_multiset_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::sgtree::clone_from(sgtree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(sg_multiset_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::sgtree::insert_equal(reference)
iterator insert(reference value)
@@ -687,12 +718,12 @@ class sg_multiset_impl
//! @copydoc ::boost::intrusive::sgtree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::sgtree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -702,13 +733,13 @@ class sg_multiset_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::sgtree::clear
void clear();
@@ -717,88 +748,88 @@ class sg_multiset_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::sgtree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::sgtree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::sgtree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::sgtree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::sgtree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::sgtree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::sgtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::sgtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::sgtree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::sgtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::sgtree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -865,7 +896,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_sg_multiset
{
@@ -873,7 +904,7 @@ struct make_sg_multiset
typedef typename pack_options
< sgtree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -884,6 +915,7 @@ struct make_sg_multiset
typedef sg_multiset_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::floating_point
@@ -896,14 +928,14 @@ struct make_sg_multiset
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class sg_multiset
: public make_sg_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -911,7 +943,7 @@ class sg_multiset
{
typedef typename make_sg_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -920,7 +952,7 @@ class sg_multiset
BOOST_MOVABLE_BUT_NOT_COPYABLE(sg_multiset)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -928,14 +960,14 @@ class sg_multiset
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- sg_multiset( const value_compare &cmp = value_compare()
+ sg_multiset( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
sg_multiset( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -947,6 +979,14 @@ class sg_multiset
sg_multiset& operator=(BOOST_RV_REF(sg_multiset) x)
{ return static_cast<sg_multiset &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const sg_multiset &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(sg_multiset) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static sg_multiset &container_from_end_iterator(iterator end_iterator)
{ return static_cast<sg_multiset &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/sgtree.hpp b/boost/intrusive/sgtree.hpp
index feeaf3bcbf..dc84c80462 100644
--- a/boost/intrusive/sgtree.hpp
+++ b/boost/intrusive/sgtree.hpp
@@ -195,13 +195,9 @@ struct alpha_holder<false, SizeType>
} //namespace detail{
struct sgtree_defaults
+ : bstree_defaults
{
- typedef default_bstree_hook_applier proto_value_traits;
- static const bool constant_time_size = true;
- typedef std::size_t size_type;
- typedef void compare;
static const bool floating_point = true;
- typedef void header_holder_type;
};
/// @endcond
@@ -222,18 +218,18 @@ struct sgtree_defaults
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyComp, class SizeType, bool FloatingPoint, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool FloatingPoint, typename HeaderHolder>
#endif
class sgtree_impl
/// @cond
- : public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, true, SgTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, true, SgTreeAlgorithms, HeaderHolder>
, public detail::alpha_holder<FloatingPoint, SizeType>
/// @endcond
{
public:
typedef ValueTraits value_traits;
/// @cond
- typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
+ typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
, true, SgTreeAlgorithms, HeaderHolder> tree_type;
typedef tree_type implementation_defined;
@@ -243,6 +239,7 @@ class sgtree_impl
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
@@ -284,16 +281,16 @@ class sgtree_impl
typedef BOOST_INTRUSIVE_IMPDEF(typename node_algorithms::insert_commit_data) insert_commit_data;
- //! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &)
- explicit sgtree_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
+ explicit sgtree_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
sgtree_impl( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{
@@ -408,26 +405,33 @@ class sgtree_impl
::boost::adl_move_swap(this->get_alpha_traits(), other.get_alpha_traits());
}
- //! @copydoc ::boost::intrusive::bstree::clone_from
+ //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
//! Additional notes: it also copies the alpha factor from the source container.
template <class Cloner, class Disposer>
void clone_from(const sgtree_impl &src, Cloner cloner, Disposer disposer)
{
- this->tree_type::clone_from(src, cloner, disposer);
+ tree_type::clone_from(src, cloner, disposer);
this->get_alpha_traits() = src.get_alpha_traits();
}
+ //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
+ //! Additional notes: it also copies the alpha factor from the source container.
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(sgtree_impl) src, Cloner cloner, Disposer disposer)
+ {
+ tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer);
+ this->get_alpha_traits() = ::boost::move(src.get_alpha_traits());
+ }
+
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
iterator insert_equal(reference value)
{
- detail::key_nodeptr_comp<value_compare, value_traits>
- key_node_comp(this->value_comp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
node_ptr p = node_algorithms::insert_equal_upper_bound
- (this->tree_type::header_ptr(), to_insert, key_node_comp
+ (this->tree_type::header_ptr(), to_insert, this->key_node_comp(this->key_comp())
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
this->tree_type::sz_traits().increment();
this->max_tree_size_ = (size_type)max_tree_size;
@@ -437,14 +441,12 @@ class sgtree_impl
//! @copydoc ::boost::intrusive::bstree::insert_equal(const_iterator,reference)
iterator insert_equal(const_iterator hint, reference value)
{
- detail::key_nodeptr_comp<value_compare, value_traits>
- key_node_comp(this->value_comp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
node_ptr p = node_algorithms::insert_equal
- (this->tree_type::header_ptr(), hint.pointed_node(), to_insert, key_node_comp
+ ( this->tree_type::header_ptr(), hint.pointed_node(), to_insert, this->key_node_comp(this->key_comp())
, (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
this->tree_type::sz_traits().increment();
this->max_tree_size_ = (size_type)max_tree_size;
@@ -464,46 +466,44 @@ class sgtree_impl
std::pair<iterator, bool> insert_unique(reference value)
{
insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(value, this->value_comp(), commit_data);
+ std::pair<iterator, bool> ret = this->insert_unique_check
+ (key_of_value()(value), this->key_comp(), commit_data);
if(!ret.second)
return ret;
- return std::pair<iterator, bool> (insert_unique_commit(value, commit_data), true);
+ return std::pair<iterator, bool> (this->insert_unique_commit(value, commit_data), true);
}
//! @copydoc ::boost::intrusive::bstree::insert_unique(const_iterator,reference)
iterator insert_unique(const_iterator hint, reference value)
{
insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(hint, value, this->value_comp(), commit_data);
+ std::pair<iterator, bool> ret = this->insert_unique_check
+ (hint, key_of_value()(value), this->key_comp(), commit_data);
if(!ret.second)
return ret.first;
- return insert_unique_commit(value, commit_data);
+ return this->insert_unique_commit(value, commit_data);
}
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- comp(key_value_comp, &this->get_value_traits());
std::pair<node_ptr, bool> ret =
- (node_algorithms::insert_unique_check
- (this->tree_type::header_ptr(), key, comp, commit_data));
+ node_algorithms::insert_unique_check
+ (this->tree_type::header_ptr(), key, this->key_node_comp(comp), commit_data);
return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
}
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- comp(key_value_comp, &this->get_value_traits());
std::pair<node_ptr, bool> ret =
- (node_algorithms::insert_unique_check
- (this->tree_type::header_ptr(), hint.pointed_node(), key, comp, commit_data));
+ node_algorithms::insert_unique_check
+ (this->tree_type::header_ptr(), hint.pointed_node(), key, this->key_node_comp(comp), commit_data);
return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
}
@@ -604,17 +604,15 @@ class sgtree_impl
iterator erase(const_iterator b, const_iterator e)
{ size_type n; return private_erase(b, e, n); }
- //! @copydoc ::boost::intrusive::bstree::erase(const_reference)
- size_type erase(const_reference value)
- { return this->erase(value, this->value_comp()); }
-
- //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
- /// @endcond
- )
+ //! @copydoc ::boost::intrusive::bstree::erase(const key_type &)
+ size_type erase(const key_type &key)
+ { return this->erase(key, this->key_comp()); }
+
+ //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ BOOST_INTRUSIVE_DOC1ST(size_type
+ , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
+ erase(const KeyType& key, KeyTypeKeyCompare comp)
{
std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n;
@@ -643,23 +641,21 @@ class sgtree_impl
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
{ size_type n; return private_erase(b, e, n, disposer); }
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer)
+ size_type erase_and_dispose(const key_type &key, Disposer disposer)
{
- std::pair<iterator,iterator> p = this->equal_range(value);
+ std::pair<iterator,iterator> p = this->equal_range(key);
size_type n;
private_erase(p.first, p.second, n, disposer);
return n;
}
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
- /// @endcond
- )
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ BOOST_INTRUSIVE_DOC1ST(size_type
+ , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
+ erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer)
{
std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n;
@@ -683,88 +679,88 @@ class sgtree_impl
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -796,6 +792,20 @@ class sgtree_impl
//! @copydoc ::boost::intrusive::bstree::rebalance_subtree
iterator rebalance_subtree(iterator root);
+ friend bool operator< (const sgtree_impl &x, const sgtree_impl &y);
+
+ friend bool operator==(const sgtree_impl &x, const sgtree_impl &y);
+
+ friend bool operator!= (const sgtree_impl &x, const sgtree_impl &y);
+
+ friend bool operator>(const sgtree_impl &x, const sgtree_impl &y);
+
+ friend bool operator<=(const sgtree_impl &x, const sgtree_impl &y);
+
+ friend bool operator>=(const sgtree_impl &x, const sgtree_impl &y);
+
+ friend void swap(sgtree_impl &x, sgtree_impl &y);
+
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! <b>Returns</b>: The balance factor (alpha) used in this tree
@@ -850,30 +860,6 @@ class sgtree_impl
/// @endcond
};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-
-template<class T, class ...Options>
-bool operator< (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator==(const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator!= (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator>(const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator<=(const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator>=(const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-void swap(sgtree_impl<T, Options...> &x, sgtree_impl<T, Options...> &y);
-
-#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! Helper metafunction to define a \c sgtree that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
@@ -882,7 +868,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_sgtree
{
@@ -890,7 +876,7 @@ struct make_sgtree
typedef typename pack_options
< sgtree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -901,6 +887,7 @@ struct make_sgtree
typedef sgtree_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::floating_point
@@ -914,14 +901,14 @@ struct make_sgtree
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class sgtree
: public make_sgtree<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -930,7 +917,7 @@ class sgtree
typedef typename make_sgtree
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -938,7 +925,7 @@ class sgtree
BOOST_MOVABLE_BUT_NOT_COPYABLE(sgtree)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -948,14 +935,14 @@ class sgtree
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit sgtree( const value_compare &cmp = value_compare()
+ explicit sgtree( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
sgtree( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, v_traits)
{}
@@ -967,6 +954,14 @@ class sgtree
sgtree& operator=(BOOST_RV_REF(sgtree) x)
{ return static_cast<sgtree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const sgtree &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(sgtree) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static sgtree &container_from_end_iterator(iterator end_iterator)
{ return static_cast<sgtree &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/slist.hpp b/boost/intrusive/slist.hpp
index 757508149b..dd3a05f2f8 100644
--- a/boost/intrusive/slist.hpp
+++ b/boost/intrusive/slist.hpp
@@ -416,8 +416,7 @@ class slist_impl
void push_front(reference value)
{
node_ptr to_insert = priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert));
if(cache_last){
if(this->empty()){
this->set_last_node(to_insert);
@@ -442,8 +441,7 @@ class slist_impl
{
BOOST_STATIC_ASSERT((cache_last));
node_ptr n = priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n));
node_algorithms::link_after(this->get_last_node(), n);
if(cache_last){
this->set_last_node(n);
@@ -768,6 +766,34 @@ class slist_impl
rollback.release();
}
+ //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
+ //!
+ //! <b>Effects</b>: Erases all the elements from *this
+ //! calling Disposer::operator()(pointer), clones all the
+ //! elements from src calling Cloner::operator()(reference)
+ //! and inserts them on *this.
+ //!
+ //! If cloner throws, all cloned elements are unlinked and disposed
+ //! calling Disposer::operator()(pointer).
+ //!
+ //! <b>Complexity</b>: Linear to erased plus inserted elements.
+ //!
+ //! <b>Throws</b>: If cloner throws.
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(slist_impl) src, Cloner cloner, Disposer disposer)
+ {
+ this->clear_and_dispose(disposer);
+ detail::exception_disposer<slist_impl, Disposer>
+ rollback(*this, disposer);
+ iterator prev(this->cbefore_begin());
+ iterator b(src.begin()), e(src.end());
+ for(; b != e; ++b){
+ prev = this->insert_after(prev, *cloner(*b));
+ }
+ rollback.release();
+ }
+
//! <b>Requires</b>: value must be an lvalue and prev_p must point to an element
//! contained by the list or to end().
//!
@@ -784,8 +810,7 @@ class slist_impl
iterator insert_after(const_iterator prev_p, reference value)
{
node_ptr n = priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n));
node_ptr prev_n(prev_p.pointed_node());
node_algorithms::link_after(prev_n, n);
if(cache_last && (this->get_last_node() == prev_n)){
@@ -815,8 +840,7 @@ class slist_impl
node_ptr prev_n(prev_p.pointed_node());
for (; f != l; ++f, ++count){
const node_ptr n = priv_value_traits().to_node_ptr(*f);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n));
node_algorithms::link_after(prev_n, n);
prev_n = n;
}
@@ -1028,6 +1052,15 @@ class slist_impl
/// @cond
+ static iterator s_insert_after(const_iterator const prev_p, reference value)
+ {
+ BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits)));
+ node_ptr const n = value_traits::to_node_ptr(value);
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n));
+ node_algorithms::link_after(prev_p.pointed_node(), n);
+ return iterator (n, const_value_traits_ptr());
+ }
+
template<class Disposer>
static iterator s_erase_after_and_dispose(const_iterator prev, Disposer disposer)
{
@@ -1044,6 +1077,23 @@ class slist_impl
return it.unconst();
}
+ template<class Disposer>
+ static iterator s_erase_after_and_dispose(const_iterator before_f, const_iterator l, Disposer disposer)
+ {
+ BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits)));
+ node_ptr bfp(before_f.pointed_node()), lp(l.pointed_node());
+ node_ptr fp(node_traits::get_next(bfp));
+ node_algorithms::unlink_after(bfp, lp);
+ while(fp != lp){
+ node_ptr to_erase(fp);
+ fp = node_traits::get_next(fp);
+ if(safemode_or_autounlink)
+ node_algorithms::init(to_erase);
+ disposer(value_traits::to_value_ptr(to_erase));
+ }
+ return l.unconst();
+ }
+
static iterator s_erase_after(const_iterator prev)
{ return s_erase_after_and_dispose(prev, detail::null_disposer()); }
@@ -1905,6 +1955,33 @@ class slist_impl
BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count);
}
+
+ friend bool operator==(const slist_impl &x, const slist_impl &y)
+ {
+ if(constant_time_size && x.size() != y.size()){
+ return false;
+ }
+ return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
+ }
+
+ friend bool operator!=(const slist_impl &x, const slist_impl &y)
+ { return !(x == y); }
+
+ friend bool operator<(const slist_impl &x, const slist_impl &y)
+ { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+
+ friend bool operator>(const slist_impl &x, const slist_impl &y)
+ { return y < x; }
+
+ friend bool operator<=(const slist_impl &x, const slist_impl &y)
+ { return !(y < x); }
+
+ friend bool operator>=(const slist_impl &x, const slist_impl &y)
+ { return !(x < y); }
+
+ friend void swap(slist_impl &x, slist_impl &y)
+ { x.swap(y); }
+
private:
void priv_splice_after(const node_ptr & prev_pos_n, slist_impl &x, const node_ptr & before_f_n, const node_ptr & before_l_n)
{
@@ -2044,111 +2121,6 @@ class slist_impl
}
};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator<
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-bool operator==
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{
- typedef slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> slist_type;
- const bool C = slist_type::constant_time_size;
- if(C && x.size() != y.size()){
- return false;
- }
- return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
-}
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator!=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return !(x == y); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator>
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return y < x; }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator<=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return !(y < x); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator>=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return !(x < y); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline void swap
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(slist_impl<T, Options...> &x, slist_impl<T, Options...> &y)
-#else
-( slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ x.swap(y); }
-
//! Helper metafunction to define a \c slist that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
@@ -2241,6 +2213,14 @@ class slist
slist& operator=(BOOST_RV_REF(slist) x)
{ return static_cast<slist &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const slist &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(slist) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static slist &container_from_end_iterator(iterator end_iterator)
{ return static_cast<slist &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/splay_set.hpp b/boost/intrusive/splay_set.hpp
index 80887dffdc..eea19d7999 100644
--- a/boost/intrusive/splay_set.hpp
+++ b/boost/intrusive/splay_set.hpp
@@ -40,15 +40,15 @@ namespace intrusive {
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class splay_set_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public splaytree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, HeaderHolder>
+ : public splaytree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, HeaderHolder>
#endif
{
/// @cond
- typedef splaytree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
+ typedef splaytree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(splay_set_impl)
typedef tree_type implementation_defined;
@@ -56,6 +56,8 @@ class splay_set_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -79,16 +81,16 @@ class splay_set_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::splaytree::splaytree(const value_compare &,const value_traits &)
- explicit splay_set_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::splaytree::splaytree(const key_compare &,const value_traits &)
+ explicit splay_set_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::splaytree::splaytree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::splaytree::splaytree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
splay_set_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(true, b, e, cmp, v_traits)
{}
@@ -169,11 +171,20 @@ class splay_set_impl
//! @copydoc ::boost::intrusive::splaytree::swap
void swap(splay_set_impl& other);
- //! @copydoc ::boost::intrusive::splaytree::clone_from
+ //! @copydoc ::boost::intrusive::splaytree::clone_from(const splaytree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const splay_set_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::splaytree::clone_from(splaytree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(splay_set_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::splaytree::insert_unique(reference)
std::pair<iterator, bool> insert(reference value)
@@ -183,18 +194,18 @@ class splay_set_impl
iterator insert(const_iterator hint, reference value)
{ return tree_type::insert_unique(hint, value); }
- //! @copydoc ::boost::intrusive::splaytree::insert_unique_check(const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::splaytree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(key, key_value_comp, commit_data); }
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(key, comp, commit_data); }
- //! @copydoc ::boost::intrusive::splaytree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::splaytree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(hint, key, key_value_comp, commit_data); }
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(hint, key, comp, commit_data); }
//! @copydoc ::boost::intrusive::splaytree::insert_unique(Iterator,Iterator)
template<class Iterator>
@@ -221,12 +232,12 @@ class splay_set_impl
//! @copydoc ::boost::intrusive::splaytree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::splaytree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -236,13 +247,13 @@ class splay_set_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::splaytree::clear
void clear();
@@ -253,107 +264,107 @@ class splay_set_impl
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::splaytree::count(const_reference)const
- size_type count(const_reference value) const
- { return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
+ //! @copydoc ::boost::intrusive::splaytree::count(const key_type &)const
+ size_type count(const key_type &key) const
+ { return static_cast<size_type>(this->tree_type::find(key) != this->tree_type::cend()); }
- //! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const
+ //! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::splaytree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::splaytree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::splaytree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::splaytree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->tree_type::lower_bound_range(value); }
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key)
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp)
{ return this->tree_type::lower_bound_range(key, comp); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->tree_type::lower_bound_range(value); }
+ equal_range(const key_type &key) const
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const
{ return this->tree_type::lower_bound_range(key, comp); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const key_type&,const key_type&,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const key_type&,const key_type&,bool,bool)const
std::pair<const_iterator, const_iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::splaytree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -382,12 +393,12 @@ class splay_set_impl
//! @copydoc ::boost::intrusive::splaytree::splay_up(iterator)
void splay_up(iterator i);
- //! @copydoc ::boost::intrusive::splaytree::splay_down(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator splay_down(const KeyType &key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::splay_down(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator splay_down(const KeyType &key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::splay_down(const_reference)
- iterator splay_down(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::splay_down(const key_type &key)
+ iterator splay_down(const key_type &key);
//! @copydoc ::boost::intrusive::splaytree::rebalance
void rebalance();
@@ -423,7 +434,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_splay_set
{
@@ -431,7 +442,7 @@ struct make_splay_set
typedef typename pack_options
< splaytree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -442,6 +453,7 @@ struct make_splay_set
typedef splay_set_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -453,14 +465,14 @@ struct make_splay_set
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class splay_set
: public make_splay_set<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -469,7 +481,7 @@ class splay_set
typedef typename make_splay_set
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -477,7 +489,7 @@ class splay_set
BOOST_MOVABLE_BUT_NOT_COPYABLE(splay_set)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -485,14 +497,14 @@ class splay_set
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit splay_set( const value_compare &cmp = value_compare()
+ explicit splay_set( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
splay_set( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -504,6 +516,14 @@ class splay_set
splay_set& operator=(BOOST_RV_REF(splay_set) x)
{ return static_cast<splay_set &>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const splay_set &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(splay_set) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static splay_set &container_from_end_iterator(iterator end_iterator)
{ return static_cast<splay_set &>(Base::container_from_end_iterator(end_iterator)); }
@@ -533,15 +553,15 @@ class splay_set
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class splay_multiset_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public splaytree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, HeaderHolder>
+ : public splaytree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, HeaderHolder>
#endif
{
/// @cond
- typedef splaytree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
+ typedef splaytree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(splay_multiset_impl)
typedef tree_type implementation_defined;
@@ -549,6 +569,8 @@ class splay_multiset_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -572,16 +594,16 @@ class splay_multiset_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::splaytree::splaytree(const value_compare &,const value_traits &)
- explicit splay_multiset_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::splaytree::splaytree(const key_compare &,const value_traits &)
+ explicit splay_multiset_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::splaytree::splaytree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::splaytree::splaytree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
splay_multiset_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(false, b, e, cmp, v_traits)
{}
@@ -662,11 +684,20 @@ class splay_multiset_impl
//! @copydoc ::boost::intrusive::splaytree::swap
void swap(splay_multiset_impl& other);
- //! @copydoc ::boost::intrusive::splaytree::clone_from
+ //! @copydoc ::boost::intrusive::splaytree::clone_from(const splaytree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const splay_multiset_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::splaytree::clone_from(splaytree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(splay_multiset_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::splaytree::insert_equal(reference)
iterator insert(reference value)
@@ -697,12 +728,12 @@ class splay_multiset_impl
//! @copydoc ::boost::intrusive::splaytree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::splaytree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::erase(const key_type&)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -712,13 +743,13 @@ class splay_multiset_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const key_type&, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::splaytree::clear
void clear();
@@ -727,88 +758,88 @@ class splay_multiset_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::splaytree::count(const_reference)
- size_type count(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::count(const key_type&)
+ size_type count(const key_type&);
- //! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const key_type&)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const key_type&)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const key_type&)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const key_type&)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::splaytree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::find(const key_type&)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::splaytree::find(const key_type&)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::splaytree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::equal_range(const key_type&)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::splaytree::equal_range(const key_type&)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::splaytree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const key_type&, const key_type&,bool,bool)
std::pair<iterator,iterator> bounded_range
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const key_type&, const key_type&,bool,bool)const
std::pair<const_iterator, const_iterator> bounded_range
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::splaytree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -837,12 +868,12 @@ class splay_multiset_impl
//! @copydoc ::boost::intrusive::splaytree::splay_up(iterator)
void splay_up(iterator i);
- //! @copydoc ::boost::intrusive::splaytree::splay_down(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator splay_down(const KeyType &key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::splay_down(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator splay_down(const KeyType &key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::splay_down(const_reference)
- iterator splay_down(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::splay_down(const key_type &key)
+ iterator splay_down(const key_type &key);
//! @copydoc ::boost::intrusive::splaytree::rebalance
void rebalance();
@@ -878,7 +909,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_splay_multiset
{
@@ -886,7 +917,7 @@ struct make_splay_multiset
typedef typename pack_options
< splaytree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -897,6 +928,7 @@ struct make_splay_multiset
typedef splay_multiset_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -909,14 +941,14 @@ struct make_splay_multiset
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class splay_multiset
: public make_splay_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -924,7 +956,7 @@ class splay_multiset
{
typedef typename make_splay_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -933,7 +965,7 @@ class splay_multiset
BOOST_MOVABLE_BUT_NOT_COPYABLE(splay_multiset)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -941,14 +973,14 @@ class splay_multiset
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit splay_multiset( const value_compare &cmp = value_compare()
+ explicit splay_multiset( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
splay_multiset( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -960,6 +992,14 @@ class splay_multiset
splay_multiset& operator=(BOOST_RV_REF(splay_multiset) x)
{ return static_cast<splay_multiset &>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const splay_multiset &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(splay_multiset) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static splay_multiset &container_from_end_iterator(iterator end_iterator)
{ return static_cast<splay_multiset &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/splaytree.hpp b/boost/intrusive/splaytree.hpp
index e3866aa912..27d75df70f 100644
--- a/boost/intrusive/splaytree.hpp
+++ b/boost/intrusive/splaytree.hpp
@@ -40,19 +40,14 @@ namespace intrusive {
/// @cond
struct splaytree_defaults
-{
- typedef default_bstree_hook_applier proto_value_traits;
- static const bool constant_time_size = true;
- typedef std::size_t size_type;
- typedef void compare;
- typedef void header_holder_type;
-};
+ : bstree_defaults
+{};
/// @endcond
//! The class template splaytree is an intrusive splay tree container that
//! is used to construct intrusive splay_set and splay_multiset containers. The no-throw
-//! guarantee holds only, if the value_compare object
+//! guarantee holds only, if the key_compare object
//! doesn't throw.
//!
//! The template parameter \c T is the type to be managed by the container.
@@ -66,17 +61,17 @@ struct splaytree_defaults
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class splaytree_impl
/// @cond
- : public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, SplayTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, SplayTreeAlgorithms, HeaderHolder>
/// @endcond
{
public:
typedef ValueTraits value_traits;
/// @cond
- typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
+ typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
, ConstantTimeSize, SplayTreeAlgorithms
, HeaderHolder> tree_type;
typedef tree_type implementation_defined;
@@ -86,6 +81,7 @@ class splaytree_impl
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
@@ -115,16 +111,16 @@ class splaytree_impl
typedef typename implementation_defined::insert_commit_data insert_commit_data;
- //! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &)
- explicit splaytree_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
+ explicit splaytree_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
splaytree_impl( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{
@@ -210,10 +206,24 @@ class splaytree_impl
//! @copydoc ::boost::intrusive::bstree::swap
void swap(splaytree_impl& other);
- //! @copydoc ::boost::intrusive::bstree::clone_from
+ //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
+ //! Additional notes: it also copies the alpha factor from the source container.
template <class Cloner, class Disposer>
void clone_from(const splaytree_impl &src, Cloner cloner, Disposer disposer);
+ #else //BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(splaytree_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
+
+ #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
iterator insert_equal(reference value);
@@ -230,16 +240,16 @@ class splaytree_impl
//! @copydoc ::boost::intrusive::bstree::insert_unique(const_iterator,reference)
iterator insert_unique(const_iterator hint, reference value);
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data);
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_commit
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data);
@@ -263,12 +273,12 @@ class splaytree_impl
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::bstree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -278,13 +288,13 @@ class splaytree_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::clear
void clear();
@@ -293,120 +303,120 @@ class splaytree_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
//! Additional note: non-const function, splaying is performed.
- size_type count(const_reference value);
+ size_type count(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: non-const function, splaying is performed.
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType &key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
//! Additional note: const function, no splaying is performed
- size_type count(const_reference value) const;
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType &key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
//! Additional note: non-const function, splaying is performed.
- iterator lower_bound(const_reference value);
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
//! Additional note: const function, no splaying is performed
- const_iterator lower_bound(const_reference value) const;
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "key"
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "value"
- iterator upper_bound(const_reference value);
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
//! Additional note: const function, no splaying is performed
- const_iterator upper_bound(const_reference value) const;
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "key"
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "value"
- iterator find(const_reference value);
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
//! Additional note: const function, no splaying is performed
- const_iterator find(const_reference value) const;
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "key"
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType &key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType &key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "value"
- std::pair<iterator, iterator> equal_range(const_reference value);
+ std::pair<iterator, iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
//! Additional note: const function, no splaying is performed
- std::pair<const_iterator, const_iterator> equal_range(const_reference value) const;
+ std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "key"
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator, iterator> equal_range(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator, iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
- template<class KeyType, class KeyValueCompare>
- std::pair<const_iterator, const_iterator> equal_range(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<const_iterator, const_iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -455,8 +465,8 @@ class splaytree_impl
//! <b>Returns</b>: An iterator to the new root of the tree, end() if the tree is empty.
//!
//! <b>Throws</b>: If the comparison functor throws.
- template<class KeyType, class KeyValueCompare>
- iterator splay_down(const KeyType &key, KeyValueCompare comp)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator splay_down(const KeyType &key, KeyTypeKeyCompare comp)
{
detail::key_nodeptr_comp<value_compare, value_traits>
key_node_comp(comp, &this->get_value_traits());
@@ -473,8 +483,8 @@ class splaytree_impl
//! <b>Returns</b>: An iterator to the new root of the tree, end() if the tree is empty.
//!
//! <b>Throws</b>: If the predicate throws.
- iterator splay_down(const_reference value)
- { return this->splay_down(value, this->value_comp()); }
+ iterator splay_down(const key_type &key)
+ { return this->splay_down(key, this->key_comp()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree::rebalance
@@ -482,33 +492,23 @@ class splaytree_impl
//! @copydoc ::boost::intrusive::bstree::rebalance_subtree
iterator rebalance_subtree(iterator root);
- #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
-};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ friend bool operator< (const splaytree_impl &x, const splaytree_impl &y);
-template<class T, class ...Options>
-bool operator< (const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
+ friend bool operator==(const splaytree_impl &x, const splaytree_impl &y);
-template<class T, class ...Options>
-bool operator==(const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
+ friend bool operator!= (const splaytree_impl &x, const splaytree_impl &y);
-template<class T, class ...Options>
-bool operator!= (const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
+ friend bool operator>(const splaytree_impl &x, const splaytree_impl &y);
-template<class T, class ...Options>
-bool operator>(const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
+ friend bool operator<=(const splaytree_impl &x, const splaytree_impl &y);
-template<class T, class ...Options>
-bool operator<=(const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
+ friend bool operator>=(const splaytree_impl &x, const splaytree_impl &y);
-template<class T, class ...Options>
-bool operator>=(const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-void swap(splaytree_impl<T, Options...> &x, splaytree_impl<T, Options...> &y);
+ friend void swap(splaytree_impl &x, splaytree_impl &y);
-#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+};
//! Helper metafunction to define a \c splaytree that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
@@ -517,7 +517,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_splaytree
{
@@ -525,7 +525,7 @@ struct make_splaytree
typedef typename pack_options
< splaytree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -536,6 +536,7 @@ struct make_splaytree
typedef splaytree_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -549,14 +550,14 @@ struct make_splaytree
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class splaytree
: public make_splaytree<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -565,7 +566,7 @@ class splaytree
typedef typename make_splaytree
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -573,7 +574,7 @@ class splaytree
BOOST_MOVABLE_BUT_NOT_COPYABLE(splaytree)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -583,14 +584,14 @@ class splaytree
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit splaytree( const value_compare &cmp = value_compare()
+ explicit splaytree( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
splaytree( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, v_traits)
{}
@@ -602,6 +603,14 @@ class splaytree
splaytree& operator=(BOOST_RV_REF(splaytree) x)
{ return static_cast<splaytree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const splaytree &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(splaytree) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static splaytree &container_from_end_iterator(iterator end_iterator)
{ return static_cast<splaytree &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/treap.hpp b/boost/intrusive/treap.hpp
index bf374696fb..52785dafb0 100644
--- a/boost/intrusive/treap.hpp
+++ b/boost/intrusive/treap.hpp
@@ -47,20 +47,16 @@ namespace intrusive {
/// @cond
struct treap_defaults
+ : bstree_defaults
{
- typedef default_bstree_hook_applier proto_value_traits;
- static const bool constant_time_size = true;
- typedef std::size_t size_type;
- typedef void compare;
typedef void priority;
- typedef void header_holder_type;
};
/// @endcond
//! The class template treap is an intrusive treap container that
//! is used to construct intrusive set and multiset containers. The no-throw
-//! guarantee holds only, if the value_compare object and priority_compare object
+//! guarantee holds only, if the key_compare object and priority_compare object
//! don't throw.
//!
//! The template parameter \c T is the type to be managed by the container.
@@ -74,24 +70,24 @@ struct treap_defaults
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyComp, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class treap_impl
/// @cond
- : public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>
//Use public inheritance to avoid MSVC bugs with closures
, public detail::ebo_functor_holder
< typename get_prio
< VoidOrPrioComp
, typename bstree_impl
- <ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>::value_type>::type
+ <ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>::value_type>::type
>
/// @endcond
{
public:
typedef ValueTraits value_traits;
/// @cond
- typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
+ typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
, ConstantTimeSize, BsTreeAlgorithms
, HeaderHolder> tree_type;
typedef tree_type implementation_defined;
@@ -108,6 +104,7 @@ class treap_impl
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
@@ -129,6 +126,15 @@ class treap_impl
static const bool stateful_value_traits = implementation_defined::stateful_value_traits;
static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
+ typedef detail::key_nodeptr_comp<priority_compare, value_traits> value_node_prio_comp_t;
+
+ template<class KeyPrioComp>
+ detail::key_nodeptr_comp<KeyPrioComp, value_traits> key_node_prio_comp(KeyPrioComp keypriocomp) const
+ { return detail::key_nodeptr_comp<KeyPrioComp, value_traits>(keypriocomp, &this->get_value_traits()); }
+
+ value_node_prio_comp_t value_node_prio_comp() const
+ { return this->key_node_prio_comp(this->priv_pcomp()); }
+
/// @cond
private:
@@ -153,7 +159,7 @@ class treap_impl
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or the copy constructor of the value_compare/priority_compare objects throw. Basic guarantee.
- explicit treap_impl( const value_compare &cmp = value_compare()
+ explicit treap_impl( const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits), prio_base(pcmp)
@@ -170,11 +176,11 @@ class treap_impl
//!
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor/operator() of the value_compare/priority_compare objects
+ //! or the copy constructor/operator() of the key_compare/priority_compare objects
//! throw. Basic guarantee.
template<class Iterator>
treap_impl( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits), prio_base(pcmp)
@@ -356,6 +362,27 @@ class treap_impl
this->priv_pcomp() = src.priv_pcomp();
}
+ //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
+ //!
+ //! <b>Effects</b>: Erases all the elements from *this
+ //! calling Disposer::operator()(pointer), clones all the
+ //! elements from src calling Cloner::operator()(reference)
+ //! and inserts them on *this. Copies the predicate from the source container.
+ //!
+ //! If cloner throws, all cloned elements are unlinked and disposed
+ //! calling Disposer::operator()(pointer).
+ //!
+ //! <b>Complexity</b>: Linear to erased plus inserted elements.
+ //!
+ //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(treap_impl) src, Cloner cloner, Disposer disposer)
+ {
+ tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer);
+ this->priv_pcomp() = ::boost::move(src.priv_pcomp());
+ }
+
//! <b>Requires</b>: value must be an lvalue
//!
//! <b>Effects</b>: Inserts value into the container before the upper bound.
@@ -363,21 +390,21 @@ class treap_impl
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
- //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw. Strong guarantee.
+ //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw. Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
iterator insert_equal(reference value)
{
- detail::key_nodeptr_comp<value_compare, value_traits>
- key_node_comp(this->value_comp(), &this->get_value_traits());
- detail::key_nodeptr_comp<priority_compare, value_traits>
- key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
- iterator ret(node_algorithms::insert_equal_upper_bound
- (this->tree_type::header_ptr(), to_insert, key_node_comp, key_node_pcomp), this->priv_value_traits_ptr());
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
+ iterator ret
+ ( node_algorithms::insert_equal_upper_bound
+ ( this->tree_type::header_ptr()
+ , to_insert
+ , this->key_node_comp(this->key_comp())
+ , this->value_node_prio_comp())
+ , this->priv_value_traits_ptr());
this->tree_type::sz_traits().increment();
return ret;
}
@@ -392,21 +419,22 @@ class treap_impl
//! <b>Complexity</b>: Logarithmic in general, but it is amortized
//! constant time if t is inserted immediately before hint.
//!
- //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw. Strong guarantee.
+ //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw. Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
iterator insert_equal(const_iterator hint, reference value)
{
- detail::key_nodeptr_comp<value_compare, value_traits>
- key_node_comp(this->value_comp(), &this->get_value_traits());
- detail::key_nodeptr_comp<priority_compare, value_traits>
- key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
- iterator ret (node_algorithms::insert_equal
- (this->tree_type::header_ptr(), hint.pointed_node(), to_insert, key_node_comp, key_node_pcomp), this->priv_value_traits_ptr());
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
+ iterator ret
+ (node_algorithms::insert_equal
+ ( this->tree_type::header_ptr()
+ , hint.pointed_node()
+ , to_insert
+ , this->key_node_comp(this->key_comp())
+ , this->value_node_prio_comp())
+ , this->priv_value_traits_ptr());
this->tree_type::sz_traits().increment();
return ret;
}
@@ -419,9 +447,9 @@ class treap_impl
//!
//! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
//! size of the range. However, it is linear in N if the range is already sorted
- //! by value_comp().
+ //! by key_comp().
//!
- //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
+ //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -442,7 +470,7 @@ class treap_impl
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
- //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
+ //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -450,10 +478,11 @@ class treap_impl
std::pair<iterator, bool> insert_unique(reference value)
{
insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(value, this->value_comp(), this->priv_pcomp(), commit_data);
+ std::pair<iterator, bool> ret = this->insert_unique_check
+ (value, this->comp(), this->priv_pcomp(), commit_data);
if(!ret.second)
return ret;
- return std::pair<iterator, bool> (insert_unique_commit(value, commit_data), true);
+ return std::pair<iterator, bool> (this->insert_unique_commit(value, commit_data), true);
}
//! <b>Requires</b>: value must be an lvalue, and "hint" must be
@@ -466,7 +495,7 @@ class treap_impl
//! constant time (two comparisons in the worst case)
//! if t is inserted immediately before hint.
//!
- //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
+ //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -474,10 +503,11 @@ class treap_impl
iterator insert_unique(const_iterator hint, reference value)
{
insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(hint, value, this->value_comp(), this->priv_pcomp(), commit_data);
+ std::pair<iterator, bool> ret = this->insert_unique_check
+ (hint, value, this->comp(), this->priv_pcomp(), commit_data);
if(!ret.second)
return ret.first;
- return insert_unique_commit(value, commit_data);
+ return this->insert_unique_commit(value, commit_data);
}
//! <b>Requires</b>: Dereferencing iterator must yield an lvalue
@@ -487,9 +517,9 @@ class treap_impl
//!
//! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
//! size of the range. However, it is linear in N if the range is already sorted
- //! by value_comp().
+ //! by key_comp().
//!
- //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
+ //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -508,11 +538,11 @@ class treap_impl
}
}
- //! <b>Requires</b>: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare.
+ //! <b>Requires</b>: comp must be a comparison function that induces
+ //! the same strict weak ordering as key_compare.
//! key_value_pcomp must be a comparison function that induces
//! the same strict weak ordering as priority_compare. The difference is that
- //! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
+ //! key_value_pcomp and comp compare an arbitrary key with the contained values.
//!
//! <b>Effects</b>: Checks if a value can be inserted in the container, using
//! a user provided key instead of the value itself.
@@ -525,7 +555,7 @@ class treap_impl
//!
//! <b>Complexity</b>: Average complexity is at most logarithmic.
//!
- //! <b>Throws</b>: If the key_value_comp or key_value_pcomp
+ //! <b>Throws</b>: If the comp or key_value_pcomp
//! ordering functions throw. Strong guarantee.
//!
//! <b>Notes</b>: This function is used to improve performance when constructing
@@ -541,26 +571,23 @@ class treap_impl
//!
//! "commit_data" remains valid for a subsequent "insert_commit" only if no more
//! objects are inserted or erased from the container.
- template<class KeyType, class KeyValueCompare, class KeyValuePrioCompare>
+ template<class KeyType, class KeyTypeKeyCompare, class KeyValuePrioCompare>
std::pair<iterator, bool> insert_unique_check
- ( const KeyType &key, KeyValueCompare key_value_comp
+ ( const KeyType &key, KeyTypeKeyCompare comp
, KeyValuePrioCompare key_value_pcomp, insert_commit_data &commit_data)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- ocomp(key_value_comp, &this->get_value_traits());
- detail::key_nodeptr_comp<KeyValuePrioCompare, value_traits>
- pcomp(key_value_pcomp, &this->get_value_traits());
- std::pair<node_ptr, bool> ret =
+ std::pair<node_ptr, bool> const ret =
(node_algorithms::insert_unique_check
- (this->tree_type::header_ptr(), key, ocomp, pcomp, commit_data));
+ ( this->tree_type::header_ptr(), key
+ , this->key_node_comp(comp), this->key_node_prio_comp(key_value_pcomp), commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
}
- //! <b>Requires</b>: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare.
+ //! <b>Requires</b>: comp must be a comparison function that induces
+ //! the same strict weak ordering as key_compare.
//! key_value_pcomp must be a comparison function that induces
//! the same strict weak ordering as priority_compare. The difference is that
- //! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
+ //! key_value_pcomp and comp compare an arbitrary key with the contained values.
//!
//! <b>Effects</b>: Checks if a value can be inserted in the container, using
//! a user provided key instead of the value itself, using "hint"
@@ -575,7 +602,7 @@ class treap_impl
//! <b>Complexity</b>: Logarithmic in general, but it's amortized
//! constant time if t is inserted immediately before hint.
//!
- //! <b>Throws</b>: If the key_value_comp or key_value_pcomp
+ //! <b>Throws</b>: If the comp or key_value_pcomp
//! ordering functions throw. Strong guarantee.
//!
//! <b>Notes</b>: This function is used to improve performance when constructing
@@ -591,20 +618,17 @@ class treap_impl
//!
//! "commit_data" remains valid for a subsequent "insert_commit" only if no more
//! objects are inserted or erased from the container.
- template<class KeyType, class KeyValueCompare, class KeyValuePrioCompare>
+ template<class KeyType, class KeyTypeKeyCompare, class KeyValuePrioCompare>
std::pair<iterator, bool> insert_unique_check
( const_iterator hint, const KeyType &key
- , KeyValueCompare key_value_comp
+ , KeyTypeKeyCompare comp
, KeyValuePrioCompare key_value_pcomp
, insert_commit_data &commit_data)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- ocomp(key_value_comp, &this->get_value_traits());
- detail::key_nodeptr_comp<KeyValuePrioCompare, value_traits>
- pcomp(key_value_pcomp, &this->get_value_traits());
- std::pair<node_ptr, bool> ret =
+ std::pair<node_ptr, bool> const ret =
(node_algorithms::insert_unique_check
- (this->tree_type::header_ptr(), hint.pointed_node(), key, ocomp, pcomp, commit_data));
+ ( this->tree_type::header_ptr(), hint.pointed_node(), key
+ , this->key_node_comp(comp), this->key_node_prio_comp(key_value_pcomp), commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
}
@@ -628,8 +652,7 @@ class treap_impl
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
{
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
node_algorithms::insert_unique_commit(this->tree_type::header_ptr(), to_insert, commit_data);
this->tree_type::sz_traits().increment();
return iterator(to_insert, this->priv_value_traits_ptr());
@@ -652,12 +675,11 @@ class treap_impl
iterator insert_before(const_iterator pos, reference value)
{
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
- detail::key_nodeptr_comp<priority_compare, value_traits>
- pcomp(this->priv_pcomp(), &this->get_value_traits());
- iterator ret (node_algorithms::insert_before
- (this->tree_type::header_ptr(), pos.pointed_node(), to_insert, pcomp), this->priv_value_traits_ptr());
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
+ iterator ret
+ ( node_algorithms::insert_before
+ ( this->tree_type::header_ptr(), pos.pointed_node(), to_insert, this->value_node_prio_comp())
+ , this->priv_value_traits_ptr());
this->tree_type::sz_traits().increment();
return ret;
}
@@ -679,11 +701,8 @@ class treap_impl
void push_back(reference value)
{
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
- detail::key_nodeptr_comp<priority_compare, value_traits>
- pcomp(this->priv_pcomp(), &this->get_value_traits());
- node_algorithms::push_back(this->tree_type::header_ptr(), to_insert, pcomp);
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
+ node_algorithms::push_back(this->tree_type::header_ptr(), to_insert, this->value_node_prio_comp());
this->tree_type::sz_traits().increment();
}
@@ -704,11 +723,8 @@ class treap_impl
void push_front(reference value)
{
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
- detail::key_nodeptr_comp<priority_compare, value_traits>
- pcomp(this->priv_pcomp(), &this->get_value_traits());
- node_algorithms::push_front(this->tree_type::header_ptr(), to_insert, pcomp);
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
+ node_algorithms::push_front(this->tree_type::header_ptr(), to_insert, this->value_node_prio_comp());
this->tree_type::sz_traits().increment();
}
@@ -725,11 +741,8 @@ class treap_impl
const_iterator ret(i);
++ret;
node_ptr to_erase(i.pointed_node());
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
- detail::key_nodeptr_comp<priority_compare, value_traits>
- key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
- node_algorithms::erase(this->tree_type::header_ptr(), to_erase, key_node_pcomp);
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(to_erase));
+ node_algorithms::erase(this->tree_type::header_ptr(), to_erase, this->value_node_prio_comp());
this->tree_type::sz_traits().decrement();
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
@@ -758,8 +771,8 @@ class treap_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- size_type erase(const_reference value)
- { return this->erase(value, this->value_comp()); }
+ size_type erase(const key_type &key)
+ { return this->erase(key, this->key_comp()); }
//! <b>Effects</b>: Erases all the elements with the given key.
//! according to the comparison functor "comp".
@@ -773,12 +786,10 @@ class treap_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
- /// @endcond
- )
+ template<class KeyType, class KeyTypeKeyCompare>
+ BOOST_INTRUSIVE_DOC1ST(size_type
+ , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
+ erase(const KeyType& key, KeyTypeKeyCompare comp)
{
std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n;
@@ -843,9 +854,9 @@ class treap_impl
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer)
+ size_type erase_and_dispose(const key_type &key, Disposer disposer)
{
- std::pair<iterator,iterator> p = this->equal_range(value);
+ std::pair<iterator,iterator> p = this->equal_range(key);
size_type n;
private_erase(p.first, p.second, n, disposer);
return n;
@@ -866,12 +877,10 @@ class treap_impl
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
- /// @endcond
- )
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ BOOST_INTRUSIVE_DOC1ST(size_type
+ , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
+ erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer)
{
std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n;
@@ -913,9 +922,8 @@ class treap_impl
template <class ExtraChecker>
void check(ExtraChecker extra_checker) const
{
- typedef detail::key_nodeptr_comp<priority_compare, value_traits> nodeptr_prio_comp_t;
- nodeptr_prio_comp_t nodeptr_prio_comp(priv_pcomp(), &this->get_value_traits());
- tree_type::check(detail::treap_node_extra_checker<ValueTraits, nodeptr_prio_comp_t, ExtraChecker>(nodeptr_prio_comp, extra_checker));
+ tree_type::check(detail::treap_node_extra_checker
+ <ValueTraits, value_node_prio_comp_t, ExtraChecker>(this->value_node_prio_comp(), extra_checker));
}
//! @copydoc ::boost::intrusive::bstree::check()const
@@ -923,88 +931,88 @@ class treap_impl
{ check(detail::empty_node_checker<ValueTraits>()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -1030,6 +1038,20 @@ class treap_impl
//! @copydoc ::boost::intrusive::bstree::remove_node
void remove_node(reference value);
+ friend bool operator< (const treap_impl &x, const treap_impl &y);
+
+ friend bool operator==(const treap_impl &x, const treap_impl &y);
+
+ friend bool operator!= (const treap_impl &x, const treap_impl &y);
+
+ friend bool operator>(const treap_impl &x, const treap_impl &y);
+
+ friend bool operator<=(const treap_impl &x, const treap_impl &y);
+
+ friend bool operator>=(const treap_impl &x, const treap_impl &y);
+
+ friend void swap(treap_impl &x, treap_impl &y);
+
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
/// @cond
@@ -1051,30 +1073,6 @@ class treap_impl
/// @endcond
};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-
-template<class T, class ...Options>
-bool operator< (const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator==(const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator!= (const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator>(const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator<=(const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator>=(const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-void swap(treap_impl<T, Options...> &x, treap_impl<T, Options...> &y);
-
-#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! Helper metafunction to define a \c treap that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
@@ -1083,14 +1081,14 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_treap
{
typedef typename pack_options
< treap_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -1101,6 +1099,7 @@ struct make_treap
typedef treap_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::priority
, typename packed_options::size_type
@@ -1114,14 +1113,14 @@ struct make_treap
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class treap
: public make_treap<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -1130,7 +1129,7 @@ class treap
typedef typename make_treap
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -1138,7 +1137,7 @@ class treap
BOOST_MOVABLE_BUT_NOT_COPYABLE(treap)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::priority_compare priority_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
@@ -1149,7 +1148,7 @@ class treap
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit treap( const value_compare &cmp = value_compare()
+ explicit treap( const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, pcmp, v_traits)
@@ -1157,7 +1156,7 @@ class treap
template<class Iterator>
treap( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, pcmp, v_traits)
@@ -1170,6 +1169,14 @@ class treap
treap& operator=(BOOST_RV_REF(treap) x)
{ return static_cast<treap&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const treap &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(treap) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static treap &container_from_end_iterator(iterator end_iterator)
{ return static_cast<treap &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/treap_set.hpp b/boost/intrusive/treap_set.hpp
index a88df58e44..188c80fdce 100644
--- a/boost/intrusive/treap_set.hpp
+++ b/boost/intrusive/treap_set.hpp
@@ -40,16 +40,16 @@ namespace intrusive {
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyComp, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class treap_set_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public treap_impl<ValueTraits, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder>
+ : public treap_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder>
#endif
{
/// @cond
public:
- typedef treap_impl<ValueTraits, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
+ typedef treap_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_set_impl)
typedef tree_type implementation_defined;
@@ -58,6 +58,8 @@ class treap_set_impl
public:
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::value_traits value_traits;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::reference reference;
@@ -65,8 +67,8 @@ class treap_set_impl
typedef typename implementation_defined::difference_type difference_type;
typedef typename implementation_defined::size_type size_type;
typedef typename implementation_defined::value_compare value_compare;
- typedef typename implementation_defined::priority_compare priority_compare;
typedef typename implementation_defined::key_compare key_compare;
+ typedef typename implementation_defined::priority_compare priority_compare;
typedef typename implementation_defined::iterator iterator;
typedef typename implementation_defined::const_iterator const_iterator;
typedef typename implementation_defined::reverse_iterator reverse_iterator;
@@ -87,8 +89,8 @@ class treap_set_impl
//!
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor of the value_compare object throws.
- explicit treap_set_impl( const value_compare &cmp = value_compare()
+ //! or the copy constructor of the key_compare object throws.
+ explicit treap_set_impl( const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, pcmp, v_traits)
@@ -105,10 +107,10 @@ class treap_set_impl
//!
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor/operator() of the value_compare object throws.
+ //! or the copy constructor/operator() of the key_compare object throws.
template<class Iterator>
treap_set_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: tree_type(true, b, e, cmp, pcmp, v_traits)
@@ -192,10 +194,23 @@ class treap_set_impl
//! @copydoc ::boost::intrusive::treap::swap
void swap(treap_set_impl& other);
- //! @copydoc ::boost::intrusive::treap::clone_from
+ //! @copydoc ::boost::intrusive::treap::clone_from(const treap&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const treap_set_impl &src, Cloner cloner, Disposer disposer);
+ #else
+
+ using tree_type::clone_from;
+
+ #endif
+
+ //! @copydoc ::boost::intrusive::treap::clone_from(treap&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(treap_set_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
+
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+
//! @copydoc ::boost::intrusive::treap::top()
iterator top();
@@ -226,20 +241,20 @@ class treap_set_impl
iterator insert(const_iterator hint, reference value)
{ return tree_type::insert_unique(hint, value); }
- //! @copydoc ::boost::intrusive::treap::insert_unique_check(const KeyType&,KeyValueCompare,KeyValuePrioCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare, class KeyValuePrioCompare>
+ //! @copydoc ::boost::intrusive::treap::insert_unique_check(const KeyType&,KeyTypeKeyCompare,KeyValuePrioCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare, class KeyValuePrioCompare>
std::pair<iterator, bool> insert_check
- ( const KeyType &key, KeyValueCompare key_value_comp, KeyValuePrioCompare key_value_pcomp
+ ( const KeyType &key, KeyTypeKeyCompare comp, KeyValuePrioCompare key_value_pcomp
, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(key, key_value_comp, key_value_pcomp, commit_data); }
+ { return tree_type::insert_unique_check(key, comp, key_value_pcomp, commit_data); }
- //! @copydoc ::boost::intrusive::treap::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,KeyValuePrioCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare, class KeyValuePrioCompare>
+ //! @copydoc ::boost::intrusive::treap::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,KeyValuePrioCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare, class KeyValuePrioCompare>
std::pair<iterator, bool> insert_check
( const_iterator hint, const KeyType &key
- , KeyValueCompare key_value_comp, KeyValuePrioCompare key_value_pcomp
+ , KeyTypeKeyCompare comp, KeyValuePrioCompare key_value_pcomp
, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(hint, key, key_value_comp, key_value_pcomp, commit_data); }
+ { return tree_type::insert_unique_check(hint, key, comp, key_value_pcomp, commit_data); }
//! @copydoc ::boost::intrusive::treap::insert_unique(Iterator,Iterator)
template<class Iterator>
@@ -266,12 +281,12 @@ class treap_set_impl
//! @copydoc ::boost::intrusive::treap::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::treap::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::treap::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -281,13 +296,13 @@ class treap_set_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::treap::clear
void clear();
@@ -298,100 +313,100 @@ class treap_set_impl
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::treap::count(const_reference)const
- size_type count(const_reference value) const
- { return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
+ //! @copydoc ::boost::intrusive::treap::count(const key_type &)const
+ size_type count(const key_type &key) const
+ { return static_cast<size_type>(this->tree_type::find(key) != this->tree_type::cend()); }
- //! @copydoc ::boost::intrusive::treap::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const
+ //! @copydoc ::boost::intrusive::treap::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::treap::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::treap::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::treap::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::treap::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::treap::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::treap::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::treap::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->tree_type::lower_bound_range(value); }
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key)
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp)
{ return this->tree_type::lower_bound_range(key, comp); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->tree_type::lower_bound_range(value); }
+ equal_range(const key_type &key) const
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const
{ return this->tree_type::lower_bound_range(key, comp); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::treap::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::treap::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::treap::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -428,14 +443,14 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_treap_set
{
typedef typename pack_options
< treap_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -446,6 +461,7 @@ struct make_treap_set
typedef treap_set_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::priority
, typename packed_options::size_type
@@ -459,14 +475,14 @@ struct make_treap_set
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class treap_set
: public make_treap_set<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -475,7 +491,7 @@ class treap_set
typedef typename make_treap_set
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -483,7 +499,7 @@ class treap_set
BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_set)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::priority_compare priority_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
@@ -492,7 +508,7 @@ class treap_set
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit treap_set( const value_compare &cmp = value_compare()
+ explicit treap_set( const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, pcmp, v_traits)
@@ -500,7 +516,7 @@ class treap_set
template<class Iterator>
treap_set( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, pcmp, v_traits)
@@ -513,6 +529,14 @@ class treap_set
treap_set& operator=(BOOST_RV_REF(treap_set) x)
{ return static_cast<treap_set &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const treap_set &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(treap_set) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static treap_set &container_from_end_iterator(iterator end_iterator)
{ return static_cast<treap_set &>(Base::container_from_end_iterator(end_iterator)); }
@@ -542,15 +566,15 @@ class treap_set
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyComp, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class treap_multiset_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public treap_impl<ValueTraits, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder>
+ : public treap_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder>
#endif
{
/// @cond
- typedef treap_impl<ValueTraits, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
+ typedef treap_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_multiset_impl)
typedef tree_type implementation_defined;
@@ -559,6 +583,8 @@ class treap_multiset_impl
public:
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::value_traits value_traits;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::reference reference;
@@ -566,8 +592,8 @@ class treap_multiset_impl
typedef typename implementation_defined::difference_type difference_type;
typedef typename implementation_defined::size_type size_type;
typedef typename implementation_defined::value_compare value_compare;
- typedef typename implementation_defined::priority_compare priority_compare;
typedef typename implementation_defined::key_compare key_compare;
+ typedef typename implementation_defined::priority_compare priority_compare;
typedef typename implementation_defined::iterator iterator;
typedef typename implementation_defined::const_iterator const_iterator;
typedef typename implementation_defined::reverse_iterator reverse_iterator;
@@ -588,8 +614,8 @@ class treap_multiset_impl
//!
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor of the value_compare object throws.
- explicit treap_multiset_impl( const value_compare &cmp = value_compare()
+ //! or the copy constructor of the key_compare object throws.
+ explicit treap_multiset_impl( const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, pcmp, v_traits)
@@ -606,10 +632,10 @@ class treap_multiset_impl
//!
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor/operator() of the value_compare object throws.
+ //! or the copy constructor/operator() of the key_compare object throws.
template<class Iterator>
treap_multiset_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: tree_type(false, b, e, cmp, pcmp, v_traits)
@@ -693,10 +719,23 @@ class treap_multiset_impl
//! @copydoc ::boost::intrusive::treap::swap
void swap(treap_multiset_impl& other);
- //! @copydoc ::boost::intrusive::treap::clone_from
+ //! @copydoc ::boost::intrusive::treap::clone_from(const treap&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const treap_multiset_impl &src, Cloner cloner, Disposer disposer);
+ #else
+
+ using tree_type::clone_from;
+
+ #endif
+
+ //! @copydoc ::boost::intrusive::treap::clone_from(treap&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(treap_multiset_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
+
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+
//! @copydoc ::boost::intrusive::treap::top()
iterator top();
@@ -748,12 +787,12 @@ class treap_multiset_impl
//! @copydoc ::boost::intrusive::treap::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::treap::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::treap::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -763,13 +802,13 @@ class treap_multiset_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::treap::clear
void clear();
@@ -778,88 +817,88 @@ class treap_multiset_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::treap::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::treap::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::treap::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::treap::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::treap::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::treap::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::treap::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::treap::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::treap::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::treap::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::treap::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::treap::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::treap::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::treap::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::treap::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::treap::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::treap::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -896,14 +935,14 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_treap_multiset
{
typedef typename pack_options
< treap_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -914,6 +953,7 @@ struct make_treap_multiset
typedef treap_multiset_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::priority
, typename packed_options::size_type
@@ -927,14 +967,14 @@ struct make_treap_multiset
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class treap_multiset
: public make_treap_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -943,7 +983,7 @@ class treap_multiset
typedef typename make_treap_multiset
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -951,7 +991,7 @@ class treap_multiset
BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_multiset)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::priority_compare priority_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
@@ -960,7 +1000,7 @@ class treap_multiset
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit treap_multiset( const value_compare &cmp = value_compare()
+ explicit treap_multiset( const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, pcmp, v_traits)
@@ -968,7 +1008,7 @@ class treap_multiset
template<class Iterator>
treap_multiset( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, pcmp, v_traits)
@@ -981,6 +1021,14 @@ class treap_multiset
treap_multiset& operator=(BOOST_RV_REF(treap_multiset) x)
{ return static_cast<treap_multiset &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const treap_multiset &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(treap_multiset) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static treap_multiset &container_from_end_iterator(iterator end_iterator)
{ return static_cast<treap_multiset &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/unordered_set.hpp b/boost/intrusive/unordered_set.hpp
index 4b0c91e741..5148f02f8c 100644
--- a/boost/intrusive/unordered_set.hpp
+++ b/boost/intrusive/unordered_set.hpp
@@ -64,14 +64,24 @@ namespace intrusive {
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Hash, class Equal, class SizeType, class BucketTraits, std::size_t BoolFlags>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class SizeType, class BucketTraits, std::size_t BoolFlags>
#endif
class unordered_set_impl
- : public hashtable_impl<ValueTraits, Hash, Equal, SizeType, BucketTraits, BoolFlags>
+ : public hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags|hash_bool_flags::unique_keys_pos>
{
/// @cond
private:
- typedef hashtable_impl<ValueTraits, Hash, Equal, SizeType, BucketTraits, BoolFlags> table_type;
+ typedef hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags|hash_bool_flags::unique_keys_pos> table_type;
+
+ template<class Iterator, class MaybeConstThis, class KeyType, class KeyHasher, class KeyEqual>
+ static std::pair<Iterator,Iterator> priv_equal_range(MaybeConstThis &c, const KeyType& key, KeyHasher hash_func, KeyEqual equal_func)
+ {
+ Iterator const it = c.find(key, hash_func, equal_func);
+ std::pair<Iterator,Iterator> ret(it, it);
+ if(it != c.end())
+ ++ret.second;
+ return ret;
+ }
//! This class is
//! movable
@@ -82,6 +92,8 @@ class unordered_set_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::bucket_traits bucket_traits;
typedef typename implementation_defined::pointer pointer;
@@ -90,7 +102,6 @@ class unordered_set_impl
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
typedef typename implementation_defined::size_type size_type;
- typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::key_equal key_equal;
typedef typename implementation_defined::hasher hasher;
typedef typename implementation_defined::bucket_type bucket_type;
@@ -108,19 +119,7 @@ class unordered_set_impl
public:
- //! <b>Requires</b>: buckets must not be being used by any other resource.
- //!
- //! <b>Effects</b>: Constructs an empty unordered_set_impl, storing a reference
- //! to the bucket array and copies of the hasher and equal functors.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If value_traits::node_traits::node
- //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor or invocation of Hash or Equal throws.
- //!
- //! <b>Notes</b>: buckets array must be disposed only after
- //! *this is disposed.
+ //! @copydoc ::boost::intrusive::hashtable::hashtable(const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
explicit unordered_set_impl( const bucket_traits &b_traits
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
@@ -128,21 +127,7 @@ class unordered_set_impl
: table_type(b_traits, hash_func, equal_func, v_traits)
{}
- //! <b>Requires</b>: buckets must not be being used by any other resource
- //! and Dereferencing iterator must yield an lvalue of type value_type.
- //!
- //! <b>Effects</b>: Constructs an empty unordered_set and inserts elements from
- //! [b, e).
- //!
- //! <b>Complexity</b>: If N is distance(b, e): Average case is O(N)
- //! (with a good hash function and with buckets_len >= N),worst case O(N2).
- //!
- //! <b>Throws</b>: If value_traits::node_traits::node
- //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor or invocation of hasher or key_equal throws.
- //!
- //! <b>Notes</b>: buckets array must be disposed only after
- //! *this is disposed.
+ //! @copydoc ::boost::intrusive::hashtable::hashtable(bool,Iterator,Iterator,const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
template<class Iterator>
unordered_set_impl( Iterator b
, Iterator e
@@ -150,859 +135,272 @@ class unordered_set_impl
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
, const value_traits &v_traits = value_traits())
- : table_type(b_traits, hash_func, equal_func, v_traits)
- { table_type::insert_unique(b, e); }
+ : table_type(true, b, e, b_traits, hash_func, equal_func, v_traits)
+ {}
- //! <b>Effects</b>: to-do
- //!
+ //! @copydoc ::boost::intrusive::hashtable::hashtable(hashtable&&)
unordered_set_impl(BOOST_RV_REF(unordered_set_impl) x)
: table_type(BOOST_MOVE_BASE(table_type, x))
{}
- //! <b>Effects</b>: to-do
- //!
+ //! @copydoc ::boost::intrusive::hashtable::operator=(hashtable&&)
unordered_set_impl& operator=(BOOST_RV_REF(unordered_set_impl) x)
{ return static_cast<unordered_set_impl&>(table_type::operator=(BOOST_MOVE_BASE(table_type, x))); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! <b>Effects</b>: Detaches all elements from this. The objects in the unordered_set
- //! are not deleted (i.e. no destructors are called).
- //!
- //! <b>Complexity</b>: Linear to the number of elements in the unordered_set, if
- //! it's a safe-mode or auto-unlink value. Otherwise constant.
- //!
- //! <b>Throws</b>: Nothing.
- ~unordered_set_impl()
- {}
+ //! @copydoc ::boost::intrusive::hashtable::~hashtable()
+ ~unordered_set_impl();
- //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_set.
- //!
- //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
- //! constant time with worst case (empty unordered_set) O(this->bucket_count())
- //!
- //! <b>Throws</b>: Nothing.
- iterator begin()
- { return table_type::begin(); }
+ //! @copydoc ::boost::intrusive::hashtable::begin()
+ iterator begin();
- //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
- //! of the unordered_set.
- //!
- //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
- //! constant time with worst case (empty unordered_set) O(this->bucket_count())
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator begin() const
- { return table_type::begin(); }
+ //! @copydoc ::boost::intrusive::hashtable::begin()const
+ const_iterator begin() const;
- //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
- //! of the unordered_set.
- //!
- //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
- //! constant time with worst case (empty unordered_set) O(this->bucket_count())
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator cbegin() const
- { return table_type::cbegin(); }
+ //! @copydoc ::boost::intrusive::hashtable::cbegin()const
+ const_iterator cbegin() const;
- //! <b>Effects</b>: Returns an iterator pointing to the end of the unordered_set.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- iterator end()
- { return table_type::end(); }
+ //! @copydoc ::boost::intrusive::hashtable::end()
+ iterator end();
- //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator end() const
- { return table_type::end(); }
+ //! @copydoc ::boost::intrusive::hashtable::end()const
+ const_iterator end() const;
- //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator cend() const
- { return table_type::cend(); }
+ //! @copydoc ::boost::intrusive::hashtable::cend()const
+ const_iterator cend() const;
- //! <b>Effects</b>: Returns the hasher object used by the unordered_set.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If hasher copy-constructor throws.
- hasher hash_function() const
- { return table_type::hash_function(); }
+ //! @copydoc ::boost::intrusive::hashtable::hash_function()const
+ hasher hash_function() const;
- //! <b>Effects</b>: Returns the key_equal object used by the unordered_set.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If key_equal copy-constructor throws.
- key_equal key_eq() const
- { return table_type::key_eq(); }
+ //! @copydoc ::boost::intrusive::hashtable::key_eq()const
+ key_equal key_eq() const;
- //! <b>Effects</b>: Returns true if the container is empty.
- //!
- //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
- //! average constant time (worst case, with empty() == true: O(this->bucket_count()).
- //! Otherwise constant.
- //!
- //! <b>Throws</b>: Nothing.
- bool empty() const
- { return table_type::empty(); }
+ //! @copydoc ::boost::intrusive::hashtable::empty()const
+ bool empty() const;
- //! <b>Effects</b>: Returns the number of elements stored in the unordered_set.
- //!
- //! <b>Complexity</b>: Linear to elements contained in *this if
- //! constant-time size option is disabled. Constant-time otherwise.
- //!
- //! <b>Throws</b>: Nothing.
- size_type size() const
- { return table_type::size(); }
+ //! @copydoc ::boost::intrusive::hashtable::size()const
+ size_type size() const;
- //! <b>Requires</b>: the hasher and the equality function unqualified swap
- //! call should not throw.
- //!
- //! <b>Effects</b>: Swaps the contents of two unordered_sets.
- //! Swaps also the contained bucket array and equality and hasher functors.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the swap() call for the comparison or hash functors
- //! found using ADL throw. Basic guarantee.
- void swap(unordered_set_impl& other)
- { table_type::swap(other.table_); }
-
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //! Cloner should yield to nodes that compare equal and produce the same
- //! hash than the original node.
- //!
- //! <b>Effects</b>: Erases all the elements from *this
- //! calling Disposer::operator()(pointer), clones all the
- //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this. The hash function and the equality
- //! predicate are copied from the source.
- //!
- //! If store_hash option is true, this method does not use the hash function.
- //!
- //! If any operation throws, all cloned elements are unlinked and disposed
- //! calling Disposer::operator()(pointer).
- //!
- //! <b>Complexity</b>: Linear to erased plus inserted elements.
- //!
- //! <b>Throws</b>: If cloner or hasher throw or hash or equality predicate copying
- //! throws. Basic guarantee.
+ //! @copydoc ::boost::intrusive::hashtable::hashtable
+ void swap(unordered_set_impl& other);
+
+ //! @copydoc ::boost::intrusive::hashtable::clone_from(const hashtable&,Cloner,Disposer)
template <class Cloner, class Disposer>
- void clone_from(const unordered_set_impl &src, Cloner cloner, Disposer disposer)
- { table_type::clone_from(src.table_, cloner, disposer); }
+ void clone_from(const unordered_set_impl &src, Cloner cloner, Disposer disposer);
+
+ #else
+
+ using table_type::clone_from;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! <b>Requires</b>: value must be an lvalue
- //!
- //! <b>Effects</b>: Tries to inserts value into the unordered_set.
- //!
- //! <b>Returns</b>: If the value
- //! is not already present inserts it and returns a pair containing the
- //! iterator to the new value and true. If there is an equivalent value
- //! returns a pair containing an iterator to the already present value
- //! and false.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Strong guarantee.
- //!
- //! <b>Note</b>: Does not affect the validity of iterators and references.
- //! No copy-constructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::clone_from(hashtable&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(unordered_set_impl) src, Cloner cloner, Disposer disposer)
+ { table_type::clone_from(BOOST_MOVE_BASE(table_type, src), cloner, disposer); }
+
+ //! @copydoc ::boost::intrusive::hashtable::insert_unique(reference)
std::pair<iterator, bool> insert(reference value)
{ return table_type::insert_unique(value); }
- //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
- //! of type value_type.
- //!
- //! <b>Effects</b>: Equivalent to this->insert(t) for each element in [b, e).
- //!
- //! <b>Complexity</b>: Average case O(N), where N is distance(b, e).
- //! Worst case O(N*this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
- //!
- //! <b>Note</b>: Does not affect the validity of iterators and references.
- //! No copy-constructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::insert_unique(Iterator,Iterator)
template<class Iterator>
void insert(Iterator b, Iterator e)
{ table_type::insert_unique(b, e); }
- //! <b>Requires</b>: "hasher" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hasher" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Checks if a value can be inserted in the unordered_set, using
- //! a user provided key instead of the value itself.
- //!
- //! <b>Returns</b>: If there is an equivalent value
- //! returns a pair containing an iterator to the already present value
- //! and false. If the value can be inserted returns true in the returned
- //! pair boolean and fills "commit_data" that is meant to be used with
- //! the "insert_commit" function.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hasher or key_value_equal throw. Strong guarantee.
- //!
- //! <b>Notes</b>: This function is used to improve performance when constructing
- //! a value_type is expensive: if there is an equivalent value
- //! the constructed object must be discarded. Many times, the part of the
- //! node that is used to impose the hash or the equality is much cheaper to
- //! construct than the value_type and this function offers the possibility to
- //! use that the part to check if the insertion will be successful.
- //!
- //! If the check is successful, the user can construct the value_type and use
- //! "insert_commit" to insert the object in constant-time.
- //!
- //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
- //! objects are inserted or erased from the unordered_set.
- //!
- //! After a successful rehashing insert_commit_data remains valid.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
+ //! @copydoc ::boost::intrusive::hashtable::insert_unique_check(const KeyType&,KeyHasher,KeyEqual,insert_commit_data&)
+ template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<iterator, bool> insert_check
- (const KeyType &key, KeyHasher hasher, KeyValueEqual key_value_equal, insert_commit_data &commit_data)
+ (const KeyType &key, KeyHasher hasher, KeyEqual key_value_equal, insert_commit_data &commit_data)
{ return table_type::insert_unique_check(key, hasher, key_value_equal, commit_data); }
- //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
- //! must have been obtained from a previous call to "insert_check".
- //! No objects should have been inserted or erased from the unordered_set between
- //! the "insert_check" that filled "commit_data" and the call to "insert_commit".
- //!
- //! <b>Effects</b>: Inserts the value in the unordered_set using the information obtained
- //! from the "commit_data" that a previous "insert_check" filled.
- //!
- //! <b>Returns</b>: An iterator to the newly inserted object.
- //!
- //! <b>Complexity</b>: Constant time.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Notes</b>: This function has only sense if a "insert_check" has been
- //! previously executed to fill "commit_data". No value should be inserted or
- //! erased between the "insert_check" and "insert_commit" calls.
- //!
- //! After a successful rehashing insert_commit_data remains valid.
+ //! @copydoc ::boost::intrusive::hashtable::insert_unique_commit
iterator insert_commit(reference value, const insert_commit_data &commit_data)
{ return table_type::insert_unique_commit(value, commit_data); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! <b>Effects</b>: Erases the element pointed to by i.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased element. No destructors are called.
- void erase(const_iterator i)
- { table_type::erase(i); }
+ //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator)
+ void erase(const_iterator i);
- //! <b>Effects</b>: Erases the range pointed to by b end e.
- //!
- //! <b>Complexity</b>: Average case O(distance(b, e)),
- //! worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- void erase(const_iterator b, const_iterator e)
- { table_type::erase(b, e); }
+ //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator,const_iterator)
+ void erase(const_iterator b, const_iterator e);
- //! <b>Effects</b>: Erases all the elements with the given value.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- size_type erase(const_reference value)
- { return table_type::erase(value); }
-
- //! <b>Requires</b>: "hasher" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hasher" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Erases all the elements that have the same hash and
- //! compare equal with the given key.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- size_type erase(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
- { return table_type::erase(key, hash_func, equal_func); }
+ //! @copydoc ::boost::intrusive::hashtable::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases the element pointed to by i.
- //! Disposer::operator()(pointer) is called for the removed element.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators
- //! to the erased elements.
+ //! @copydoc ::boost::intrusive::hashtable::erase(const KeyType&,KeyHasher,KeyEqual)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ size_type erase(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
+
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
- void erase_and_dispose(const_iterator i, Disposer disposer
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0
- /// @endcond
- )
- { table_type::erase_and_dispose(i, disposer); }
-
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases the range pointed to by b end e.
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Complexity</b>: Average case O(distance(b, e)),
- //! worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators
- //! to the erased elements.
+ BOOST_INTRUSIVE_DOC1ST(void
+ , typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
+ erase_and_dispose(const_iterator i, Disposer disposer);
+
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,const_iterator,Disposer)
template<class Disposer>
- void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
- { table_type::erase_and_dispose(b, e, disposer); }
+ void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases all the elements with the given value.
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const key_type &,Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer)
- { return table_type::erase_and_dispose(value, disposer); }
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases all the elements with the given key.
- //! according to the comparison functor "equal_func".
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators
- //! to the erased elements.
- template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func, Disposer disposer)
- { return table_type::erase_and_dispose(key, hash_func, equal_func, disposer); }
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const KeyType&,KeyHasher,KeyEqual,Disposer)
+ template<class KeyType, class KeyHasher, class KeyEqual, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func, Disposer disposer);
- //! <b>Effects</b>: Erases all of the elements.
- //!
- //! <b>Complexity</b>: Linear to the number of elements on the container.
- //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- void clear()
- { return table_type::clear(); }
+ //! @copydoc ::boost::intrusive::hashtable::clear
+ void clear();
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases all of the elements.
- //!
- //! <b>Complexity</b>: Linear to the number of elements on the container.
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::clear_and_dispose
template<class Disposer>
- void clear_and_dispose(Disposer disposer)
- { return table_type::clear_and_dispose(disposer); }
+ void clear_and_dispose(Disposer disposer);
- //! <b>Effects</b>: Returns the number of contained elements with the given value
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- size_type count(const_reference value) const
- { return table_type::find(value) != end(); }
+ //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "equal_func" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "equal_func" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Returns the number of contained elements with the given key
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hash_func or equal_func throw.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- size_type count(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
- { return table_type::find(key, hash_func, equal_func) != end(); }
+ //! @copydoc ::boost::intrusive::hashtable::count(const KeyType&,KeyHasher,KeyEqual)const
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ size_type count(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
- //! <b>Effects</b>: Finds an iterator to the first element is equal to
- //! "value" or end() if that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- iterator find(const_reference value)
- { return table_type::find(value); }
+ //! @copydoc ::boost::intrusive::hashtable::find(const key_type &)
+ iterator find(const key_type &key);
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "equal_func" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "equal_func" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Finds an iterator to the first element whose key is
- //! "key" according to the given hasher and equality functor or end() if
- //! that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hash_func or equal_func throw.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
- { return table_type::find(key, hash_func, equal_func); }
-
- //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
- //! "key" or end() if that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- const_iterator find(const_reference value) const
- { return table_type::find(value); }
+ //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "equal_func" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "equal_func" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Finds an iterator to the first element whose key is
- //! "key" according to the given hasher and equality functor or end() if
- //! that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hash_func or equal_func throw.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- const_iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
- { return table_type::find(key, hash_func, equal_func); }
-
- //! <b>Effects</b>: Returns a range containing all elements with values equivalent
- //! to value. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return table_type::equal_range(value); }
+ //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "equal_func" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "equal_func" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Returns a range containing all elements with equivalent
- //! keys. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(key, hash_func, hash_func)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hash_func or the equal_func throw.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
- { return table_type::equal_range(key, hash_func, equal_func); }
-
- //! <b>Effects</b>: Returns a range containing all elements with values equivalent
- //! to value. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
+ //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)const
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ const_iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
+ #endif
+
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)
+ std::pair<iterator,iterator> equal_range(const key_type &key)
+ { return this->equal_range(key, this->hash_function(), this->key_eq()); }
+
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func)
+ { return this->priv_equal_range<iterator>(*this, key, hash_func, equal_func); }
+
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return table_type::equal_range(value); }
+ equal_range(const key_type &key) const
+ { return this->equal_range(key, this->hash_function(), this->key_eq()); }
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "equal_func" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "equal_func" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Returns a range containing all elements with equivalent
- //! keys. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the hash_func or equal_func throw.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)const
+ template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
- { return table_type::equal_range(key, hash_func, equal_func); }
+ equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const
+ { return this->priv_equal_range<const_iterator>(*this, key, hash_func, equal_func); }
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid iterator belonging to the unordered_set
- //! that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the internal hash function throws.
- iterator iterator_to(reference value)
- { return table_type::iterator_to(value); }
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ //! @copydoc ::boost::intrusive::hashtable::iterator_to(reference)
+ iterator iterator_to(reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid const_iterator belonging to the
- //! unordered_set that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the internal hash function throws.
- const_iterator iterator_to(const_reference value) const
- { return table_type::iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::iterator_to(const_reference)const
+ const_iterator iterator_to(const_reference value) const;
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
- //! that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: This static function is available only if the <i>value traits</i>
- //! is stateless.
- static local_iterator s_local_iterator_to(reference value)
- { return table_type::s_local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(reference)
+ static local_iterator s_local_iterator_to(reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
- //! the unordered_set that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: This static function is available only if the <i>value traits</i>
- //! is stateless.
- static const_local_iterator s_local_iterator_to(const_reference value)
- { return table_type::s_local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(const_reference)
+ static const_local_iterator s_local_iterator_to(const_reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
- //! that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- local_iterator local_iterator_to(reference value)
- { return table_type::local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(reference)
+ local_iterator local_iterator_to(reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
- //! the unordered_set that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- const_local_iterator local_iterator_to(const_reference value) const
- { return table_type::local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(const_reference)
+ const_local_iterator local_iterator_to(const_reference value) const;
- //! <b>Effects</b>: Returns the number of buckets passed in the constructor
- //! or the last rehash function.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- size_type bucket_count() const
- { return table_type::bucket_count(); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket_count
+ size_type bucket_count() const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns the number of elements in the nth bucket.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- size_type bucket_size(size_type n) const
- { return table_type::bucket_size(n); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket_size
+ size_type bucket_size(size_type n) const;
- //! <b>Effects</b>: Returns the index of the bucket in which elements
- //! with keys equivalent to k would be found, if any such element existed.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the hash functor throws.
- //!
- //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
- size_type bucket(const value_type& k) const
- { return table_type::bucket(k); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket(const key_type&)const
+ size_type bucket(const key_type& k) const;
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! <b>Effects</b>: Returns the index of the bucket in which elements
- //! with keys equivalent to k would be found, if any such element existed.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If hash_func throws.
- //!
- //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
+ //! @copydoc ::boost::intrusive::hashtable::bucket(const KeyType&,KeyHasher)const
template<class KeyType, class KeyHasher>
- size_type bucket(const KeyType& k, KeyHasher hash_func) const
- { return table_type::bucket(k, hash_func); }
+ size_type bucket(const KeyType& k, KeyHasher hash_func) const;
- //! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
- //! or the last rehash function.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- bucket_ptr bucket_pointer() const
- { return table_type::bucket_pointer(); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket_pointer
+ bucket_ptr bucket_pointer() const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a local_iterator pointing to the beginning
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- local_iterator begin(size_type n)
- { return table_type::begin(n); }
+ //! @copydoc ::boost::intrusive::hashtable::begin(size_type)
+ local_iterator begin(size_type n);
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator begin(size_type n) const
- { return table_type::begin(n); }
+ //! @copydoc ::boost::intrusive::hashtable::begin(size_type)const
+ const_local_iterator begin(size_type n) const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator cbegin(size_type n) const
- { return table_type::cbegin(n); }
+ //! @copydoc ::boost::intrusive::hashtable::cbegin(size_type)const
+ const_local_iterator cbegin(size_type n) const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a local_iterator pointing to the end
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- local_iterator end(size_type n)
- { return table_type::end(n); }
+ //! @copydoc ::boost::intrusive::hashtable::end(size_type)
+ local_iterator end(size_type n);
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator end(size_type n) const
- { return table_type::end(n); }
+ //! @copydoc ::boost::intrusive::hashtable::end(size_type)const
+ const_local_iterator end(size_type n) const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator cend(size_type n) const
- { return table_type::cend(n); }
-
- //! <b>Requires</b>: new_buckets must be a pointer to a new bucket array
- //! or the same as the old bucket array. new_size is the length of the
- //! the array pointed by new_buckets. If new_buckets == this->bucket_pointer()
- //! n can be bigger or smaller than this->bucket_count().
- //!
- //! <b>Effects</b>: Updates the internal reference with the new bucket erases
- //! the values from the old bucket and inserts then in the new one.
- //!
- //! If store_hash option is true, this method does not use the hash function.
- //!
- //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
- //!
- //! <b>Throws</b>: If the hasher functor throws. Basic guarantee.
- void rehash(const bucket_traits &new_bucket_traits)
- { table_type::rehash(new_bucket_traits); }
+ //! @copydoc ::boost::intrusive::hashtable::cend(size_type)const
+ const_local_iterator cend(size_type n) const;
- //! <b>Requires</b>:
- //!
- //! <b>Effects</b>:
- //!
- //! <b>Complexity</b>:
- //!
- //! <b>Throws</b>:
- //!
- //! <b>Note</b>: this method is only available if incremental<true> option is activated.
- bool incremental_rehash(bool grow = true)
- { return table_type::incremental_rehash(grow); }
+ //! @copydoc ::boost::intrusive::hashtable::rehash(const bucket_traits &)
+ void rehash(const bucket_traits &new_bucket_traits);
- //! <b>Note</b>: this method is only available if incremental<true> option is activated.
- bool incremental_rehash(const bucket_traits &new_bucket_traits)
- { return table_type::incremental_rehash(new_bucket_traits); }
+ //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(bool)
+ bool incremental_rehash(bool grow = true);
- //! <b>Requires</b>:
- //!
- //! <b>Effects</b>:
- //!
- //! <b>Complexity</b>:
- //!
- //! <b>Throws</b>:
- size_type split_count() const
- { return table_type::split_count(); }
-
- //! <b>Effects</b>: Returns the nearest new bucket count optimized for
- //! the container that is bigger than n. This suggestion can be used
- //! to create bucket arrays with a size that will usually improve
- //! container's performance. If such value does not exist, the
- //! higher possible value is returned.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- //!
- //! <b>Throws</b>: Nothing.
- static size_type suggested_upper_bucket_count(size_type n)
- { return table_type::suggested_upper_bucket_count(n); }
-
- //! <b>Effects</b>: Returns the nearest new bucket count optimized for
- //! the container that is smaller than n. This suggestion can be used
- //! to create bucket arrays with a size that will usually improve
- //! container's performance. If such value does not exist, the
- //! lower possible value is returned.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- //!
- //! <b>Throws</b>: Nothing.
- static size_type suggested_lower_bucket_count(size_type n)
- { return table_type::suggested_lower_bucket_count(n); }
+ //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(const bucket_traits &)
+ bool incremental_rehash(const bucket_traits &new_bucket_traits);
+
+ //! @copydoc ::boost::intrusive::hashtable::split_count
+ size_type split_count() const;
+
+ //! @copydoc ::boost::intrusive::hashtable::suggested_upper_bucket_count
+ static size_type suggested_upper_bucket_count(size_type n);
+
+ //! @copydoc ::boost::intrusive::hashtable::suggested_lower_bucket_count
+ static size_type suggested_lower_bucket_count(size_type n);
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ friend bool operator==(const unordered_set_impl &x, const unordered_set_impl &y)
+ {
+ if(table_type::constant_time_size && x.size() != y.size()){
+ return false;
+ }
+ //Find each element of x in y
+ for (const_iterator ix = x.cbegin(), ex = x.cend(), ey = y.cend(); ix != ex; ++ix){
+ const_iterator iy = y.find(key_of_value()(*ix));
+ if (iy == ey || !(*ix == *iy))
+ return false;
+ }
+ return true;
+ }
+
+ friend bool operator!=(const unordered_set_impl &x, const unordered_set_impl &y)
+ { return !(x == y); }
+
+ friend bool operator<(const unordered_set_impl &x, const unordered_set_impl &y)
+ { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+
+ friend bool operator>(const unordered_set_impl &x, const unordered_set_impl &y)
+ { return y < x; }
+
+ friend bool operator<=(const unordered_set_impl &x, const unordered_set_impl &y)
+ { return !(y < x); }
+
+ friend bool operator>=(const unordered_set_impl &x, const unordered_set_impl &y)
+ { return !(x < y); }
};
//! Helper metafunction to define an \c unordered_set that yields to the same type when the
@@ -1037,6 +435,7 @@ struct make_unordered_set
typedef unordered_set_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::hash
, typename packed_options::equal
, typename packed_options::size_type
@@ -1115,6 +514,14 @@ class unordered_set
unordered_set& operator=(BOOST_RV_REF(unordered_set) x)
{ return static_cast<unordered_set&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(const unordered_set &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(unordered_set) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
};
#endif
@@ -1158,14 +565,14 @@ class unordered_set
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Hash, class Equal, class SizeType, class BucketTraits, std::size_t BoolFlags>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class SizeType, class BucketTraits, std::size_t BoolFlags>
#endif
class unordered_multiset_impl
- : public hashtable_impl<ValueTraits, Hash, Equal, SizeType, BucketTraits, BoolFlags>
+ : public hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags>
{
/// @cond
private:
- typedef hashtable_impl<ValueTraits, Hash, Equal, SizeType, BucketTraits, BoolFlags> table_type;
+ typedef hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags> table_type;
/// @endcond
//Movable
@@ -1175,6 +582,7 @@ class unordered_multiset_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::bucket_traits bucket_traits;
typedef typename implementation_defined::pointer pointer;
@@ -1183,7 +591,6 @@ class unordered_multiset_impl
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
typedef typename implementation_defined::size_type size_type;
- typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::key_equal key_equal;
typedef typename implementation_defined::hasher hasher;
typedef typename implementation_defined::bucket_type bucket_type;
@@ -1201,19 +608,7 @@ class unordered_multiset_impl
public:
- //! <b>Requires</b>: buckets must not be being used by any other resource.
- //!
- //! <b>Effects</b>: Constructs an empty unordered_multiset, storing a reference
- //! to the bucket array and copies of the hasher and equal functors.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If value_traits::node_traits::node
- //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor or invocation of Hash or Equal throws.
- //!
- //! <b>Notes</b>: buckets array must be disposed only after
- //! *this is disposed.
+ //! @copydoc ::boost::intrusive::hashtable::hashtable(const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
explicit unordered_multiset_impl ( const bucket_traits &b_traits
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
@@ -1221,21 +616,7 @@ class unordered_multiset_impl
: table_type(b_traits, hash_func, equal_func, v_traits)
{}
- //! <b>Requires</b>: buckets must not be being used by any other resource
- //! and Dereferencing iterator must yield an lvalue of type value_type.
- //!
- //! <b>Effects</b>: Constructs an empty unordered_multiset and inserts elements from
- //! [b, e).
- //!
- //! <b>Complexity</b>: If N is distance(b, e): Average case is O(N)
- //! (with a good hash function and with buckets_len >= N),worst case O(N2).
- //!
- //! <b>Throws</b>: If value_traits::node_traits::node
- //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor or invocation of hasher or key_equal throws.
- //!
- //! <b>Notes</b>: buckets array must be disposed only after
- //! *this is disposed.
+ //! @copydoc ::boost::intrusive::hashtable::hashtable(bool,Iterator,Iterator,const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
template<class Iterator>
unordered_multiset_impl ( Iterator b
, Iterator e
@@ -1243,8 +624,8 @@ class unordered_multiset_impl
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
, const value_traits &v_traits = value_traits())
- : table_type(b_traits, hash_func, equal_func, v_traits)
- { table_type::insert_equal(b, e); }
+ : table_type(false, b, e, b_traits, hash_func, equal_func, v_traits)
+ {}
//! <b>Effects</b>: to-do
//!
@@ -1259,785 +640,212 @@ class unordered_multiset_impl
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! <b>Effects</b>: Detaches all elements from this. The objects in the unordered_multiset
- //! are not deleted (i.e. no destructors are called).
- //!
- //! <b>Complexity</b>: Linear to the number of elements in the unordered_multiset, if
- //! it's a safe-mode or auto-unlink value. Otherwise constant.
- //!
- //! <b>Throws</b>: Nothing.
- ~unordered_multiset_impl()
- {}
+ //! @copydoc ::boost::intrusive::hashtable::~hashtable()
+ ~unordered_multiset_impl();
- //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_multiset.
- //!
- //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
- //! constant time with worst case (empty unordered_set) O(this->bucket_count())
- //!
- //! <b>Throws</b>: Nothing.
- iterator begin()
- { return table_type::begin(); }
+ //! @copydoc ::boost::intrusive::hashtable::begin()
+ iterator begin();
- //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
- //! of the unordered_multiset.
- //!
- //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
- //! constant time with worst case (empty unordered_set) O(this->bucket_count())
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator begin() const
- { return table_type::begin(); }
+ //! @copydoc ::boost::intrusive::hashtable::begin()const
+ const_iterator begin() const;
- //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
- //! of the unordered_multiset.
- //!
- //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
- //! constant time with worst case (empty unordered_set) O(this->bucket_count())
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator cbegin() const
- { return table_type::cbegin(); }
+ //! @copydoc ::boost::intrusive::hashtable::cbegin()const
+ const_iterator cbegin() const;
- //! <b>Effects</b>: Returns an iterator pointing to the end of the unordered_multiset.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- iterator end()
- { return table_type::end(); }
+ //! @copydoc ::boost::intrusive::hashtable::end()
+ iterator end();
- //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_multiset.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator end() const
- { return table_type::end(); }
+ //! @copydoc ::boost::intrusive::hashtable::end()const
+ const_iterator end() const;
- //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_multiset.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator cend() const
- { return table_type::cend(); }
+ //! @copydoc ::boost::intrusive::hashtable::cend()const
+ const_iterator cend() const;
- //! <b>Effects</b>: Returns the hasher object used by the unordered_set.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If hasher copy-constructor throws.
- hasher hash_function() const
- { return table_type::hash_function(); }
+ //! @copydoc ::boost::intrusive::hashtable::hash_function()const
+ hasher hash_function() const;
- //! <b>Effects</b>: Returns the key_equal object used by the unordered_multiset.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If key_equal copy-constructor throws.
- key_equal key_eq() const
- { return table_type::key_eq(); }
+ //! @copydoc ::boost::intrusive::hashtable::key_eq()const
+ key_equal key_eq() const;
- //! <b>Effects</b>: Returns true if the container is empty.
- //!
- //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
- //! average constant time (worst case, with empty() == true: O(this->bucket_count()).
- //! Otherwise constant.
- //!
- //! <b>Throws</b>: Nothing.
- bool empty() const
- { return table_type::empty(); }
+ //! @copydoc ::boost::intrusive::hashtable::empty()const
+ bool empty() const;
- //! <b>Effects</b>: Returns the number of elements stored in the unordered_multiset.
- //!
- //! <b>Complexity</b>: Linear to elements contained in *this if
- //! constant-time size option is disabled. Constant-time otherwise.
- //!
- //! <b>Throws</b>: Nothing.
- size_type size() const
- { return table_type::size(); }
+ //! @copydoc ::boost::intrusive::hashtable::size()const
+ size_type size() const;
- //! <b>Requires</b>: the hasher and the equality function unqualified swap
- //! call should not throw.
- //!
- //! <b>Effects</b>: Swaps the contents of two unordered_multisets.
- //! Swaps also the contained bucket array and equality and hasher functors.
- //!
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the swap() call for the comparison or hash functors
- //! found using ADL throw. Basic guarantee.
- void swap(unordered_multiset_impl& other)
- { table_type::swap(other.table_); }
-
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //! Cloner should yield to nodes that compare equal and produce the same
- //! hash than the original node.
- //!
- //! <b>Effects</b>: Erases all the elements from *this
- //! calling Disposer::operator()(pointer), clones all the
- //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this. The hash function and the equality
- //! predicate are copied from the source.
- //!
- //! If store_hash option is true, this method does not use the hash function.
- //!
- //! If any operation throws, all cloned elements are unlinked and disposed
- //! calling Disposer::operator()(pointer).
- //!
- //! <b>Complexity</b>: Linear to erased plus inserted elements.
- //!
- //! <b>Throws</b>: If cloner or hasher throw or hash or equality predicate copying
- //! throws. Basic guarantee.
+ //! @copydoc ::boost::intrusive::hashtable::hashtable
+ void swap(unordered_multiset_impl& other);
+
+ //! @copydoc ::boost::intrusive::hashtable::clone_from(const hashtable&,Cloner,Disposer)
template <class Cloner, class Disposer>
- void clone_from(const unordered_multiset_impl &src, Cloner cloner, Disposer disposer)
- { table_type::clone_from(src.table_, cloner, disposer); }
+ void clone_from(const unordered_multiset_impl &src, Cloner cloner, Disposer disposer);
+
+ #else
+
+ using table_type::clone_from;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! <b>Requires</b>: value must be an lvalue
- //!
- //! <b>Effects</b>: Inserts value into the unordered_multiset.
- //!
- //! <b>Returns</b>: An iterator to the new inserted value.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Strong guarantee.
- //!
- //! <b>Note</b>: Does not affect the validity of iterators and references.
- //! No copy-constructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::clone_from(hashtable&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(unordered_multiset_impl) src, Cloner cloner, Disposer disposer)
+ { table_type::clone_from(BOOST_MOVE_BASE(table_type, src), cloner, disposer); }
+
+ //! @copydoc ::boost::intrusive::hashtable::insert_equal(reference)
iterator insert(reference value)
{ return table_type::insert_equal(value); }
- //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
- //! of type value_type.
- //!
- //! <b>Effects</b>: Equivalent to this->insert(t) for each element in [b, e).
- //!
- //! <b>Complexity</b>: Average case is O(N), where N is the
- //! size of the range.
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
- //!
- //! <b>Note</b>: Does not affect the validity of iterators and references.
- //! No copy-constructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::insert_equal(Iterator,Iterator)
template<class Iterator>
void insert(Iterator b, Iterator e)
{ table_type::insert_equal(b, e); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! <b>Effects</b>: Erases the element pointed to by i.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased element. No destructors are called.
- void erase(const_iterator i)
- { table_type::erase(i); }
+ //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator)
+ void erase(const_iterator i);
- //! <b>Effects</b>: Erases the range pointed to by b end e.
- //!
- //! <b>Complexity</b>: Average case O(distance(b, e)),
- //! worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- void erase(const_iterator b, const_iterator e)
- { table_type::erase(b, e); }
+ //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator,const_iterator)
+ void erase(const_iterator b, const_iterator e);
- //! <b>Effects</b>: Erases all the elements with the given value.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- size_type erase(const_reference value)
- { return table_type::erase(value); }
-
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Erases all the elements that have the same hash and
- //! compare equal with the given key.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the hash_func or the equal_func functors throws.
- //! Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- size_type erase(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
- { return table_type::erase(key, hash_func, equal_func); }
+ //! @copydoc ::boost::intrusive::hashtable::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases the element pointed to by i.
- //! Disposer::operator()(pointer) is called for the removed element.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators
- //! to the erased elements.
- template<class Disposer>
- void erase_and_dispose(const_iterator i, Disposer disposer
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0
- /// @endcond
- )
- { table_type::erase_and_dispose(i, disposer); }
-
- #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ //! @copydoc ::boost::intrusive::hashtable::erase(const KeyType&,KeyHasher,KeyEqual)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ size_type erase(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
+
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
- void erase_and_dispose(const_iterator i, Disposer disposer)
- { this->erase_and_dispose(const_iterator(i), disposer); }
- #endif
+ BOOST_INTRUSIVE_DOC1ST(void
+ , typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
+ erase_and_dispose(const_iterator i, Disposer disposer);
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases the range pointed to by b end e.
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Complexity</b>: Average case O(distance(b, e)),
- //! worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators
- //! to the erased elements.
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,const_iterator,Disposer)
template<class Disposer>
- void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
- { table_type::erase_and_dispose(b, e, disposer); }
+ void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases all the elements with the given value.
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const key_type &,Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer)
- { return table_type::erase_and_dispose(value, disposer); }
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases all the elements with the given key.
- //! according to the comparison functor "equal_func".
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators
- //! to the erased elements.
- template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func, Disposer disposer)
- { return table_type::erase_and_dispose(key, hash_func, equal_func, disposer); }
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const KeyType&,KeyHasher,KeyEqual,Disposer)
+ template<class KeyType, class KeyHasher, class KeyEqual, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func, Disposer disposer);
- //! <b>Effects</b>: Erases all the elements of the container.
- //!
- //! <b>Complexity</b>: Linear to the number of elements on the container.
- //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- void clear()
- { return table_type::clear(); }
+ //! @copydoc ::boost::intrusive::hashtable::clear
+ void clear();
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases all the elements of the container.
- //!
- //! <b>Complexity</b>: Linear to the number of elements on the container.
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::clear_and_dispose
template<class Disposer>
- void clear_and_dispose(Disposer disposer)
- { return table_type::clear_and_dispose(disposer); }
+ void clear_and_dispose(Disposer disposer);
- //! <b>Effects</b>: Returns the number of contained elements with the given key
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- size_type count(const_reference value) const
- { return table_type::count(value); }
+ //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Returns the number of contained elements with the given key
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- size_type count(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
- { return table_type::count(key, hash_func, equal_func); }
+ //! @copydoc ::boost::intrusive::hashtable::count(const KeyType&,KeyHasher,KeyEqual)const
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ size_type count(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
- //! <b>Effects</b>: Finds an iterator to the first element whose value is
- //! "value" or end() if that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- iterator find(const_reference value)
- { return table_type::find(value); }
+ //! @copydoc ::boost::intrusive::hashtable::find(const key_type &)
+ iterator find(const key_type &key);
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Finds an iterator to the first element whose key is
- //! "key" according to the given hasher and equality functor or end() if
- //! that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
- { return table_type::find(key, hash_func, equal_func); }
-
- //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
- //! "key" or end() if that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- const_iterator find(const_reference value) const
- { return table_type::find(value); }
+ //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Finds an iterator to the first element whose key is
- //! "key" according to the given hasher and equality functor or end() if
- //! that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- const_iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
- { return table_type::find(key, hash_func, equal_func); }
-
- //! <b>Effects</b>: Returns a range containing all elements with values equivalent
- //! to value. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return table_type::equal_range(value); }
+ //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Returns a range containing all elements with equivalent
- //! keys. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- std::pair<iterator,iterator> equal_range
- (const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
- { return table_type::equal_range(key, hash_func, equal_func); }
-
- //! <b>Effects</b>: Returns a range containing all elements with values equivalent
- //! to value. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
+ //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)const
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ const_iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
+
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
+
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
+
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return table_type::equal_range(value); }
+ equal_range(const key_type &key) const;
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Returns a range containing all elements with equivalent
- //! keys. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)const
+ template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
- { return table_type::equal_range(key, hash_func, equal_func); }
+ equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_multiset of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid iterator belonging to the unordered_multiset
- //! that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the hash function throws.
- iterator iterator_to(reference value)
- { return table_type::iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::iterator_to(reference)
+ iterator iterator_to(reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_multiset of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid const_iterator belonging to the
- //! unordered_multiset that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the hash function throws.
- const_iterator iterator_to(const_reference value) const
- { return table_type::iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::iterator_to(const_reference)const
+ const_iterator iterator_to(const_reference value) const;
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
- //! that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: This static function is available only if the <i>value traits</i>
- //! is stateless.
- static local_iterator s_local_iterator_to(reference value)
- { return table_type::s_local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(reference)
+ static local_iterator s_local_iterator_to(reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
- //! the unordered_set that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: This static function is available only if the <i>value traits</i>
- //! is stateless.
- static const_local_iterator s_local_iterator_to(const_reference value)
- { return table_type::s_local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(const_reference)
+ static const_local_iterator s_local_iterator_to(const_reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
- //! that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- local_iterator local_iterator_to(reference value)
- { return table_type::local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(reference)
+ local_iterator local_iterator_to(reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
- //! the unordered_set that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- const_local_iterator local_iterator_to(const_reference value) const
- { return table_type::local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(const_reference)
+ const_local_iterator local_iterator_to(const_reference value) const;
- //! <b>Effects</b>: Returns the number of buckets passed in the constructor
- //! or the last rehash function.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- size_type bucket_count() const
- { return table_type::bucket_count(); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket_count
+ size_type bucket_count() const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns the number of elements in the nth bucket.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- size_type bucket_size(size_type n) const
- { return table_type::bucket_size(n); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket_size
+ size_type bucket_size(size_type n) const;
- //! <b>Effects</b>: Returns the index of the bucket in which elements
- //! with keys equivalent to k would be found, if any such element existed.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the hash functor throws.
- //!
- //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
- size_type bucket(const value_type& k) const
- { return table_type::bucket(k); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket(const key_type&)const
+ size_type bucket(const key_type& k) const;
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! <b>Effects</b>: Returns the index of the bucket in which elements
- //! with keys equivalent to k would be found, if any such element existed.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the hash functor throws.
- //!
- //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
+ //! @copydoc ::boost::intrusive::hashtable::bucket(const KeyType&,KeyHasher)const
template<class KeyType, class KeyHasher>
- size_type bucket(const KeyType& k, const KeyHasher &hash_func) const
- { return table_type::bucket(k, hash_func); }
+ size_type bucket(const KeyType& k, KeyHasher hash_func) const;
- //! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
- //! or the last rehash function.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- bucket_ptr bucket_pointer() const
- { return table_type::bucket_pointer(); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket_pointer
+ bucket_ptr bucket_pointer() const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a local_iterator pointing to the beginning
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- local_iterator begin(size_type n)
- { return table_type::begin(n); }
+ //! @copydoc ::boost::intrusive::hashtable::begin(size_type)
+ local_iterator begin(size_type n);
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator begin(size_type n) const
- { return table_type::begin(n); }
+ //! @copydoc ::boost::intrusive::hashtable::begin(size_type)const
+ const_local_iterator begin(size_type n) const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator cbegin(size_type n) const
- { return table_type::cbegin(n); }
+ //! @copydoc ::boost::intrusive::hashtable::cbegin(size_type)const
+ const_local_iterator cbegin(size_type n) const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a local_iterator pointing to the end
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- local_iterator end(size_type n)
- { return table_type::end(n); }
+ //! @copydoc ::boost::intrusive::hashtable::end(size_type)
+ local_iterator end(size_type n);
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator end(size_type n) const
- { return table_type::end(n); }
+ //! @copydoc ::boost::intrusive::hashtable::end(size_type)const
+ const_local_iterator end(size_type n) const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator cend(size_type n) const
- { return table_type::cend(n); }
-
- //! <b>Requires</b>: new_buckets must be a pointer to a new bucket array
- //! or the same as the old bucket array. new_size is the length of the
- //! the array pointed by new_buckets. If new_buckets == this->bucket_pointer()
- //! n can be bigger or smaller than this->bucket_count().
- //!
- //! <b>Effects</b>: Updates the internal reference with the new bucket erases
- //! the values from the old bucket and inserts then in the new one.
- //!
- //! If store_hash option is true, this method does not use the hash function.
- //!
- //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
- //!
- //! <b>Throws</b>: If the hasher functor throws.
- void rehash(const bucket_traits &new_bucket_traits)
- { table_type::rehash(new_bucket_traits); }
+ //! @copydoc ::boost::intrusive::hashtable::cend(size_type)const
+ const_local_iterator cend(size_type n) const;
- //! <b>Requires</b>:
- //!
- //! <b>Effects</b>:
- //!
- //! <b>Complexity</b>:
- //!
- //! <b>Throws</b>:
- //!
- //! <b>Note</b>: this method is only available if incremental<true> option is activated.
- bool incremental_rehash(bool grow = true)
- { return table_type::incremental_rehash(grow); }
+ //! @copydoc ::boost::intrusive::hashtable::rehash(const bucket_traits &)
+ void rehash(const bucket_traits &new_bucket_traits);
- //! <b>Note</b>: this method is only available if incremental<true> option is activated.
- bool incremental_rehash(const bucket_traits &new_bucket_traits)
- { return table_type::incremental_rehash(new_bucket_traits); }
+ //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(bool)
+ bool incremental_rehash(bool grow = true);
- //! <b>Requires</b>:
- //!
- //! <b>Effects</b>:
- //!
- //! <b>Complexity</b>:
- //!
- //! <b>Throws</b>:
- size_type split_count() const
- { return table_type::split_count(); }
-
- //! <b>Effects</b>: Returns the nearest new bucket count optimized for
- //! the container that is bigger than n. This suggestion can be used
- //! to create bucket arrays with a size that will usually improve
- //! container's performance. If such value does not exist, the
- //! higher possible value is returned.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- //!
- //! <b>Throws</b>: Nothing.
- static size_type suggested_upper_bucket_count(size_type n)
- { return table_type::suggested_upper_bucket_count(n); }
-
- //! <b>Effects</b>: Returns the nearest new bucket count optimized for
- //! the container that is smaller than n. This suggestion can be used
- //! to create bucket arrays with a size that will usually improve
- //! container's performance. If such value does not exist, the
- //! lower possible value is returned.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- //!
- //! <b>Throws</b>: Nothing.
- static size_type suggested_lower_bucket_count(size_type n)
- { return table_type::suggested_lower_bucket_count(n); }
+ //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(const bucket_traits &)
+ bool incremental_rehash(const bucket_traits &new_bucket_traits);
+
+ //! @copydoc ::boost::intrusive::hashtable::split_count
+ size_type split_count() const;
+
+ //! @copydoc ::boost::intrusive::hashtable::suggested_upper_bucket_count
+ static size_type suggested_upper_bucket_count(size_type n);
+
+ //! @copydoc ::boost::intrusive::hashtable::suggested_lower_bucket_count
+ static size_type suggested_lower_bucket_count(size_type n);
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
};
@@ -2074,6 +882,7 @@ struct make_unordered_multiset
typedef unordered_multiset_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::hash
, typename packed_options::equal
, typename packed_options::size_type
@@ -2151,6 +960,14 @@ class unordered_multiset
unordered_multiset& operator=(BOOST_RV_REF(unordered_multiset) x)
{ return static_cast<unordered_multiset&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(const unordered_multiset &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(unordered_multiset) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
};
#endif
diff --git a/boost/iterator/is_lvalue_iterator.hpp b/boost/iterator/is_lvalue_iterator.hpp
index 20c4f38ad4..e821da9c3c 100644
--- a/boost/iterator/is_lvalue_iterator.hpp
+++ b/boost/iterator/is_lvalue_iterator.hpp
@@ -9,10 +9,13 @@
#include <boost/detail/workaround.hpp>
#include <boost/detail/iterator.hpp>
+#include <boost/type_traits/add_lvalue_reference.hpp>
#include <boost/iterator/detail/any_conversion_eater.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
// should be the last #includes
-#include <boost/type_traits/detail/bool_trait_def.hpp>
+#include <boost/type_traits/integral_constant.hpp>
#include <boost/iterator/detail/config_def.hpp>
#ifndef BOOST_NO_IS_CONVERTIBLE
@@ -52,7 +55,7 @@ namespace detail
// convertible to Value const&
struct conversion_eater
{
- conversion_eater(Value&);
+ conversion_eater(typename add_lvalue_reference<Value>::type);
};
static char tester(conversion_eater, int);
@@ -134,13 +137,19 @@ namespace detail
{};
} // namespace detail
-// Define the trait with full mpl lambda capability and various broken
-// compiler workarounds
-BOOST_TT_AUX_BOOL_TRAIT_DEF1(
- is_lvalue_iterator,T,::boost::iterators::detail::is_readable_lvalue_iterator_impl<T>::value)
+template< typename T > struct is_lvalue_iterator
+: public ::boost::integral_constant<bool,::boost::iterators::detail::is_readable_lvalue_iterator_impl<T>::value>
+{
+public:
+ BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_lvalue_iterator,(T))
+};
-BOOST_TT_AUX_BOOL_TRAIT_DEF1(
- is_non_const_lvalue_iterator,T,::boost::iterators::detail::is_non_const_lvalue_iterator_impl<T>::value)
+template< typename T > struct is_non_const_lvalue_iterator
+: public ::boost::integral_constant<bool,::boost::iterators::detail::is_non_const_lvalue_iterator_impl<T>::value>
+{
+public:
+ BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_non_const_lvalue_iterator,(T))
+};
} // namespace iterators
@@ -152,6 +161,5 @@ using iterators::is_non_const_lvalue_iterator;
#endif
#include <boost/iterator/detail/config_undef.hpp>
-#include <boost/type_traits/detail/bool_trait_undef.hpp>
#endif // IS_LVALUE_ITERATOR_DWA2003112_HPP
diff --git a/boost/iterator/is_readable_iterator.hpp b/boost/iterator/is_readable_iterator.hpp
index 3f08b92c0e..5bc2339cec 100644
--- a/boost/iterator/is_readable_iterator.hpp
+++ b/boost/iterator/is_readable_iterator.hpp
@@ -5,12 +5,14 @@
# define IS_READABLE_ITERATOR_DWA2003112_HPP
#include <boost/mpl/bool.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
#include <boost/detail/iterator.hpp>
+#include <boost/type_traits/add_lvalue_reference.hpp>
-#include <boost/type_traits/detail/bool_trait_def.hpp>
#include <boost/iterator/detail/any_conversion_eater.hpp>
// should be the last #include
+#include <boost/type_traits/integral_constant.hpp>
#include <boost/iterator/detail/config_def.hpp>
#ifndef BOOST_NO_IS_CONVERTIBLE
@@ -26,7 +28,7 @@ namespace detail
template <class Value>
struct is_readable_iterator_impl
{
- static char tester(Value&, int);
+ static char tester(typename add_lvalue_reference<Value>::type, int);
static char (& tester(any_conversion_eater, ...) )[2];
template <class It>
@@ -96,10 +98,12 @@ namespace detail
{};
} // namespace detail
-// Define the trait with full mpl lambda capability and various broken
-// compiler workarounds
-BOOST_TT_AUX_BOOL_TRAIT_DEF1(
- is_readable_iterator,T,::boost::iterators::detail::is_readable_iterator_impl2<T>::value)
+template< typename T > struct is_readable_iterator
+: public ::boost::integral_constant<bool,::boost::iterators::detail::is_readable_iterator_impl2<T>::value>
+{
+public:
+ BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_readable_iterator,(T))
+};
} // namespace iterators
diff --git a/boost/iterator/iterator_categories.hpp b/boost/iterator/iterator_categories.hpp
index 31b2a9d3ec..71202c993a 100644
--- a/boost/iterator/iterator_categories.hpp
+++ b/boost/iterator/iterator_categories.hpp
@@ -168,13 +168,6 @@ struct pure_traversal_tag
{
};
-// This import is needed for backward compatibility with Boost.Range:
-// boost/range/detail/demote_iterator_traversal_tag.hpp
-// It should be removed when that header is fixed.
-namespace detail {
-using iterators::pure_traversal_tag;
-} // namespace detail
-
//
// Trait to retrieve one of the iterator traversal tags from the iterator category or traversal.
//
diff --git a/boost/iterator/iterator_facade.hpp b/boost/iterator/iterator_facade.hpp
index c08a869bbd..7b11d0aec1 100644
--- a/boost/iterator/iterator_facade.hpp
+++ b/boost/iterator/iterator_facade.hpp
@@ -22,6 +22,7 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_pointer.hpp>
+#include <boost/type_traits/add_lvalue_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/is_convertible.hpp>
@@ -284,7 +285,15 @@ namespace iterators {
: mpl::eval_if<
mpl::and_<
// A proxy is only needed for readable iterators
- is_convertible<Reference,Value const&>
+ is_convertible<
+ Reference
+ // Use add_lvalue_reference to form `reference to Value` due to
+ // some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
+ // 'reference-to-reference' in the template which described in CWG
+ // DR106.
+ // http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106
+ , typename add_lvalue_reference<Value const>::type
+ >
// No multipass iterator can have values that disappear
// before positions can be re-visited
diff --git a/boost/lambda/detail/lambda_config.hpp b/boost/lambda/detail/lambda_config.hpp
index 9fd1a7b761..f47100b969 100644
--- a/boost/lambda/detail/lambda_config.hpp
+++ b/boost/lambda/detail/lambda_config.hpp
@@ -22,13 +22,6 @@
# define BOOST_REF_TO_FUNC_CONFLICTS_WITH_REF_TO_T
# define BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
# endif
-# if (__GNUC__ == 2 && __GNUC_MINOR__ <= 97)
-# define BOOST_NO_TEMPLATED_STREAMS
-# define BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
-# endif
-# if (__GNUC__ == 2 && __GNUC_MINOR__ <= 95)
-# define BOOST_LAMBDA_FAILS_IN_TEMPLATE_KEYWORD_AFTER_SCOPE_OPER
-# endif
# endif // __GNUC__
diff --git a/boost/lambda/detail/lambda_traits.hpp b/boost/lambda/detail/lambda_traits.hpp
index f35fa09735..cae0f38e6d 100644
--- a/boost/lambda/detail/lambda_traits.hpp
+++ b/boost/lambda/detail/lambda_traits.hpp
@@ -282,6 +282,11 @@ struct const_copy_argument<void> {
typedef void type;
};
+template<>
+struct const_copy_argument<void const> {
+ typedef void type;
+};
+
// Does the same as const_copy_argument, but passes references through as such
template<class T>
diff --git a/boost/lambda/detail/operator_return_type_traits.hpp b/boost/lambda/detail/operator_return_type_traits.hpp
index b2d3d3ad9c..6af4d03671 100644
--- a/boost/lambda/detail/operator_return_type_traits.hpp
+++ b/boost/lambda/detail/operator_return_type_traits.hpp
@@ -12,7 +12,13 @@
#define BOOST_LAMBDA_OPERATOR_RETURN_TYPE_TRAITS_HPP
#include "boost/lambda/detail/is_instance_of.hpp"
-#include "boost/type_traits/same_traits.hpp"
+#include "boost/type_traits/is_same.hpp"
+#include "boost/type_traits/is_pointer.hpp"
+#include "boost/type_traits/is_float.hpp"
+#include "boost/type_traits/is_convertible.hpp"
+#include "boost/type_traits/remove_pointer.hpp"
+#include "boost/type_traits/remove_const.hpp"
+#include "boost/type_traits/remove_reference.hpp"
#include "boost/indirect_reference.hpp"
#include "boost/detail/container_fwd.hpp"
@@ -536,36 +542,6 @@ struct return_type_2<bitwise_action<Act>, A, B>
namespace detail {
-#ifdef BOOST_NO_TEMPLATED_STREAMS
-
-template<class A, class B>
-struct leftshift_type {
-
- typedef typename detail::IF<
- boost::is_convertible<
- typename boost::remove_reference<A>::type*,
- std::ostream*
- >::value,
- std::ostream&,
- typename detail::remove_reference_and_cv<A>::type
- >::RET type;
-};
-
-template<class A, class B>
-struct rightshift_type {
-
- typedef typename detail::IF<
-
- boost::is_convertible<
- typename boost::remove_reference<A>::type*,
- std::istream*
- >::value,
- std::istream&,
- typename detail::remove_reference_and_cv<A>::type
- >::RET type;
-};
-
-#else
template <class T> struct get_ostream_type {
typedef std::basic_ostream<typename T::char_type,
@@ -602,7 +578,6 @@ public:
};
-#endif
} // end detail
diff --git a/boost/lambda/detail/operators.hpp b/boost/lambda/detail/operators.hpp
index 149e1eeaa4..136e28f1b4 100644
--- a/boost/lambda/detail/operators.hpp
+++ b/boost/lambda/detail/operators.hpp
@@ -161,23 +161,6 @@ namespace detail {
// Note that the overloading is const vs. non-const first argument
-#ifdef BOOST_NO_TEMPLATED_STREAMS
-template<class T> struct convert_ostream_to_ref_others_to_c_plain_by_default {
- typedef typename detail::IF<
- boost::is_convertible<T*, std::ostream*>::value,
- T&,
- typename const_copy_argument <T>::type
- >::RET type;
-};
-
-template<class T> struct convert_istream_to_ref_others_to_c_plain_by_default {
- typedef typename detail::IF<
- boost::is_convertible<T*, std::istream*>::value,
- T&,
- typename const_copy_argument <T>::type
- >::RET type;
-};
-#else
template<class T> struct convert_ostream_to_ref_others_to_c_plain_by_default {
typedef typename detail::IF<
@@ -198,7 +181,6 @@ template<class T> struct convert_istream_to_ref_others_to_c_plain_by_default {
typename const_copy_argument <T>::type
>::RET type;
};
-#endif
} // detail
diff --git a/boost/lambda/detail/return_type_traits.hpp b/boost/lambda/detail/return_type_traits.hpp
index bf2394ed18..da2879cbb0 100644
--- a/boost/lambda/detail/return_type_traits.hpp
+++ b/boost/lambda/detail/return_type_traits.hpp
@@ -19,10 +19,6 @@
namespace boost {
namespace lambda {
-using ::boost::type_traits::ice_and;
-using ::boost::type_traits::ice_or;
-using ::boost::type_traits::ice_not;
-
// Much of the type deduction code for standard arithmetic types
// from Gary Powell
@@ -77,8 +73,7 @@ template <class Act, class A> struct return_type_1_prot {
public:
typedef typename
detail::IF<
- // is_protectable<Act>::value && is_lambda_functor<A>::value,
- ice_and<is_protectable<Act>::value, is_lambda_functor<A>::value>::value,
+ is_protectable<Act>::value && is_lambda_functor<A>::value,
lambda_functor<
lambda_functor_base<
Act,
@@ -112,9 +107,7 @@ namespace detail {
// add const to rvalues, so that all rvalues are stored as const in
// the args tuple
typedef typename detail::IF_type<
-// boost::is_reference<T>::value && !boost::is_const<non_ref_T>::value,
- ice_and<boost::is_reference<T>::value,
- ice_not<boost::is_const<non_ref_T>::value>::value>::value,
+ boost::is_reference<T>::value && !boost::is_const<non_ref_T>::value,
detail::identity_mapping<T>,
const_copy_argument<non_ref_T> // handles funtion and array
>::type type; // types correctly
@@ -148,11 +141,8 @@ template <class Act, class A, class B> struct return_type_2_prot {
typedef typename
detail::IF<
-// is_protectable<Act>::value &&
-// (is_lambda_functor<A>::value || is_lambda_functor<B>::value),
- ice_and<is_protectable<Act>::value,
- ice_or<is_lambda_functor<A>::value,
- is_lambda_functor<B>::value>::value>::value,
+ is_protectable<Act>::value &&
+ (is_lambda_functor<A>::value || is_lambda_functor<B>::value),
lambda_functor<
lambda_functor_base<
Act,
@@ -187,11 +177,8 @@ struct return_type_2_comma
typedef typename
detail::IF<
-// is_protectable<other_action<comma_action> >::value && // it is protectable
-// (is_lambda_functor<A>::value || is_lambda_functor<B>::value),
- ice_and<is_protectable<other_action<comma_action> >::value, // it is protectable
- ice_or<is_lambda_functor<A>::value,
- is_lambda_functor<B>::value>::value>::value,
+ is_protectable<other_action<comma_action> >::value && // it is protectable
+ (is_lambda_functor<A>::value || is_lambda_functor<B>::value),
lambda_functor<
lambda_functor_base<
other_action<comma_action>,
diff --git a/boost/lambda/detail/suppress_unused.hpp b/boost/lambda/detail/suppress_unused.hpp
index 43999f1a92..5dd339d01b 100644
--- a/boost/lambda/detail/suppress_unused.hpp
+++ b/boost/lambda/detail/suppress_unused.hpp
@@ -10,8 +10,8 @@
// ------------------------------------------------------------
-#ifndef BOOST_LAMBDA_SUPRESS_UNUSED_HPP
-#define BOOST_LAMBDA_SUPRESS_UNUSED_HPP
+#ifndef BOOST_LAMBDA_SUPPRESS_UNUSED_HPP
+#define BOOST_LAMBDA_SUPPRESS_UNUSED_HPP
namespace boost {
namespace lambda {
diff --git a/boost/lambda/lambda.hpp b/boost/lambda/lambda.hpp
index 75b06c72fe..e1654a2964 100644
--- a/boost/lambda/lambda.hpp
+++ b/boost/lambda/lambda.hpp
@@ -24,11 +24,6 @@
#include "boost/lambda/detail/operators.hpp"
-
-#ifndef BOOST_LAMBDA_FAILS_IN_TEMPLATE_KEYWORD_AFTER_SCOPE_OPER
-// sorry, member ptr does not work with gcc2.95
#include "boost/lambda/detail/member_ptr.hpp"
-#endif
-
#endif
diff --git a/boost/lexical_cast.hpp b/boost/lexical_cast.hpp
index dc3d7e3fb7..a880c0cd9c 100644
--- a/boost/lexical_cast.hpp
+++ b/boost/lexical_cast.hpp
@@ -30,19 +30,20 @@
#include <boost/range/iterator_range_core.hpp>
#include <boost/lexical_cast/bad_lexical_cast.hpp>
#include <boost/lexical_cast/try_lexical_convert.hpp>
+#include <boost/utility/value_init.hpp>
namespace boost
{
template <typename Target, typename Source>
inline Target lexical_cast(const Source &arg)
{
- Target result;
+ boost::value_initialized<Target> result;
- if (!boost::conversion::detail::try_lexical_convert(arg, result)) {
+ if (!boost::conversion::detail::try_lexical_convert(arg, get(result))) {
boost::conversion::detail::throw_bad_cast<Source, Target>();
}
- return result;
+ return get(result);
}
template <typename Target>
diff --git a/boost/lexical_cast/detail/converter_lexical.hpp b/boost/lexical_cast/detail/converter_lexical.hpp
index 961dbde277..6a7878bdbe 100644
--- a/boost/lexical_cast/detail/converter_lexical.hpp
+++ b/boost/lexical_cast/detail/converter_lexical.hpp
@@ -30,8 +30,9 @@
#include <cstddef>
#include <string>
#include <boost/limits.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.hpp>
-#include <boost/type_traits/ice.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_float.hpp>
#include <boost/type_traits/has_left_shift.hpp>
@@ -422,28 +423,27 @@ namespace boost {
BOOST_DEDUCED_TYPENAME boost::detail::extract_char_traits<char_type, Target>,
BOOST_DEDUCED_TYPENAME boost::detail::extract_char_traits<char_type, no_cv_src>
>::type::trait_t traits;
-
- typedef boost::type_traits::ice_and<
- boost::is_same<char, src_char_t>::value, // source is not a wide character based type
- boost::type_traits::ice_ne<sizeof(char), sizeof(target_char_t) >::value, // target type is based on wide character
- boost::type_traits::ice_not<
- boost::detail::is_character<no_cv_src>::value // single character widening is optimized
- >::value // and does not requires stringbuffer
- > is_string_widening_required_t;
-
- typedef boost::type_traits::ice_not< boost::type_traits::ice_or<
- boost::is_integral<no_cv_src>::value,
- boost::detail::is_character<
+
+ typedef boost::mpl::bool_
+ <
+ boost::is_same<char, src_char_t>::value && // source is not a wide character based type
+ (sizeof(char) != sizeof(target_char_t)) && // target type is based on wide character
+ (!(boost::detail::is_character<no_cv_src>::value))
+ > is_string_widening_required_t;
+
+ typedef boost::mpl::bool_
+ <
+ !(boost::is_integral<no_cv_src>::value ||
+ boost::detail::is_character<
BOOST_DEDUCED_TYPENAME deduce_src_char_metafunc::stage1_type // if we did not get character type at stage1
- >::value // then we have no optimization for that type
- >::value > is_source_input_not_optimized_t;
-
+ >::value // then we have no optimization for that type
+ )
+ > is_source_input_not_optimized_t;
+
// If we have an optimized conversion for
// Source, we do not need to construct stringbuf.
BOOST_STATIC_CONSTANT(bool, requires_stringbuf =
- (boost::type_traits::ice_or<
- is_string_widening_required_t::value, is_source_input_not_optimized_t::value
- >::value)
+ (is_string_widening_required_t::value || is_source_input_not_optimized_t::value)
);
typedef boost::detail::lcast_src_length<no_cv_src> len_t;
diff --git a/boost/lexical_cast/detail/converter_lexical_streams.hpp b/boost/lexical_cast/detail/converter_lexical_streams.hpp
index 2d6617dadd..ba8d3b4dc3 100644
--- a/boost/lexical_cast/detail/converter_lexical_streams.hpp
+++ b/boost/lexical_cast/detail/converter_lexical_streams.hpp
@@ -34,7 +34,6 @@
#include <cstdio>
#include <boost/limits.hpp>
#include <boost/mpl/if.hpp>
-#include <boost/type_traits/ice.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/workaround.hpp>
diff --git a/boost/lexical_cast/detail/converter_numeric.hpp b/boost/lexical_cast/detail/converter_numeric.hpp
index 54f7a35ff4..a6cc8e77b8 100644
--- a/boost/lexical_cast/detail/converter_numeric.hpp
+++ b/boost/lexical_cast/detail/converter_numeric.hpp
@@ -24,8 +24,9 @@
#endif
#include <boost/limits.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.hpp>
-#include <boost/type_traits/ice.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/is_integral.hpp>
@@ -153,22 +154,35 @@ struct dynamic_num_converter_impl
{
static inline bool try_convert(const Source &arg, Target& result) BOOST_NOEXCEPT {
typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
- boost::type_traits::ice_and<
- boost::is_unsigned<Target>::value,
- boost::type_traits::ice_or<
- boost::is_signed<Source>::value,
- boost::is_float<Source>::value
- >::value,
- boost::type_traits::ice_not<
- boost::is_same<Source, bool>::value
- >::value,
- boost::type_traits::ice_not<
- boost::is_same<Target, bool>::value
- >::value
- >::value,
+ boost::is_unsigned<Target>::value &&
+ (boost::is_signed<Source>::value || boost::is_float<Source>::value) &&
+ !(boost::is_same<Source, bool>::value) &&
+ !(boost::is_same<Target, bool>::value),
lexical_cast_dynamic_num_ignoring_minus<Target, Source>,
lexical_cast_dynamic_num_not_ignoring_minus<Target, Source>
>::type caster_type;
+
+#if 0
+
+ typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
+ BOOST_DEDUCED_TYPENAME boost::mpl::and_<
+ boost::is_unsigned<Target>,
+ boost::mpl::or_<
+ boost::is_signed<Source>,
+ boost::is_float<Source>
+ >,
+ boost::mpl::not_<
+ boost::is_same<Source, bool>
+ >,
+ boost::mpl::not_<
+ boost::is_same<Target, bool>
+ >
+ >::type,
+ lexical_cast_dynamic_num_ignoring_minus<Target, Source>,
+ lexical_cast_dynamic_num_not_ignoring_minus<Target, Source>
+ >::type caster_type;
+
+#endif
return caster_type::try_convert(arg, result);
}
diff --git a/boost/lexical_cast/detail/is_character.hpp b/boost/lexical_cast/detail/is_character.hpp
index e967f58525..732c39f8e8 100644
--- a/boost/lexical_cast/detail/is_character.hpp
+++ b/boost/lexical_cast/detail/is_character.hpp
@@ -23,6 +23,7 @@
# pragma once
#endif
+#include <boost/mpl/bool.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost {
@@ -33,22 +34,22 @@ namespace boost {
template < typename T >
struct is_character
{
- typedef boost::type_traits::ice_or<
- boost::is_same< T, char >::value,
+ typedef BOOST_DEDUCED_TYPENAME boost::mpl::bool_<
+ boost::is_same< T, char >::value ||
#if !defined(BOOST_NO_STRINGSTREAM) && !defined(BOOST_NO_STD_WSTRING)
- boost::is_same< T, wchar_t >::value,
+ boost::is_same< T, wchar_t >::value ||
#endif
#ifndef BOOST_NO_CXX11_CHAR16_T
- boost::is_same< T, char16_t >::value,
+ boost::is_same< T, char16_t >::value ||
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
- boost::is_same< T, char32_t >::value,
+ boost::is_same< T, char32_t >::value ||
#endif
- boost::is_same< T, unsigned char >::value,
- boost::is_same< T, signed char >::value
- > result_type;
+ boost::is_same< T, unsigned char >::value ||
+ boost::is_same< T, signed char >::value
+ > type;
- BOOST_STATIC_CONSTANT(bool, value = (result_type::value) );
+ BOOST_STATIC_CONSTANT(bool, value = (type::value) );
};
}
}
diff --git a/boost/lexical_cast/detail/lcast_unsigned_converters.hpp b/boost/lexical_cast/detail/lcast_unsigned_converters.hpp
index efe91ede9a..268961ee72 100644
--- a/boost/lexical_cast/detail/lcast_unsigned_converters.hpp
+++ b/boost/lexical_cast/detail/lcast_unsigned_converters.hpp
@@ -30,7 +30,6 @@
#include <cstdio>
#include <boost/limits.hpp>
#include <boost/mpl/if.hpp>
-#include <boost/type_traits/ice.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/workaround.hpp>
diff --git a/boost/lexical_cast/try_lexical_convert.hpp b/boost/lexical_cast/try_lexical_convert.hpp
index a9e0a0aa2f..66270eee76 100644
--- a/boost/lexical_cast/try_lexical_convert.hpp
+++ b/boost/lexical_cast/try_lexical_convert.hpp
@@ -24,8 +24,9 @@
#endif
#include <string>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.hpp>
-#include <boost/type_traits/ice.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
@@ -57,17 +58,15 @@ namespace boost {
template<typename Target, typename Source>
struct is_arithmetic_and_not_xchars
{
+ typedef boost::mpl::bool_<
+ !(boost::detail::is_character<Target>::value) &&
+ !(boost::detail::is_character<Source>::value) &&
+ boost::is_arithmetic<Source>::value &&
+ boost::is_arithmetic<Target>::value
+ > type;
+
BOOST_STATIC_CONSTANT(bool, value = (
- boost::type_traits::ice_and<
- boost::type_traits::ice_not<
- boost::detail::is_character<Target>::value
- >::value,
- boost::type_traits::ice_not<
- boost::detail::is_character<Source>::value
- >::value,
- boost::is_arithmetic<Source>::value,
- boost::is_arithmetic<Target>::value
- >::value
+ type::value
));
};
@@ -78,13 +77,15 @@ namespace boost {
template<typename Target, typename Source>
struct is_xchar_to_xchar
{
- BOOST_STATIC_CONSTANT(bool, value = (
- boost::type_traits::ice_and<
- boost::type_traits::ice_eq<sizeof(Source), sizeof(Target)>::value,
- boost::type_traits::ice_eq<sizeof(Source), sizeof(char)>::value,
- boost::detail::is_character<Target>::value,
+ typedef boost::mpl::bool_<
+ sizeof(Source) == sizeof(Target) &&
+ sizeof(Source) == sizeof(char) &&
+ boost::detail::is_character<Target>::value &&
boost::detail::is_character<Source>::value
- >::value
+ > type;
+
+ BOOST_STATIC_CONSTANT(bool, value = (
+ type::value
));
};
@@ -140,17 +141,17 @@ namespace boost {
{
typedef BOOST_DEDUCED_TYPENAME boost::detail::array_to_pointer_decay<Source>::type src;
- typedef BOOST_DEDUCED_TYPENAME boost::type_traits::ice_or<
- boost::detail::is_xchar_to_xchar<Target, src >::value,
- boost::detail::is_char_array_to_stdstring<Target, src >::value,
- boost::type_traits::ice_and<
- boost::is_same<Target, src >::value,
+ typedef boost::mpl::bool_<
+ boost::detail::is_xchar_to_xchar<Target, src >::value ||
+ boost::detail::is_char_array_to_stdstring<Target, src >::value ||
+ (
+ boost::is_same<Target, src >::value &&
boost::detail::is_stdstring<Target >::value
- >::value,
- boost::type_traits::ice_and<
- boost::is_same<Target, src >::value,
+ ) ||
+ (
+ boost::is_same<Target, src >::value &&
boost::detail::is_character<Target >::value
- >::value
+ )
> shall_we_copy_t;
typedef boost::detail::is_arithmetic_and_not_xchars<Target, src >
diff --git a/boost/lockfree/detail/copy_payload.hpp b/boost/lockfree/detail/copy_payload.hpp
index a1aff54f05..75b1b52a2b 100644
--- a/boost/lockfree/detail/copy_payload.hpp
+++ b/boost/lockfree/detail/copy_payload.hpp
@@ -12,6 +12,11 @@
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_convertible.hpp>
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable: 4512) // assignment operator could not be generated
+#endif
+
namespace boost {
namespace lockfree {
namespace detail {
@@ -71,4 +76,8 @@ struct consume_noop
}}}
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
#endif /* BOOST_LOCKFREE_DETAIL_COPY_PAYLOAD_HPP_INCLUDED */
diff --git a/boost/lockfree/detail/freelist.hpp b/boost/lockfree/detail/freelist.hpp
index 739df08ee5..b053dce00c 100644
--- a/boost/lockfree/detail/freelist.hpp
+++ b/boost/lockfree/detail/freelist.hpp
@@ -466,6 +466,7 @@ public:
{
index_t index = tagged_index.get_index();
T * n = NodeStorage::nodes() + index;
+ (void)n; // silence msvc warning
n->~T();
deallocate<ThreadSafe>(index);
}
diff --git a/boost/lockfree/spsc_queue.hpp b/boost/lockfree/spsc_queue.hpp
index 444e681200..3fbbea7a86 100644
--- a/boost/lockfree/spsc_queue.hpp
+++ b/boost/lockfree/spsc_queue.hpp
@@ -86,7 +86,7 @@ protected:
size_t read_available(size_t max_size) const
{
- size_t write_index = write_index_.load(memory_order_relaxed);
+ size_t write_index = write_index_.load(memory_order_acquire);
const size_t read_index = read_index_.load(memory_order_relaxed);
return read_available(write_index, read_index, max_size);
}
@@ -94,7 +94,7 @@ protected:
size_t write_available(size_t max_size) const
{
size_t write_index = write_index_.load(memory_order_relaxed);
- const size_t read_index = read_index_.load(memory_order_relaxed);
+ const size_t read_index = read_index_.load(memory_order_acquire);
return write_available(write_index, read_index, max_size);
}
@@ -914,7 +914,7 @@ public:
*
* \return number of available elements that can be popped from the spsc_queue
*
- * \note Thread-safe and wait-free, should only be called from the producer thread
+ * \note Thread-safe and wait-free, should only be called from the consumer thread
* */
size_type read_available() const
{
@@ -925,7 +925,7 @@ public:
*
* \return number of elements that can be pushed to the spsc_queue
*
- * \note Thread-safe and wait-free, should only be called from the consumer thread
+ * \note Thread-safe and wait-free, should only be called from the producer thread
* */
size_type write_available() const
{
@@ -936,7 +936,7 @@ public:
*
* Availability of front element can be checked using read_available().
*
- * \pre only one thread is allowed to check front element
+ * \pre only a consuming thread is allowed to check front element
* \pre read_available() > 0. If ringbuffer is empty, it's undefined behaviour to invoke this method.
* \return reference to the first element in the queue
*
diff --git a/boost/log/attributes/attribute_value.hpp b/boost/log/attributes/attribute_value.hpp
index 95014c19ad..7cc11bfa8e 100644
--- a/boost/log/attributes/attribute_value.hpp
+++ b/boost/log/attributes/attribute_value.hpp
@@ -15,11 +15,11 @@
#ifndef BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_
#define BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_
+#include <boost/type_index.hpp>
#include <boost/move/core.hpp>
#include <boost/smart_ptr/intrusive_ptr.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/utility/explicit_operator_bool.hpp>
-#include <boost/log/utility/type_info_wrapper.hpp>
#include <boost/log/utility/type_dispatch/type_dispatcher.hpp>
#include <boost/log/attributes/attribute.hpp>
#include <boost/log/attributes/value_extraction_fwd.hpp>
@@ -103,7 +103,7 @@ public:
/*!
* \return The attribute value type
*/
- virtual type_info_wrapper get_type() const { return type_info_wrapper(); }
+ virtual typeindex::type_index get_type() const { return typeindex::type_index(); }
};
private:
@@ -166,12 +166,12 @@ public:
* the information cannot be provided. If the returned value is not empty, the type
* can be used for value extraction.
*/
- type_info_wrapper get_type() const
+ typeindex::type_index get_type() const
{
if (m_pImpl.get())
return m_pImpl->get_type();
else
- return type_info_wrapper();
+ return typeindex::type_index();
}
/*!
diff --git a/boost/log/attributes/attribute_value_impl.hpp b/boost/log/attributes/attribute_value_impl.hpp
index 99bf022e72..50ba812271 100644
--- a/boost/log/attributes/attribute_value_impl.hpp
+++ b/boost/log/attributes/attribute_value_impl.hpp
@@ -15,6 +15,7 @@
#ifndef BOOST_LOG_ATTRIBUTES_ATTRIBUTE_VALUE_IMPL_HPP_INCLUDED_
#define BOOST_LOG_ATTRIBUTES_ATTRIBUTE_VALUE_IMPL_HPP_INCLUDED_
+#include <boost/type_index.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility.hpp>
#include <boost/type_traits/remove_cv.hpp>
@@ -87,7 +88,7 @@ public:
/*!
* \return The attribute value type
*/
- type_info_wrapper get_type() const { return type_info_wrapper(typeid(value_type)); }
+ typeindex::type_index get_type() const { return typeindex::type_id< value_type >(); }
/*!
* \return Reference to the contained value.
diff --git a/boost/log/attributes/current_thread_id.hpp b/boost/log/attributes/current_thread_id.hpp
index 0861a370be..23573e38be 100644
--- a/boost/log/attributes/current_thread_id.hpp
+++ b/boost/log/attributes/current_thread_id.hpp
@@ -79,7 +79,7 @@ protected:
return new detached_value(boost::log::aux::this_thread::get_id());
}
- type_info_wrapper get_type() const { return type_info_wrapper(typeid(value_type)); }
+ typeindex::type_index get_type() const { return typeindex::type_id< value_type >(); }
};
public:
diff --git a/boost/log/attributes/fallback_policy.hpp b/boost/log/attributes/fallback_policy.hpp
index 549b81df9f..cde3e94623 100644
--- a/boost/log/attributes/fallback_policy.hpp
+++ b/boost/log/attributes/fallback_policy.hpp
@@ -15,11 +15,11 @@
#ifndef BOOST_LOG_ATTRIBUTES_FALLBACK_POLICY_HPP_INCLUDED_
#define BOOST_LOG_ATTRIBUTES_FALLBACK_POLICY_HPP_INCLUDED_
+#include <boost/type_index.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/log/exceptions.hpp>
-#include <boost/log/utility/type_info_wrapper.hpp>
#include <boost/log/attributes/fallback_policy_fwd.hpp>
#include <boost/log/detail/header.hpp>
@@ -59,7 +59,7 @@ struct fallback_to_none
/*!
* The method is called when value extraction failed because the attribute value has different type than requested.
*/
- static void on_invalid_type(type_info_wrapper const&)
+ static void on_invalid_type(typeindex::type_index const&)
{
}
@@ -99,7 +99,7 @@ struct fallback_to_throw
/*!
* The method is called when value extraction failed because the attribute value has different type than requested.
*/
- static void on_invalid_type(type_info_wrapper const& t)
+ static void on_invalid_type(typeindex::type_index const& t)
{
BOOST_LOG_THROW_DESCR_PARAMS(invalid_type, "Attribute value has incompatible type", (t));
}
@@ -161,7 +161,7 @@ struct fallback_to_default
/*!
* The method is called when value extraction failed because the attribute value has different type than requested.
*/
- static void on_invalid_type(type_info_wrapper const&)
+ static void on_invalid_type(typeindex::type_index const&)
{
}
diff --git a/boost/log/core/record_view.hpp b/boost/log/core/record_view.hpp
index 613f93dab3..6fa7a63f98 100644
--- a/boost/log/core/record_view.hpp
+++ b/boost/log/core/record_view.hpp
@@ -88,8 +88,8 @@ private:
BOOST_DELETED_FUNCTION(public_data(public_data const&))
BOOST_DELETED_FUNCTION(public_data& operator= (public_data const&))
- friend void intrusive_ptr_add_ref(const public_data* p) { ++p->m_ref_counter; }
- friend void intrusive_ptr_release(const public_data* p) { if (--p->m_ref_counter == 0) public_data::destroy(p); }
+ friend void intrusive_ptr_add_ref(const public_data* p) BOOST_NOEXCEPT { ++p->m_ref_counter; }
+ friend void intrusive_ptr_release(const public_data* p) BOOST_NOEXCEPT { if (--p->m_ref_counter == 0) public_data::destroy(p); }
};
private:
diff --git a/boost/log/detail/code_conversion.hpp b/boost/log/detail/code_conversion.hpp
index 4c39f9c02b..41c086e109 100644
--- a/boost/log/detail/code_conversion.hpp
+++ b/boost/log/detail/code_conversion.hpp
@@ -16,9 +16,12 @@
#ifndef BOOST_LOG_DETAIL_CODE_CONVERSION_HPP_INCLUDED_
#define BOOST_LOG_DETAIL_CODE_CONVERSION_HPP_INCLUDED_
+#include <cstddef>
#include <locale>
#include <string>
+#include <boost/core/enable_if.hpp>
#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/is_character_type.hpp>
#include <boost/log/detail/header.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
@@ -32,44 +35,64 @@ BOOST_LOG_OPEN_NAMESPACE
namespace aux {
//! The function converts one string to the character type of another
-BOOST_LOG_API void code_convert(const wchar_t* str1, std::size_t len, std::string& str2, std::locale const& loc = std::locale());
+BOOST_LOG_API void code_convert_impl(const wchar_t* str1, std::size_t len, std::string& str2, std::locale const& loc = std::locale());
//! The function converts one string to the character type of another
-BOOST_LOG_API void code_convert(const char* str1, std::size_t len, std::wstring& str2, std::locale const& loc = std::locale());
+BOOST_LOG_API void code_convert_impl(const char* str1, std::size_t len, std::wstring& str2, std::locale const& loc = std::locale());
-// Note: MSVC 2015 (aka VC14) implement char16_t and char32_t types but not codecvt locale facets
-#if !defined(BOOST_MSVC)
+#if !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
#if !defined(BOOST_NO_CXX11_CHAR16_T)
//! The function converts one string to the character type of another
-BOOST_LOG_API void code_convert(const char16_t* str1, std::size_t len, std::string& str2, std::locale const& loc = std::locale());
+BOOST_LOG_API void code_convert_impl(const char16_t* str1, std::size_t len, std::string& str2, std::locale const& loc = std::locale());
//! The function converts one string to the character type of another
-BOOST_LOG_API void code_convert(const char* str1, std::size_t len, std::u16string& str2, std::locale const& loc = std::locale());
+BOOST_LOG_API void code_convert_impl(const char* str1, std::size_t len, std::u16string& str2, std::locale const& loc = std::locale());
+//! The function converts one string to the character type of another
+BOOST_LOG_API void code_convert_impl(const char16_t* str1, std::size_t len, std::wstring& str2, std::locale const& loc = std::locale());
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
//! The function converts one string to the character type of another
-BOOST_LOG_API void code_convert(const char32_t* str1, std::size_t len, std::string& str2, std::locale const& loc = std::locale());
+BOOST_LOG_API void code_convert_impl(const char32_t* str1, std::size_t len, std::string& str2, std::locale const& loc = std::locale());
+//! The function converts one string to the character type of another
+BOOST_LOG_API void code_convert_impl(const char* str1, std::size_t len, std::u32string& str2, std::locale const& loc = std::locale());
+//! The function converts one string to the character type of another
+BOOST_LOG_API void code_convert_impl(const char32_t* str1, std::size_t len, std::wstring& str2, std::locale const& loc = std::locale());
+#endif
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_CHAR32_T)
+//! The function converts one string to the character type of another
+BOOST_LOG_API void code_convert_impl(const char16_t* str1, std::size_t len, std::u32string& str2, std::locale const& loc = std::locale());
//! The function converts one string to the character type of another
-BOOST_LOG_API void code_convert(const char* str1, std::size_t len, std::u32string& str2, std::locale const& loc = std::locale());
+BOOST_LOG_API void code_convert_impl(const char32_t* str1, std::size_t len, std::u16string& str2, std::locale const& loc = std::locale());
#endif
-#endif // !defined(BOOST_MSVC)
+#endif // !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
//! The function converts one string to the character type of another
-template< typename CharT, typename SourceTraitsT, typename SourceAllocatorT, typename TargetTraitsT, typename TargetAllocatorT >
-inline void code_convert(std::basic_string< CharT, SourceTraitsT, SourceAllocatorT > const& str1, std::basic_string< CharT, TargetTraitsT, TargetAllocatorT >& str2, std::locale const& = std::locale())
+template< typename SourceCharT, typename SourceTraitsT, typename SourceAllocatorT, typename TargetCharT, typename TargetTraitsT, typename TargetAllocatorT >
+inline typename boost::enable_if_c< is_character_type< SourceCharT >::value && is_character_type< TargetCharT >::value && sizeof(SourceCharT) == sizeof(TargetCharT) >::type
+code_convert(std::basic_string< SourceCharT, SourceTraitsT, SourceAllocatorT > const& str1, std::basic_string< TargetCharT, TargetTraitsT, TargetAllocatorT >& str2, std::locale const& = std::locale())
{
- str2.append(str1.c_str(), str1.size());
+ str2.append(reinterpret_cast< const TargetCharT* >(str1.c_str()), str1.size());
}
//! The function converts one string to the character type of another
-template< typename CharT, typename TargetTraitsT, typename TargetAllocatorT >
-inline void code_convert(const CharT* str1, std::size_t len, std::basic_string< CharT, TargetTraitsT, TargetAllocatorT >& str2, std::locale const& = std::locale())
+template< typename SourceCharT, typename TargetCharT, typename TargetTraitsT, typename TargetAllocatorT >
+inline typename boost::enable_if_c< is_character_type< SourceCharT >::value && is_character_type< TargetCharT >::value && sizeof(SourceCharT) == sizeof(TargetCharT) >::type
+code_convert(const SourceCharT* str1, std::size_t len, std::basic_string< TargetCharT, TargetTraitsT, TargetAllocatorT >& str2, std::locale const& = std::locale())
{
- str2.append(str1, len);
+ str2.append(reinterpret_cast< const TargetCharT* >(str1), len);
}
//! The function converts one string to the character type of another
template< typename SourceCharT, typename SourceTraitsT, typename SourceAllocatorT, typename TargetCharT, typename TargetTraitsT, typename TargetAllocatorT >
-inline void code_convert(std::basic_string< SourceCharT, SourceTraitsT, SourceAllocatorT > const& str1, std::basic_string< TargetCharT, TargetTraitsT, TargetAllocatorT >& str2, std::locale const& loc = std::locale())
+inline typename boost::enable_if_c< is_character_type< SourceCharT >::value && is_character_type< TargetCharT >::value && sizeof(SourceCharT) != sizeof(TargetCharT) >::type
+code_convert(std::basic_string< SourceCharT, SourceTraitsT, SourceAllocatorT > const& str1, std::basic_string< TargetCharT, TargetTraitsT, TargetAllocatorT >& str2, std::locale const& loc = std::locale())
+{
+ aux::code_convert_impl(str1.c_str(), str1.size(), str2, loc);
+}
+
+//! The function converts one string to the character type of another
+template< typename SourceCharT, typename TargetCharT, typename TargetTraitsT, typename TargetAllocatorT >
+inline typename boost::enable_if_c< is_character_type< SourceCharT >::value && is_character_type< TargetCharT >::value && sizeof(SourceCharT) != sizeof(TargetCharT) >::type
+code_convert(const SourceCharT* str1, std::size_t len, std::basic_string< TargetCharT, TargetTraitsT, TargetAllocatorT >& str2, std::locale const& loc = std::locale())
{
- aux::code_convert(str1.c_str(), str1.size(), str2, loc);
+ aux::code_convert_impl(str1, len, str2, loc);
}
//! The function converts the passed string to the narrow-character encoding
diff --git a/boost/log/detail/config.hpp b/boost/log/detail/config.hpp
index c5a73679ae..64b4412383 100644
--- a/boost/log/detail/config.hpp
+++ b/boost/log/detail/config.hpp
@@ -96,6 +96,13 @@
# define BOOST_LOG_BROKEN_CONSTANT_EXPRESSIONS
#endif
+#if defined(BOOST_NO_CXX11_HDR_CODECVT)
+ // The compiler does not support std::codecvt<char16_t> and std::codecvt<char32_t> specializations.
+ // The BOOST_NO_CXX11_HDR_CODECVT means there's no usable <codecvt>, which is slightly different from this macro.
+ // But in order for <codecvt> to be implemented the std::codecvt specializations have to be implemented as well.
+# define BOOST_LOG_NO_CXX11_CODECVT_FACETS
+#endif
+
#if defined(__CYGWIN__)
// Boost.ASIO is broken on Cygwin
# define BOOST_LOG_NO_ASIO
diff --git a/boost/log/detail/event.hpp b/boost/log/detail/event.hpp
index 4bb49822c1..0168e170e7 100644
--- a/boost/log/detail/event.hpp
+++ b/boost/log/detail/event.hpp
@@ -22,12 +22,15 @@
#ifndef BOOST_LOG_NO_THREADS
#if defined(BOOST_THREAD_PLATFORM_PTHREAD)
-# if defined(_POSIX_SEMAPHORES) && (_POSIX_SEMAPHORES + 0) > 0
-# if defined(__GNUC__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
-# include <semaphore.h>
-# include <boost/cstdint.hpp>
-# define BOOST_LOG_EVENT_USE_POSIX_SEMAPHORE
-# endif
+# include <boost/atomic/capabilities.hpp>
+# if (defined(linux) || defined(__linux) || defined(__linux__)) && BOOST_ATOMIC_INT_LOCK_FREE == 2
+# include <boost/atomic/atomic.hpp>
+# define BOOST_LOG_EVENT_USE_FUTEX
+# elif defined(_POSIX_SEMAPHORES) && (_POSIX_SEMAPHORES + 0) > 0 && BOOST_ATOMIC_FLAG_LOCK_FREE == 2
+# include <semaphore.h>
+# include <boost/cstdint.hpp>
+# include <boost/atomic/atomic_flag.hpp>
+# define BOOST_LOG_EVENT_USE_POSIX_SEMAPHORE
# endif
#elif defined(BOOST_THREAD_PLATFORM_WIN32)
# include <boost/cstdint.hpp>
@@ -48,12 +51,37 @@ BOOST_LOG_OPEN_NAMESPACE
namespace aux {
-#if defined(BOOST_LOG_EVENT_USE_POSIX_SEMAPHORE)
+#if defined(BOOST_LOG_EVENT_USE_FUTEX)
+
+class futex_based_event
+{
+private:
+ boost::atomic< int > m_state;
+
+public:
+ //! Default constructor
+ BOOST_LOG_API futex_based_event();
+ //! Destructor
+ BOOST_LOG_API ~futex_based_event();
+
+ //! Waits for the object to become signalled
+ BOOST_LOG_API void wait();
+ //! Sets the object to a signalled state
+ BOOST_LOG_API void set_signalled();
+
+ // Copying prohibited
+ BOOST_DELETED_FUNCTION(futex_based_event(futex_based_event const&))
+ BOOST_DELETED_FUNCTION(futex_based_event& operator= (futex_based_event const&))
+};
+
+typedef futex_based_event event;
+
+#elif defined(BOOST_LOG_EVENT_USE_POSIX_SEMAPHORE)
class sem_based_event
{
private:
- boost::uint32_t m_state;
+ boost::atomic_flag m_state;
sem_t m_semaphore;
public:
diff --git a/boost/log/detail/is_character_type.hpp b/boost/log/detail/is_character_type.hpp
new file mode 100644
index 0000000000..29f7dccd55
--- /dev/null
+++ b/boost/log/detail/is_character_type.hpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright Andrey Semashev 2007 - 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)
+ */
+/*!
+ * \file is_character_type.hpp
+ * \author Andrey Semashev
+ * \date 25.07.2015
+ *
+ * The header defines \c is_character_type trait which checks if the type is one of the character types
+ */
+
+#ifndef BOOST_LOG_DETAIL_IS_CHARACTER_TYPE_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_IS_CHARACTER_TYPE_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+template< typename T >
+struct is_character_type
+{
+ static BOOST_CONSTEXPR_OR_CONST bool value = false;
+};
+
+template< >
+struct is_character_type< char >
+{
+ static BOOST_CONSTEXPR_OR_CONST bool value = true;
+};
+
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+template< >
+struct is_character_type< wchar_t >
+{
+ static BOOST_CONSTEXPR_OR_CONST bool value = true;
+};
+#endif
+
+#if !defined(BOOST_NO_CXX11_CHAR16_T)
+template< >
+struct is_character_type< char16_t >
+{
+ static BOOST_CONSTEXPR_OR_CONST bool value = true;
+};
+#endif
+
+#if !defined(BOOST_NO_CXX11_CHAR32_T)
+template< >
+struct is_character_type< char32_t >
+{
+ static BOOST_CONSTEXPR_OR_CONST bool value = true;
+};
+#endif
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_IS_CHARACTER_TYPE_HPP_INCLUDED_
diff --git a/boost/log/detail/visible_type.hpp b/boost/log/detail/is_ostream.hpp
index 79f4007d2a..2131baebb5 100644
--- a/boost/log/detail/visible_type.hpp
+++ b/boost/log/detail/is_ostream.hpp
@@ -5,19 +5,23 @@
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*!
- * \file visible_type.hpp
+ * \file is_ostream.hpp
* \author Andrey Semashev
- * \date 08.03.2007
+ * \date 05.07.2015
*
* \brief This header is the Boost.Log library implementation, see the library documentation
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. In this file
* internal configuration macros are defined.
*/
-#ifndef BOOST_LOG_DETAIL_VISIBLE_TYPE_HPP_INCLUDED_
-#define BOOST_LOG_DETAIL_VISIBLE_TYPE_HPP_INCLUDED_
+#ifndef BOOST_LOG_DETAIL_IS_OSTREAM_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_IS_OSTREAM_HPP_INCLUDED_
+#include <iosfwd>
+#include <boost/type_traits/is_base_of.hpp>
+#include <boost/type_traits/has_left_shift.hpp>
#include <boost/log/detail/config.hpp>
+#include <boost/log/utility/formatting_ostream_fwd.hpp>
#include <boost/log/detail/header.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
@@ -30,11 +34,16 @@ BOOST_LOG_OPEN_NAMESPACE
namespace aux {
-//! The wrapper type whose type_info is always visible
template< typename T >
-struct BOOST_SYMBOL_VISIBLE visible_type
+struct is_ostream
{
- typedef T wrapped_type;
+ static BOOST_CONSTEXPR_OR_CONST bool value = is_base_of< std::ios_base, T >::value && has_left_shift< T, int >::value;
+};
+
+template< typename CharT, typename TraitsT, typename AllocatorT >
+struct is_ostream< basic_formatting_ostream< CharT, TraitsT, AllocatorT > >
+{
+ static BOOST_CONSTEXPR_OR_CONST bool value = true;
};
} // namespace aux
@@ -45,4 +54,4 @@ BOOST_LOG_CLOSE_NAMESPACE // namespace log
#include <boost/log/detail/footer.hpp>
-#endif // BOOST_LOG_DETAIL_VISIBLE_TYPE_HPP_INCLUDED_
+#endif // BOOST_LOG_DETAIL_IS_OSTREAM_HPP_INCLUDED_
diff --git a/boost/log/exceptions.hpp b/boost/log/exceptions.hpp
index f5bcbc436e..8f305fabeb 100644
--- a/boost/log/exceptions.hpp
+++ b/boost/log/exceptions.hpp
@@ -18,10 +18,10 @@
#include <cstddef>
#include <string>
#include <stdexcept>
+#include <boost/type_index.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/log/attributes/attribute_name.hpp>
-#include <boost/log/utility/type_info_wrapper.hpp>
#include <boost/log/detail/header.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
@@ -130,8 +130,8 @@ public:
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, attribute_name const& name);
- static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, type_info_wrapper const& type);
- static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, attribute_name const& name, type_info_wrapper const& type);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, typeindex::type_index const& type);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, attribute_name const& name, typeindex::type_index const& type);
#endif
};
diff --git a/boost/log/expressions/formatters/c_decorator.hpp b/boost/log/expressions/formatters/c_decorator.hpp
index 9c2b62d726..ec3f485405 100644
--- a/boost/log/expressions/formatters/c_decorator.hpp
+++ b/boost/log/expressions/formatters/c_decorator.hpp
@@ -60,7 +60,7 @@ struct c_decorator_traits< char >
template< unsigned int N >
static std::size_t print_escaped(char (&buf)[N], char c)
{
- int n = boost::log::aux::snprintf(buf, N, "\\x%0.2X", static_cast< unsigned int >(static_cast< uint8_t >(c)));
+ int n = boost::log::aux::snprintf(buf, N, "\\x%.2X", static_cast< unsigned int >(static_cast< uint8_t >(c)));
if (n < 0)
{
n = 0;
@@ -98,17 +98,17 @@ struct c_decorator_traits< wchar_t >
unsigned int val;
if (sizeof(wchar_t) == 1)
{
- format = L"\\x%0.2X";
+ format = L"\\x%.2X";
val = static_cast< uint8_t >(c);
}
else if (sizeof(wchar_t) == 2)
{
- format = L"\\x%0.4X";
+ format = L"\\x%.4X";
val = static_cast< uint16_t >(c);
}
else
{
- format = L"\\x%0.8X";
+ format = L"\\x%.8X";
val = static_cast< uint32_t >(c);
}
@@ -148,7 +148,7 @@ struct c_decorator_gen
* can be used to construct the actual decorator. For example:
*
* <code>
- * c_decor[ attr< std::string >("MyAttr") ]
+ * c_decor[ stream << attr< std::string >("MyAttr") ]
* </code>
*
* For wide-character formatting there is the similar \c wc_decor decorator generator object.
@@ -231,7 +231,6 @@ struct c_ascii_decorator_gen
template< typename SubactorT >
BOOST_FORCEINLINE char_decorator_actor< SubactorT, c_ascii_pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
{
- typedef c_decorator_traits< char_type > traits_type;
typedef c_ascii_pattern_replacer< char_type > replacer_type;
typedef char_decorator_actor< SubactorT, replacer_type > result_type;
typedef typename result_type::terminal_type terminal_type;
@@ -249,7 +248,7 @@ struct c_ascii_decorator_gen
* can be used to construct the actual decorator. For example:
*
* <code>
- * c_ascii_decor[ attr< std::string >("MyAttr") ]
+ * c_ascii_decor[ stream << attr< std::string >("MyAttr") ]
* </code>
*
* For wide-character formatting there is the similar \c wc_ascii_decor decorator generator object.
diff --git a/boost/log/expressions/formatters/csv_decorator.hpp b/boost/log/expressions/formatters/csv_decorator.hpp
index e28daf2e2e..a4c1c28399 100644
--- a/boost/log/expressions/formatters/csv_decorator.hpp
+++ b/boost/log/expressions/formatters/csv_decorator.hpp
@@ -108,7 +108,7 @@ struct csv_decorator_gen
* the actual decorator. For example:
*
* <code>
- * csv_decor[ attr< std::string >("MyAttr") ]
+ * csv_decor[ stream << attr< std::string >("MyAttr") ]
* </code>
*
* For wide-character formatting there is the similar \c wcsv_decor decorator generator object.
diff --git a/boost/log/expressions/formatters/xml_decorator.hpp b/boost/log/expressions/formatters/xml_decorator.hpp
index 0a7613328a..ca93a7d58a 100644
--- a/boost/log/expressions/formatters/xml_decorator.hpp
+++ b/boost/log/expressions/formatters/xml_decorator.hpp
@@ -106,7 +106,7 @@ struct xml_decorator_gen
* <tt>operator[]</tt> that can be used to construct the actual decorator. For example:
*
* <code>
- * xml_decor[ attr< std::string >("MyAttr") ]
+ * xml_decor[ stream << attr< std::string >("MyAttr") ]
* </code>
*
* For wide-character formatting there is the similar \c wxml_decor decorator generator object.
diff --git a/boost/log/sinks/event_log_backend.hpp b/boost/log/sinks/event_log_backend.hpp
index 08d211cea7..5378295160 100644
--- a/boost/log/sinks/event_log_backend.hpp
+++ b/boost/log/sinks/event_log_backend.hpp
@@ -562,7 +562,7 @@ public:
* The following named parameters are supported:
*
* \li \c message_file - Specifies the file name that contains resources that
- * describe events and categories.
+ * describe events and categories. This parameter is mandatory unless \c registration is \c never.
* \li \c target - Specifies an UNC path to the remote server to which log records should be sent to.
* The local machine will be used to process log records, if not specified.
* \li \c log_name - Specifies the log in which the source should be registered.
@@ -625,7 +625,7 @@ private:
void construct(ArgsT const& args)
{
construct(
- filesystem::path(args[keywords::message_file]),
+ filesystem::path(args[keywords::message_file | filesystem::path()]),
args[keywords::target | string_type()],
args[keywords::log_name || &basic_event_log_backend::get_default_log_name],
args[keywords::log_source || &basic_event_log_backend::get_default_source_name],
diff --git a/boost/log/sources/global_logger_storage.hpp b/boost/log/sources/global_logger_storage.hpp
index ffbc4313e3..a98e5e63e1 100644
--- a/boost/log/sources/global_logger_storage.hpp
+++ b/boost/log/sources/global_logger_storage.hpp
@@ -15,14 +15,13 @@
#ifndef BOOST_LOG_SOURCES_GLOBAL_LOGGER_STORAGE_HPP_INCLUDED_
#define BOOST_LOG_SOURCES_GLOBAL_LOGGER_STORAGE_HPP_INCLUDED_
-#include <typeinfo>
#include <stdexcept>
+#include <boost/type_index.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared_object.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/log/detail/singleton.hpp>
-#include <boost/log/detail/visible_type.hpp>
#include <boost/log/detail/header.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
@@ -41,17 +40,19 @@ namespace aux {
struct BOOST_LOG_NO_VTABLE BOOST_SYMBOL_VISIBLE logger_holder_base
{
//! The source file name where the logger was registered
- const char* m_RegistrationFile;
+ const char* const m_RegistrationFile;
//! The line number where the logger was registered
- unsigned int m_RegistrationLine;
+ const unsigned int m_RegistrationLine;
+ //! Stored logger type
+ const typeindex::type_index m_LoggerType;
- logger_holder_base(const char* file, unsigned int line) :
+ logger_holder_base(const char* file, unsigned int line, typeindex::type_index logger_type) BOOST_NOEXCEPT :
m_RegistrationFile(file),
- m_RegistrationLine(line)
+ m_RegistrationLine(line),
+ m_LoggerType(logger_type)
{
}
virtual ~logger_holder_base() {}
- virtual std::type_info const& logger_type() const = 0;
};
//! The actual logger holder class
@@ -63,11 +64,10 @@ struct BOOST_SYMBOL_VISIBLE logger_holder :
LoggerT m_Logger;
logger_holder(const char* file, unsigned int line, LoggerT const& logger) :
- logger_holder_base(file, line),
+ logger_holder_base(file, line, typeindex::type_id< LoggerT >()),
m_Logger(logger)
{
}
- std::type_info const& logger_type() const { return typeid(LoggerT); }
};
//! The class implements a global repository of tagged loggers
@@ -76,7 +76,7 @@ struct global_storage
typedef shared_ptr< logger_holder_base >(*initializer_t)();
//! Finds or creates the logger and returns its holder
- BOOST_LOG_API static shared_ptr< logger_holder_base > get_or_init(std::type_info const& key, initializer_t initializer);
+ BOOST_LOG_API static shared_ptr< logger_holder_base > get_or_init(typeindex::type_index key, initializer_t initializer);
// Non-constructible, non-copyable, non-assignable
BOOST_DELETED_FUNCTION(global_storage())
@@ -86,8 +86,8 @@ struct global_storage
//! Throws the \c odr_violation exception
BOOST_LOG_API BOOST_LOG_NORETURN void throw_odr_violation(
- std::type_info const& tag_type,
- std::type_info const& logger_type,
+ typeindex::type_index tag_type,
+ typeindex::type_index logger_type,
logger_holder_base const& registered);
//! The class implements a logger singleton
@@ -116,18 +116,24 @@ struct logger_singleton :
static void init_instance()
{
shared_ptr< logger_holder< logger_type > >& instance = base_type::get_instance();
- shared_ptr< logger_holder_base > holder = global_storage::get_or_init(
- typeid(boost::log::aux::visible_type< TagT >),
- &logger_singleton::construct_logger);
- instance = boost::dynamic_pointer_cast< logger_holder< logger_type > >(holder);
- if (!instance)
+ const typeindex::type_index tag_type_index = typeindex::type_id< TagT >();
+ shared_ptr< logger_holder_base > holder = global_storage::get_or_init(tag_type_index, &logger_singleton::construct_logger);
+ const typeindex::type_index logger_type_index = typeindex::type_id< logger_type >();
+ if (holder->m_LoggerType == logger_type_index)
+ {
+ // Note: dynamic_cast may fail here if logger_type is not visible (for example, with Clang on Linux, if the original logger
+ // instance was initialized in a different DSO than where it's being queried). logger_holder default visibility doesn't
+ // help since it is inhibited by the template parameter visibility.
+ instance = boost::static_pointer_cast< logger_holder< logger_type > >(holder);
+ }
+ else
{
// In pure C++ this should never happen, since there cannot be two
// different tag types that have equal type_infos. In real life it can
// happen if the same-named tag is defined differently in two or more
// dlls. This check is intended to detect such ODR violations. However, there
// is no protection against different definitions of the logger type itself.
- throw_odr_violation(typeid(TagT), typeid(logger_type), *holder);
+ throw_odr_violation(tag_type_index, logger_type_index, *holder);
}
}
diff --git a/boost/log/support/exception.hpp b/boost/log/support/exception.hpp
index e880115ee6..f6d9be20d5 100644
--- a/boost/log/support/exception.hpp
+++ b/boost/log/support/exception.hpp
@@ -15,11 +15,11 @@
#ifndef BOOST_LOG_SUPPORT_EXCEPTION_HPP_INCLUDED_
#define BOOST_LOG_SUPPORT_EXCEPTION_HPP_INCLUDED_
+#include <boost/type_index.hpp>
#include <boost/exception/info.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/log/attributes/attribute_name.hpp>
#include <boost/log/attributes/named_scope.hpp>
-#include <boost/log/utility/type_info_wrapper.hpp>
#include <boost/log/detail/header.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
@@ -38,7 +38,7 @@ typedef error_info< struct attribute_name_info_tag, attribute_name > attribute_n
/*!
* Type info exception information
*/
-typedef error_info< struct type_info_info_tag, type_info_wrapper > type_info_info;
+typedef error_info< struct type_info_info_tag, typeindex::type_index > type_info_info;
/*!
* Parse position exception information
diff --git a/boost/log/utility/empty_deleter.hpp b/boost/log/utility/empty_deleter.hpp
deleted file mode 100644
index 09bf29c7e8..0000000000
--- a/boost/log/utility/empty_deleter.hpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright Andrey Semashev 2007 - 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)
- */
-/*!
- * \file empty_deleter.hpp
- * \author Andrey Semashev
- * \date 22.04.2007
- *
- * This header is deprecated, use boost/utility/empty_deleter.hpp instead. The header is left for
- * backward compatibility and will be removed in future versions.
- */
-
-#ifndef BOOST_LOG_UTILITY_EMPTY_DELETER_HPP_INCLUDED_
-#define BOOST_LOG_UTILITY_EMPTY_DELETER_HPP_INCLUDED_
-
-#include <boost/core/null_deleter.hpp>
-#include <boost/log/detail/config.hpp>
-
-#ifdef BOOST_HAS_PRAGMA_ONCE
-#pragma once
-#endif
-
-#if defined(__GNUC__)
-#pragma message "Boost.Log: This header is deprecated, use boost/core/null_deleter.hpp instead."
-#elif defined(_MSC_VER)
-#pragma message("Boost.Log: This header is deprecated, use boost/core/null_deleter.hpp instead.")
-#endif
-
-namespace boost {
-
-BOOST_LOG_OPEN_NAMESPACE
-
-typedef boost::null_deleter empty_deleter;
-
-BOOST_LOG_CLOSE_NAMESPACE // namespace log
-
-} // namespace boost
-
-#endif // BOOST_LOG_UTILITY_EMPTY_DELETER_HPP_INCLUDED_
diff --git a/boost/log/utility/explicit_operator_bool.hpp b/boost/log/utility/explicit_operator_bool.hpp
deleted file mode 100644
index d30aff6070..0000000000
--- a/boost/log/utility/explicit_operator_bool.hpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright Andrey Semashev 2007 - 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)
- */
-/*!
- * \file explicit_operator_bool.hpp
- * \author Andrey Semashev
- * \date 08.03.2009
- *
- * This header is deprecated, use boost/utility/explicit_operator_bool.hpp instead. The header is left for
- * backward compatibility and will be removed in future versions.
- */
-
-#ifndef BOOST_LOG_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_
-#define BOOST_LOG_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_
-
-#include <boost/utility/explicit_operator_bool.hpp>
-#include <boost/log/detail/config.hpp>
-
-#ifdef BOOST_HAS_PRAGMA_ONCE
-#pragma once
-#endif
-
-#if defined(__GNUC__)
-#pragma message "Boost.Log: This header is deprecated, use boost/utility/explicit_operator_bool.hpp instead."
-#elif defined(_MSC_VER)
-#pragma message("Boost.Log: This header is deprecated, use boost/utility/explicit_operator_bool.hpp instead.")
-#endif
-
-/*!
- * \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 <tt>operator!</tt>,
- * in terms of which the conversion operator will be implemented.
- */
-#define BOOST_LOG_EXPLICIT_OPERATOR_BOOL()\
- BOOST_EXPLICIT_OPERATOR_BOOL()
-
-#endif // BOOST_LOG_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_
diff --git a/boost/log/utility/formatting_ostream.hpp b/boost/log/utility/formatting_ostream.hpp
index 13f367f791..4345206f12 100644
--- a/boost/log/utility/formatting_ostream.hpp
+++ b/boost/log/utility/formatting_ostream.hpp
@@ -19,6 +19,7 @@
#include <string>
#include <memory>
#include <locale>
+#include <boost/core/explicit_operator_bool.hpp>
#include <boost/utility/string_ref_fwd.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/log/detail/config.hpp>
@@ -26,7 +27,6 @@
#include <boost/log/detail/code_conversion.hpp>
#include <boost/log/utility/string_literal_fwd.hpp>
#include <boost/log/utility/formatting_ostream_fwd.hpp>
-#include <boost/utility/explicit_operator_bool.hpp>
#include <boost/log/detail/header.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
@@ -40,19 +40,26 @@ BOOST_LOG_OPEN_NAMESPACE
namespace aux {
template< typename T, typename R >
-struct enable_if_char_type {};
+struct enable_if_streamable_char_type {};
template< typename R >
-struct enable_if_char_type< char, R > { typedef R type; };
+struct enable_if_streamable_char_type< char, R > { typedef R type; };
template< typename R >
-struct enable_if_char_type< wchar_t, R > { typedef R type; };
+struct enable_if_streamable_char_type< wchar_t, R > { typedef R type; };
+#if !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
#if !defined(BOOST_NO_CXX11_CHAR16_T)
template< typename R >
-struct enable_if_char_type< char16_t, R > { typedef R type; };
+struct enable_if_streamable_char_type< char16_t, R > { typedef R type; };
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
template< typename R >
-struct enable_if_char_type< char32_t, R > { typedef R type; };
+struct enable_if_streamable_char_type< char32_t, R > { typedef R type; };
#endif
+#endif
+
+template< typename StreamT, typename R >
+struct enable_if_formatting_ostream {};
+template< typename CharT, typename TraitsT, typename AllocatorT, typename R >
+struct enable_if_formatting_ostream< basic_formatting_ostream< CharT, TraitsT, AllocatorT >, R > { typedef R type; };
} // namespace aux
@@ -338,7 +345,7 @@ public:
}
template< typename OtherCharT >
- typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type
+ typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
put(OtherCharT c)
{
write(&c, 1);
@@ -352,7 +359,7 @@ public:
}
template< typename OtherCharT >
- typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type
+ typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
write(const OtherCharT* p, std::streamsize size)
{
sentry guard(*this);
@@ -402,6 +409,7 @@ public:
return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< wchar_t >::length(p)));
}
#endif
+#if !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
#if !defined(BOOST_NO_CXX11_CHAR16_T)
basic_formatting_ostream& operator<< (char16_t c)
{
@@ -422,6 +430,7 @@ public:
return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char32_t >::length(p)));
}
#endif
+#endif
basic_formatting_ostream& operator<< (bool value)
{
@@ -510,26 +519,91 @@ public:
}
template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
- friend typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type
+ friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
operator<< (basic_formatting_ostream& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT > const& str)
{
return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
}
template< typename OtherCharT, typename OtherTraitsT >
- friend typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type
+ friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
operator<< (basic_formatting_ostream& strm, basic_string_literal< OtherCharT, OtherTraitsT > const& str)
{
return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
}
template< typename OtherCharT, typename OtherTraitsT >
- friend typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type
+ friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
operator<< (basic_formatting_ostream& strm, basic_string_ref< OtherCharT, OtherTraitsT > const& str)
{
return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
}
+ template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
+ friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
+ operator<< (basic_formatting_ostream& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT >& str)
+ {
+ return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
+ }
+
+ template< typename OtherCharT, typename OtherTraitsT >
+ friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
+ operator<< (basic_formatting_ostream& strm, basic_string_literal< OtherCharT, OtherTraitsT >& str)
+ {
+ return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
+ }
+
+ template< typename OtherCharT, typename OtherTraitsT >
+ friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
+ operator<< (basic_formatting_ostream& strm, basic_string_ref< OtherCharT, OtherTraitsT >& str)
+ {
+ return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
+ }
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
+ friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
+ operator<< (basic_formatting_ostream&& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT > const& str)
+ {
+ return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
+ }
+
+ template< typename OtherCharT, typename OtherTraitsT >
+ friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
+ operator<< (basic_formatting_ostream&& strm, basic_string_literal< OtherCharT, OtherTraitsT > const& str)
+ {
+ return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
+ }
+
+ template< typename OtherCharT, typename OtherTraitsT >
+ friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
+ operator<< (basic_formatting_ostream&& strm, basic_string_ref< OtherCharT, OtherTraitsT > const& str)
+ {
+ return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
+ }
+
+ template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
+ friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
+ operator<< (basic_formatting_ostream&& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT >& str)
+ {
+ return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
+ }
+
+ template< typename OtherCharT, typename OtherTraitsT >
+ friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
+ operator<< (basic_formatting_ostream&& strm, basic_string_literal< OtherCharT, OtherTraitsT >& str)
+ {
+ return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
+ }
+
+ template< typename OtherCharT, typename OtherTraitsT >
+ friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
+ operator<< (basic_formatting_ostream&& strm, basic_string_ref< OtherCharT, OtherTraitsT >& str)
+ {
+ return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
+ }
+#endif
+
private:
void init_stream()
{
@@ -703,17 +777,19 @@ void basic_formatting_ostream< CharT, TraitsT, AllocatorT >::aligned_write(const
}
}
-template< typename CharT, typename TraitsT, typename AllocatorT, typename T >
-inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >&
-operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, T const& value)
+// Implementation note: these operators below should be the least attractive for the compiler
+// so that user's overloads are chosen, when present. We use function template partial ordering for this purpose.
+template< typename StreamT, typename T >
+inline typename boost::log::aux::enable_if_formatting_ostream< StreamT, StreamT& >::type
+operator<< (StreamT& strm, T const& value)
{
strm.stream() << value;
return strm;
}
-template< typename CharT, typename TraitsT, typename AllocatorT, typename T >
-inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >&
-operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, T& value)
+template< typename StreamT, typename T >
+inline typename boost::log::aux::enable_if_formatting_ostream< StreamT, StreamT& >::type
+operator<< (StreamT& strm, T& value)
{
strm.stream() << value;
return strm;
@@ -721,19 +797,19 @@ operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, T& val
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
-template< typename CharT, typename TraitsT, typename AllocatorT, typename T >
-inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >&
-operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >&& strm, T const& value)
+template< typename StreamT, typename T >
+inline typename boost::log::aux::enable_if_formatting_ostream< StreamT, StreamT& >::type
+operator<< (StreamT&& strm, T const& value)
{
- static_cast< basic_formatting_ostream< CharT, TraitsT, AllocatorT >& >(strm) << value;
+ strm.stream() << value;
return strm;
}
-template< typename CharT, typename TraitsT, typename AllocatorT, typename T >
-inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >&
-operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >&& strm, T& value)
+template< typename StreamT, typename T >
+inline typename boost::log::aux::enable_if_formatting_ostream< StreamT, StreamT& >::type
+operator<< (StreamT&& strm, T& value)
{
- static_cast< basic_formatting_ostream< CharT, TraitsT, AllocatorT >& >(strm) << value;
+ strm.stream() << value;
return strm;
}
diff --git a/boost/log/utility/intrusive_ref_counter.hpp b/boost/log/utility/intrusive_ref_counter.hpp
deleted file mode 100644
index 87f8ccc70b..0000000000
--- a/boost/log/utility/intrusive_ref_counter.hpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright Andrey Semashev 2007 - 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)
- */
-/*!
- * \file intrusive_ref_counter.hpp
- * \author Andrey Semashev
- * \date 12.03.2009
- *
- * This header is deprecated, use boost/smart_ptr/intrusive_ref_counter.hpp instead. The header is left for
- * backward compatibility and will be removed in future versions.
- */
-
-#ifndef BOOST_LOG_UTILITY_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
-#define BOOST_LOG_UTILITY_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
-
-#include <boost/smart_ptr/intrusive_ptr.hpp>
-#include <boost/smart_ptr/intrusive_ref_counter.hpp>
-#include <boost/log/detail/config.hpp>
-#include <boost/log/detail/header.hpp>
-
-#ifdef BOOST_HAS_PRAGMA_ONCE
-#pragma once
-#endif
-
-#if defined(__GNUC__)
-#pragma message "Boost.Log: This header is deprecated, use boost/smart_ptr/intrusive_ref_counter.hpp instead."
-#elif defined(_MSC_VER)
-#pragma message("Boost.Log: This header is deprecated, use boost/smart_ptr/intrusive_ref_counter.hpp instead.")
-#endif
-
-namespace boost {
-
-BOOST_LOG_OPEN_NAMESPACE
-
-namespace aux {
-
-struct legacy_intrusive_ref_counter_root
-{
- virtual ~legacy_intrusive_ref_counter_root() {}
-};
-
-} // namespace aux
-
-typedef boost::intrusive_ref_counter< aux::legacy_intrusive_ref_counter_root > intrusive_ref_counter;
-
-BOOST_LOG_CLOSE_NAMESPACE // namespace log
-
-} // namespace boost
-
-#include <boost/log/detail/footer.hpp>
-
-#endif // BOOST_LOG_UTILITY_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
diff --git a/boost/log/utility/manipulators/to_log.hpp b/boost/log/utility/manipulators/to_log.hpp
index 20ea2c261d..9186616903 100644
--- a/boost/log/utility/manipulators/to_log.hpp
+++ b/boost/log/utility/manipulators/to_log.hpp
@@ -16,8 +16,9 @@
#define BOOST_LOG_UTILITY_MANIPULATORS_TO_LOG_HPP_INCLUDED_
#include <iosfwd>
-#include <boost/mpl/bool.hpp>
+#include <boost/core/enable_if.hpp>
#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/is_ostream.hpp>
#include <boost/log/utility/formatting_ostream_fwd.hpp>
#include <boost/log/detail/header.hpp>
@@ -46,34 +47,27 @@ private:
value_type const& m_value;
public:
- explicit to_log_manip(value_type const& value) : m_value(value) {}
- to_log_manip(to_log_manip const& that) : m_value(that.m_value) {}
+ explicit to_log_manip(value_type const& value) BOOST_NOEXCEPT : m_value(value) {}
+ to_log_manip(to_log_manip const& that) BOOST_NOEXCEPT : m_value(that.m_value) {}
- value_type const& get() const { return m_value; }
+ value_type const& get() const BOOST_NOEXCEPT { return m_value; }
};
-template< typename CharT, typename TraitsT, typename T, typename TagT >
-inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, to_log_manip< T, TagT > manip)
-{
- strm << manip.get();
- return strm;
-}
-
-template< typename CharT, typename TraitsT, typename AllocatorT, typename T, typename TagT >
-inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >& operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, to_log_manip< T, TagT > manip)
+template< typename StreamT, typename T, typename TagT >
+inline typename enable_if_c< log::aux::is_ostream< StreamT >::value, StreamT& >::type operator<< (StreamT& strm, to_log_manip< T, TagT > manip)
{
strm << manip.get();
return strm;
}
template< typename T >
-inline to_log_manip< T > to_log(T const& value)
+inline to_log_manip< T > to_log(T const& value) BOOST_NOEXCEPT
{
return to_log_manip< T >(value);
}
template< typename TagT, typename T >
-inline to_log_manip< T, TagT > to_log(T const& value)
+inline to_log_manip< T, TagT > to_log(T const& value) BOOST_NOEXCEPT
{
return to_log_manip< T, TagT >(value);
}
diff --git a/boost/log/utility/type_dispatch/date_time_types.hpp b/boost/log/utility/type_dispatch/date_time_types.hpp
index 36c9265213..38e6a461f8 100644
--- a/boost/log/utility/type_dispatch/date_time_types.hpp
+++ b/boost/log/utility/type_dispatch/date_time_types.hpp
@@ -17,9 +17,7 @@
#include <ctime>
#include <boost/mpl/vector.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/mpl/push_back.hpp>
+#include <boost/preprocessor/seq/enum.hpp>
#include <boost/date_time/gregorian/gregorian_types.hpp>
#include <boost/date_time/local_time/local_time_types.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
@@ -34,29 +32,73 @@ namespace boost {
BOOST_LOG_OPEN_NAMESPACE
+//! Boost.Preprocessor sequence of the standard C date/time types
+#define BOOST_LOG_NATIVE_DATE_TIME_TYPES()\
+ (std::time_t)(std::tm)
+
+//! Boost.Preprocessor sequence of the standard C date types
+#define BOOST_LOG_NATIVE_DATE_TYPES()\
+ BOOST_LOG_NATIVE_DATE_TIME_TYPES()
+
+//! Boost.Preprocessor sequence of the Boost date/time types
+#define BOOST_LOG_BOOST_DATE_TIME_TYPES()\
+ (boost::posix_time::ptime)(boost::local_time::local_date_time)
+
+//! Boost.Preprocessor sequence of date/time types
+#define BOOST_LOG_DATE_TIME_TYPES()\
+ BOOST_LOG_NATIVE_DATE_TIME_TYPES()BOOST_LOG_BOOST_DATE_TIME_TYPES()\
+
+//! Boost.Preprocessor sequence of the Boost date types
+#define BOOST_LOG_BOOST_DATE_TYPES()\
+ BOOST_LOG_BOOST_DATE_TIME_TYPES()(boost::gregorian::date)
+
+//! Boost.Preprocessor sequence of date types
+#define BOOST_LOG_DATE_TYPES()\
+ BOOST_LOG_NATIVE_DATE_TYPES()BOOST_LOG_BOOST_DATE_TYPES()
+
+
+//! Boost.Preprocessor sequence of the standard time duration types
+#define BOOST_LOG_NATIVE_TIME_DURATION_TYPES()\
+ (double) /* result of difftime() */
+
+//! Boost.Preprocessor sequence of the Boost time duration types
+#define BOOST_LOG_BOOST_TIME_DURATION_TYPES()\
+ (boost::posix_time::time_duration)(boost::gregorian::date_duration)
+
+//! Boost.Preprocessor sequence of time duration types
+#define BOOST_LOG_TIME_DURATION_TYPES()\
+ BOOST_LOG_NATIVE_TIME_DURATION_TYPES()BOOST_LOG_BOOST_TIME_DURATION_TYPES()
+
+
+//! Boost.Preprocessor sequence of the Boost time period types
+#define BOOST_LOG_BOOST_TIME_PERIOD_TYPES()\
+ (boost::posix_time::time_period)(boost::local_time::local_time_period)(boost::gregorian::date_period)
+
+//! Boost.Preprocessor sequence of time period types
+#define BOOST_LOG_TIME_PERIOD_TYPES()\
+ BOOST_LOG_BOOST_TIME_PERIOD_TYPES()
+
+
/*!
* An MPL-sequence of natively supported date and time types of attributes
*/
typedef mpl::vector<
- std::time_t,
- std::tm
+ BOOST_PP_SEQ_ENUM(BOOST_LOG_NATIVE_DATE_TIME_TYPES())
> native_date_time_types;
/*!
* An MPL-sequence of Boost date and time types of attributes
*/
typedef mpl::vector<
- posix_time::ptime,
- local_time::local_date_time
+ BOOST_PP_SEQ_ENUM(BOOST_LOG_BOOST_DATE_TIME_TYPES())
> boost_date_time_types;
/*!
* An MPL-sequence with the complete list of the supported date and time types
*/
-typedef mpl::copy<
- boost_date_time_types,
- mpl::back_inserter< native_date_time_types >
->::type date_time_types;
+typedef mpl::vector<
+ BOOST_PP_SEQ_ENUM(BOOST_LOG_DATE_TIME_TYPES())
+> date_time_types;
/*!
* An MPL-sequence of natively supported date types of attributes
@@ -66,18 +108,16 @@ typedef native_date_time_types native_date_types;
/*!
* An MPL-sequence of Boost date types of attributes
*/
-typedef mpl::push_back<
- boost_date_time_types,
- gregorian::date
->::type boost_date_types;
+typedef mpl::vector<
+ BOOST_PP_SEQ_ENUM(BOOST_LOG_BOOST_DATE_TYPES())
+> boost_date_types;
/*!
* An MPL-sequence with the complete list of the supported date types
*/
-typedef mpl::copy<
- boost_date_types,
- mpl::back_inserter< native_date_types >
->::type date_types;
+typedef mpl::vector<
+ BOOST_PP_SEQ_ENUM(BOOST_LOG_DATE_TYPES())
+> date_types;
/*!
* An MPL-sequence of natively supported time types
@@ -96,32 +136,28 @@ typedef date_time_types time_types;
* An MPL-sequence of natively supported time duration types of attributes
*/
typedef mpl::vector<
- double // result of difftime
+ BOOST_PP_SEQ_ENUM(BOOST_LOG_NATIVE_TIME_DURATION_TYPES())
> native_time_duration_types;
/*!
* An MPL-sequence of Boost time duration types of attributes
*/
typedef mpl::vector<
- posix_time::time_duration,
- gregorian::date_duration
+ BOOST_PP_SEQ_ENUM(BOOST_LOG_BOOST_TIME_DURATION_TYPES())
> boost_time_duration_types;
/*!
* An MPL-sequence with the complete list of the supported time duration types
*/
-typedef mpl::copy<
- boost_time_duration_types,
- mpl::back_inserter< native_time_duration_types >
->::type time_duration_types;
+typedef mpl::vector<
+ BOOST_PP_SEQ_ENUM(BOOST_LOG_TIME_DURATION_TYPES())
+> time_duration_types;
/*!
* An MPL-sequence of Boost time duration types of attributes
*/
typedef mpl::vector<
- posix_time::time_period,
- local_time::local_time_period,
- gregorian::date_period
+ BOOST_PP_SEQ_ENUM(BOOST_LOG_BOOST_TIME_PERIOD_TYPES())
> boost_time_period_types;
/*!
diff --git a/boost/log/utility/type_dispatch/dynamic_type_dispatcher.hpp b/boost/log/utility/type_dispatch/dynamic_type_dispatcher.hpp
index 63c7bc1120..d01228a5da 100644
--- a/boost/log/utility/type_dispatch/dynamic_type_dispatcher.hpp
+++ b/boost/log/utility/type_dispatch/dynamic_type_dispatcher.hpp
@@ -19,11 +19,10 @@
#include <memory>
#include <map>
#include <boost/ref.hpp>
+#include <boost/type_index.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared_object.hpp>
#include <boost/log/detail/config.hpp>
-#include <boost/log/detail/visible_type.hpp>
-#include <boost/log/utility/type_info_wrapper.hpp>
#include <boost/log/utility/type_dispatch/type_dispatcher.hpp>
#include <boost/log/detail/header.hpp>
@@ -78,7 +77,7 @@ private:
#endif // BOOST_LOG_DOXYGEN_PASS
//! The dispatching map
- typedef std::map< type_info_wrapper, shared_ptr< callback_base > > dispatching_map;
+ typedef std::map< typeindex::type_index, shared_ptr< callback_base > > dispatching_map;
dispatching_map m_DispatchingMap;
public:
@@ -118,7 +117,7 @@ public:
boost::shared_ptr< callback_base > p(
boost::make_shared< callback_impl< T, VisitorT > >(boost::cref(visitor)));
- type_info_wrapper wrapper(typeid(aux::visible_type< T >));
+ typeindex::type_index wrapper(typeindex::type_id< T >());
m_DispatchingMap[wrapper].swap(p);
}
@@ -132,11 +131,10 @@ public:
private:
#ifndef BOOST_LOG_DOXYGEN_PASS
- static callback_base get_callback(type_dispatcher* p, std::type_info const& type)
+ static callback_base get_callback(type_dispatcher* p, typeindex::type_index type)
{
dynamic_type_dispatcher* const self = static_cast< dynamic_type_dispatcher* >(p);
- type_info_wrapper wrapper(type);
- dispatching_map::iterator it = self->m_DispatchingMap.find(wrapper);
+ dispatching_map::iterator it = self->m_DispatchingMap.find(type);
if (it != self->m_DispatchingMap.end())
return *it->second;
else
diff --git a/boost/log/utility/type_dispatch/standard_types.hpp b/boost/log/utility/type_dispatch/standard_types.hpp
index a437f6f00a..fc01be34b4 100644
--- a/boost/log/utility/type_dispatch/standard_types.hpp
+++ b/boost/log/utility/type_dispatch/standard_types.hpp
@@ -17,8 +17,10 @@
#include <string>
#include <boost/mpl/vector.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/back_inserter.hpp>
+#include <boost/mpl/vector/vector30.hpp> // needed to use mpl::vector sizes greater than 20 even when the default BOOST_MPL_LIMIT_VECTOR_SIZE is not set
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/seq/enum.hpp>
+#include <boost/preprocessor/seq/size.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/log/utility/string_literal_fwd.hpp>
#include <boost/log/detail/header.hpp>
@@ -31,70 +33,108 @@ namespace boost {
BOOST_LOG_OPEN_NAMESPACE
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+#define BOOST_LOG_AUX_STANDARD_TYPE_WCHAR_T() (wchar_t)
+#else
+#define BOOST_LOG_AUX_STANDARD_TYPE_WCHAR_T()
+#endif
+
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
+#define BOOST_LOG_AUX_STANDARD_TYPE_CHAR16_T() (char16_t)
+#else
+#define BOOST_LOG_AUX_STANDARD_TYPE_CHAR16_T()
+#endif
+
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
+#define BOOST_LOG_AUX_STANDARD_TYPE_CHAR32_T() (char32_t)
+#else
+#define BOOST_LOG_AUX_STANDARD_TYPE_CHAR32_T()
+#endif
+
+//! Boost.Preprocessor sequence of character types
+#define BOOST_LOG_STANDARD_CHAR_TYPES()\
+ (char)BOOST_LOG_AUX_STANDARD_TYPE_WCHAR_T()BOOST_LOG_AUX_STANDARD_TYPE_CHAR16_T()BOOST_LOG_AUX_STANDARD_TYPE_CHAR32_T()
+
+#if defined(BOOST_HAS_LONG_LONG)
+#define BOOST_LOG_AUX_STANDARD_LONG_LONG_TYPES() (long long)(unsigned long long)
+#else
+#define BOOST_LOG_AUX_STANDARD_LONG_LONG_TYPES()
+#endif
+
+//! Boost.Preprocessor sequence of integral types
+#define BOOST_LOG_STANDARD_INTEGRAL_TYPES()\
+ (bool)(signed char)(unsigned char)(short)(unsigned short)(int)(unsigned int)(long)(unsigned long)BOOST_LOG_AUX_STANDARD_LONG_LONG_TYPES()\
+ BOOST_LOG_STANDARD_CHAR_TYPES()
+
+//! Boost.Preprocessor sequence of floating point types
+#define BOOST_LOG_STANDARD_FLOATING_POINT_TYPES()\
+ (float)(double)(long double)
+
+//! Boost.Preprocessor sequence of arithmetic types
+#define BOOST_LOG_STANDARD_ARITHMETIC_TYPES()\
+ BOOST_LOG_STANDARD_INTEGRAL_TYPES()BOOST_LOG_STANDARD_FLOATING_POINT_TYPES()
+
+#if defined(BOOST_LOG_USE_CHAR)
+#define BOOST_LOG_AUX_STANDARD_STRING_TYPES() (std::string)(boost::log::string_literal)
+#else
+#define BOOST_LOG_AUX_STANDARD_STRING_TYPES()
+#endif
+
+#if defined(BOOST_LOG_USE_WCHAR_T)
+#define BOOST_LOG_AUX_STANDARD_WSTRING_TYPES() (std::wstring)(boost::log::wstring_literal)
+#else
+#define BOOST_LOG_AUX_STANDARD_WSTRING_TYPES()
+#endif
+
+//! Boost.Preprocessor sequence of string types
+#define BOOST_LOG_STANDARD_STRING_TYPES()\
+ BOOST_LOG_AUX_STANDARD_STRING_TYPES()BOOST_LOG_AUX_STANDARD_WSTRING_TYPES()
+
+//! Boost.Preprocessor sequence of the default attribute value types supported by the library
+#define BOOST_LOG_DEFAULT_ATTRIBUTE_VALUE_TYPES()\
+ BOOST_LOG_STANDARD_ARITHMETIC_TYPES()BOOST_LOG_STANDARD_STRING_TYPES()
+
+
/*!
* An MPL-sequence of integral types of attributes, supported by default
*/
typedef mpl::vector<
- bool,
- char,
-#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
- wchar_t,
-#endif
- signed char,
- unsigned char,
- short,
- unsigned short,
- int,
- unsigned int,
- long,
- unsigned long
-#if defined(BOOST_HAS_LONG_LONG)
- , long long
- , unsigned long long
-#endif // defined(BOOST_HAS_LONG_LONG)
+ BOOST_PP_SEQ_ENUM(BOOST_LOG_STANDARD_INTEGRAL_TYPES())
> integral_types;
/*!
* An MPL-sequence of FP types of attributes, supported by default
*/
typedef mpl::vector<
- float,
- double,
- long double
+ BOOST_PP_SEQ_ENUM(BOOST_LOG_STANDARD_FLOATING_POINT_TYPES())
> floating_point_types;
/*!
* An MPL-sequence of all numeric types of attributes, supported by default
*/
-typedef mpl::copy<
- floating_point_types,
- mpl::back_inserter< integral_types >
->::type numeric_types;
+typedef mpl::vector<
+ BOOST_PP_SEQ_ENUM(BOOST_LOG_STANDARD_ARITHMETIC_TYPES())
+> arithmetic_types;
+
+//! Deprecated alias
+typedef arithmetic_types numeric_types;
/*!
* An MPL-sequence of string types of attributes, supported by default
*/
typedef mpl::vector<
-#ifdef BOOST_LOG_USE_CHAR
- std::string,
- string_literal
-#ifdef BOOST_LOG_USE_WCHAR_T
- ,
-#endif
-#endif
-#ifdef BOOST_LOG_USE_WCHAR_T
- std::wstring,
- wstring_literal
-#endif
+ BOOST_PP_SEQ_ENUM(BOOST_LOG_STANDARD_STRING_TYPES())
> string_types;
/*!
* An MPL-sequence of all attribute value types that are supported by the library by default.
*/
-typedef mpl::copy<
- string_types,
- mpl::back_inserter< numeric_types >
->::type default_attribute_types;
+typedef BOOST_PP_CAT(mpl::vector, BOOST_PP_SEQ_SIZE(BOOST_LOG_DEFAULT_ATTRIBUTE_VALUE_TYPES()))<
+ BOOST_PP_SEQ_ENUM(BOOST_LOG_DEFAULT_ATTRIBUTE_VALUE_TYPES())
+> default_attribute_value_types;
+
+//! Deprecated alias
+typedef default_attribute_value_types default_attribute_types;
BOOST_LOG_CLOSE_NAMESPACE // namespace log
diff --git a/boost/log/utility/type_dispatch/static_type_dispatcher.hpp b/boost/log/utility/type_dispatch/static_type_dispatcher.hpp
index a5743e28e0..bae420f7e5 100644
--- a/boost/log/utility/type_dispatch/static_type_dispatcher.hpp
+++ b/boost/log/utility/type_dispatch/static_type_dispatcher.hpp
@@ -21,6 +21,7 @@
#include <algorithm>
#include <boost/array.hpp>
#include <boost/static_assert.hpp>
+#include <boost/type_index.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/begin.hpp>
@@ -30,9 +31,7 @@
#include <boost/mpl/is_sequence.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/log/detail/config.hpp>
-#include <boost/log/detail/visible_type.hpp>
#include <boost/log/utility/once_block.hpp>
-#include <boost/log/utility/type_info_wrapper.hpp>
#include <boost/log/utility/type_dispatch/type_dispatcher.hpp>
#include <boost/log/detail/header.hpp>
@@ -50,7 +49,7 @@ namespace aux {
struct dispatching_map_order
{
typedef bool result_type;
- typedef std::pair< type_info_wrapper, void* > first_argument_type, second_argument_type;
+ typedef std::pair< typeindex::type_index, void* > first_argument_type, second_argument_type;
result_type operator() (first_argument_type const& left, second_argument_type const& right) const
{
return (left.first < right.first);
@@ -62,15 +61,15 @@ template< typename VisitorT >
struct dispatching_map_initializer
{
template< typename IteratorT >
- static BOOST_FORCEINLINE void init(IteratorT*, IteratorT*, std::pair< type_info_wrapper, void* >*)
+ static BOOST_FORCEINLINE void init(IteratorT*, IteratorT*, std::pair< typeindex::type_index, void* >*)
{
}
template< typename BeginIteratorT, typename EndIteratorT >
- static BOOST_FORCEINLINE void init(BeginIteratorT*, EndIteratorT* end, std::pair< type_info_wrapper, void* >* p)
+ static BOOST_FORCEINLINE void init(BeginIteratorT*, EndIteratorT* end, std::pair< typeindex::type_index, void* >* p)
{
typedef typename mpl::deref< BeginIteratorT >::type type;
- do_init(static_cast< visible_type< type >* >(0), p);
+ do_init(static_cast< type* >(0), p);
typedef typename mpl::next< BeginIteratorT >::type next_iterator_type;
init(static_cast< next_iterator_type* >(0), end, p + 1);
@@ -78,9 +77,9 @@ struct dispatching_map_initializer
private:
template< typename T >
- static BOOST_FORCEINLINE void do_init(visible_type< T >*, std::pair< type_info_wrapper, void* >* p)
+ static BOOST_FORCEINLINE void do_init(T*, std::pair< typeindex::type_index, void* >* p)
{
- p->first = typeid(visible_type< T >);
+ p->first = typeindex::type_id< T >();
typedef void (*trampoline_t)(void*, T const&);
BOOST_STATIC_ASSERT_MSG(sizeof(trampoline_t) == sizeof(void*), "Boost.Log: Unsupported platform, the size of a function pointer differs from the size of a pointer");
@@ -101,7 +100,7 @@ class type_sequence_dispatcher_base :
{
private:
//! Dispatching map element type
- typedef std::pair< type_info_wrapper, void* > dispatching_map_element_type;
+ typedef std::pair< typeindex::type_index, void* > dispatching_map_element_type;
private:
//! Dispatching map
@@ -123,21 +122,20 @@ protected:
private:
//! The get_callback method implementation
- static callback_base get_callback(type_dispatcher* p, std::type_info const& type)
+ static callback_base get_callback(type_dispatcher* p, typeindex::type_index type)
{
type_sequence_dispatcher_base* const self = static_cast< type_sequence_dispatcher_base* >(p);
- type_info_wrapper wrapper(type);
const dispatching_map_element_type* begin = self->m_dispatching_map_begin;
const dispatching_map_element_type* end = begin + self->m_dispatching_map_size;
const dispatching_map_element_type* it = std::lower_bound
(
begin,
end,
- dispatching_map_element_type(wrapper, (void*)0),
+ dispatching_map_element_type(type, (void*)0),
dispatching_map_order()
);
- if (it != end && it->first == wrapper)
+ if (it != end && it->first == type)
return callback_base(self->m_visitor, it->second);
else
return callback_base();
@@ -160,7 +158,7 @@ public:
private:
//! The dispatching map
typedef array<
- std::pair< type_info_wrapper, void* >,
+ std::pair< typeindex::type_index, void* >,
mpl::size< supported_types >::value
> dispatching_map;
@@ -210,13 +208,13 @@ class single_type_dispatcher_base :
{
private:
//! The type to match against
- std::type_info const& m_type;
+ typeindex::type_index m_type;
//! A callback for the supported type
callback_base m_callback;
protected:
//! Initializing constructor
- single_type_dispatcher_base(std::type_info const& type, callback_base const& callback) BOOST_NOEXCEPT :
+ single_type_dispatcher_base(typeindex::type_index type, callback_base const& callback) BOOST_NOEXCEPT :
type_dispatcher(&single_type_dispatcher_base::get_callback),
m_type(type),
m_callback(callback)
@@ -225,7 +223,7 @@ protected:
private:
//! The get_callback method implementation
- static callback_base get_callback(type_dispatcher* p, std::type_info const& type)
+ static callback_base get_callback(type_dispatcher* p, typeindex::type_index type)
{
single_type_dispatcher_base* const self = static_cast< single_type_dispatcher_base* >(p);
if (type == self->m_type)
@@ -248,7 +246,7 @@ public:
//! Constructor
template< typename VisitorT >
explicit single_type_dispatcher(VisitorT& visitor) BOOST_NOEXCEPT :
- single_type_dispatcher_base(typeid(visible_type< T >), callback_base((void*)boost::addressof(visitor), &callback_base::trampoline< VisitorT, T >))
+ single_type_dispatcher_base(typeindex::type_id< T >(), callback_base((void*)boost::addressof(visitor), &callback_base::trampoline< VisitorT, T >))
{
}
diff --git a/boost/log/utility/type_dispatch/type_dispatcher.hpp b/boost/log/utility/type_dispatch/type_dispatcher.hpp
index 9ca52cd56c..c5265113fc 100644
--- a/boost/log/utility/type_dispatch/type_dispatcher.hpp
+++ b/boost/log/utility/type_dispatch/type_dispatcher.hpp
@@ -15,10 +15,9 @@
#ifndef BOOST_LOG_TYPE_DISPATCHER_HPP_INCLUDED_
#define BOOST_LOG_TYPE_DISPATCHER_HPP_INCLUDED_
-#include <typeinfo>
+#include <boost/type_index.hpp>
#include <boost/static_assert.hpp>
#include <boost/log/detail/config.hpp>
-#include <boost/log/detail/visible_type.hpp>
#include <boost/utility/explicit_operator_bool.hpp>
#include <boost/log/detail/header.hpp>
@@ -148,7 +147,7 @@ public:
protected:
//! Pointer to the callback acquisition method
- typedef callback_base (*get_callback_impl_type)(type_dispatcher*, std::type_info const&);
+ typedef callback_base (*get_callback_impl_type)(type_dispatcher*, typeindex::type_index);
private:
//! Pointer to the callback acquisition method
@@ -176,7 +175,7 @@ public:
template< typename T >
callback< T > get_callback()
{
- return callback< T >((this->m_get_callback_impl)(this, typeid(boost::log::aux::visible_type< T >)));
+ return callback< T >((this->m_get_callback_impl)(this, typeindex::type_id< T >()));
}
};
diff --git a/boost/log/utility/type_info_wrapper.hpp b/boost/log/utility/type_info_wrapper.hpp
index 9b1dc53201..81cd3aed69 100644
--- a/boost/log/utility/type_info_wrapper.hpp
+++ b/boost/log/utility/type_info_wrapper.hpp
@@ -26,6 +26,12 @@
#pragma once
#endif
+#if defined(__GNUC__)
+#pragma message "Boost.Log: This header is deprecated, use Boost.TypeIndex instead."
+#elif defined(_MSC_VER)
+#pragma message("Boost.Log: This header is deprecated, use Boost.TypeIndex instead.")
+#endif
+
namespace boost {
BOOST_LOG_OPEN_NAMESPACE
diff --git a/boost/make_default.hpp b/boost/make_default.hpp
new file mode 100644
index 0000000000..b8255feead
--- /dev/null
+++ b/boost/make_default.hpp
@@ -0,0 +1,40 @@
+/// @file
+// Copyright (c) 2009-2014 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_MAKE_DEFAULT_HPP
+#define BOOST_MAKE_DEFAULT_HPP
+
+namespace boost
+{
+ /// @details A considerable number of libraries require an instance of a class
+ /// provided (storage created and initialized). For example,
+ /// @code
+ /// Type result;
+ /// ...
+ /// istream >> result;
+ /// @endcode
+ /// In generic code that results in the Default Constructibility requirement imposed
+ /// on every type 'Type' to be used with the respective code. Inevitably, that requirement
+ /// a) either excludes all the classes that for various reasons do not meet that requirement or
+ /// b) imposes certain (not necessarily desirable) design/implementation onto respective classes.
+ ///
+ /// Deployment of boost::make_default() eliminates the Default Constructibility requirement with
+ /// @code
+ /// Type result = boost::make_default<Type>();
+ /// ...
+ /// istream >> result;
+ /// @endcode
+ /// Classes with no default constructor can now be included via a boost::make_default() specialization:
+ /// @code
+ /// namespace boost
+ /// {
+ /// template<> inline Type make_default<Type>() { return Type(parameters); }
+ /// }
+ /// @endcode
+
+ template<typename T> T make_default() { return T(); }
+}
+
+#endif // BOOST_MAKE_DEFAULT_HPP
diff --git a/boost/math/cstdfloat/cstdfloat_limits.hpp b/boost/math/cstdfloat/cstdfloat_limits.hpp
index c04062639a..ae9fbcbd15 100644
--- a/boost/math/cstdfloat/cstdfloat_limits.hpp
+++ b/boost/math/cstdfloat/cstdfloat_limits.hpp
@@ -40,7 +40,7 @@
static boost::math::cstdfloat::detail::float_internal128_t (max) () BOOST_NOEXCEPT { return BOOST_CSTDFLOAT_FLOAT128_MAX; }
static boost::math::cstdfloat::detail::float_internal128_t lowest() BOOST_NOEXCEPT { return -(max)(); }
BOOST_STATIC_CONSTEXPR int digits = 113;
- BOOST_STATIC_CONSTEXPR int digits10 = 34;
+ BOOST_STATIC_CONSTEXPR int digits10 = 33;
BOOST_STATIC_CONSTEXPR int max_digits10 = 36;
BOOST_STATIC_CONSTEXPR bool is_signed = true;
BOOST_STATIC_CONSTEXPR bool is_integer = false;
diff --git a/boost/math/special_functions/detail/bernoulli_details.hpp b/boost/math/special_functions/detail/bernoulli_details.hpp
index f2d3c655c8..525c1fccf4 100644
--- a/boost/math/special_functions/detail/bernoulli_details.hpp
+++ b/boost/math/special_functions/detail/bernoulli_details.hpp
@@ -625,7 +625,7 @@ private:
//
fixed_vector<T> bn, tn;
std::vector<T> m_intermediates;
- // The value at which we know overflow has already occured for the Bn:
+ // The value at which we know overflow has already occurred for the Bn:
std::size_t m_overflow_limit;
#if !defined(BOOST_HAS_THREADS)
#elif defined(BOOST_MATH_NO_ATOMIC_INT)
diff --git a/boost/math/tools/big_constant.hpp b/boost/math/tools/big_constant.hpp
index 3895638891..ff136337e1 100644
--- a/boost/math/tools/big_constant.hpp
+++ b/boost/math/tools/big_constant.hpp
@@ -27,7 +27,7 @@ template <>
struct numeric_traits<__float128>
{
static const int digits = 113;
- static const int digits10 = 34;
+ static const int digits10 = 33;
static const int max_exponent = 16384;
static const bool is_specialized = true;
};
diff --git a/boost/math/tools/config.hpp b/boost/math/tools/config.hpp
index 23cba0c9a9..e88f578db7 100644
--- a/boost/math/tools/config.hpp
+++ b/boost/math/tools/config.hpp
@@ -54,6 +54,14 @@
// Any use of __float128 in program startup code causes a segfault (tested JM 2015, Solaris 11).
# define BOOST_MATH_DISABLE_FLOAT128
#endif
+#ifdef __HAIKU__
+//
+// Not sure what's up with the math detection on Haiku, but linking fails with
+// float128 code enabled, and we don't have an implementation of __expl, so
+// disabling long double functions for now as well.
+# define BOOST_MATH_DISABLE_FLOAT128
+# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+#endif
#if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && ((LDBL_MANT_DIG == 106) || (__LDBL_MANT_DIG__ == 106)) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
//
// Darwin's rather strange "double double" is rather hard to
diff --git a/boost/move/core.hpp b/boost/move/core.hpp
index 408a7138fa..55486e6b45 100644
--- a/boost/move/core.hpp
+++ b/boost/move/core.hpp
@@ -53,6 +53,12 @@
#include <boost/move/detail/type_traits.hpp>
+ #if defined(BOOST_MOVE_ADDRESS_SANITIZER_ON)
+ #define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) reinterpret_cast<RV_TYPE>(ARG)
+ #else
+ #define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) static_cast<RV_TYPE>(ARG)
+ #endif
+
//Move emulation rv breaks standard aliasing rules so add workarounds for some compilers
#if defined(__GNUC__) && (__GNUC__ >= 4) && \
(\
@@ -101,6 +107,12 @@
: integral_constant<bool, ::boost::move_detail::is_rv_impl<T>::value >
{};
+ template <class T>
+ struct is_not_rv
+ {
+ static const bool value = !is_rv<T>::value;
+ };
+
} //namespace move_detail {
//////////////////////////////////////////////////////////////////////////////
@@ -113,6 +125,12 @@
: ::boost::move_detail::has_move_emulation_enabled_impl<T>
{};
+ template<class T>
+ struct has_move_emulation_disabled
+ {
+ static const bool value = !::boost::move_detail::has_move_emulation_enabled_impl<T>::value;
+ };
+
} //namespace boost {
#define BOOST_RV_REF(TYPE)\
@@ -135,6 +153,14 @@
>& \
//
+ #define BOOST_RV_REF_BEG_IF_CXX11 \
+ \
+ //
+
+ #define BOOST_RV_REF_END_IF_CXX11 \
+ \
+ //
+
#define BOOST_FWD_REF(TYPE)\
const TYPE & \
//
@@ -183,7 +209,7 @@
, ::boost::rv<T>&>::type
move_return(T& x) BOOST_NOEXCEPT
{
- return *static_cast< ::boost::rv<T>* >(::boost::move_detail::addressof(x));
+ return *BOOST_MOVE_TO_RV_CAST(::boost::rv<T>*, ::boost::move_detail::addressof(x));
}
template <class Ret, class T>
@@ -216,9 +242,9 @@
BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
public:\
operator ::boost::rv<TYPE>&() \
- { return *static_cast< ::boost::rv<TYPE>* >(this); }\
+ { return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this); }\
operator const ::boost::rv<TYPE>&() const \
- { return *static_cast<const ::boost::rv<TYPE>* >(this); }\
+ { return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this); }\
private:\
//
@@ -231,21 +257,21 @@
#define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
public:\
TYPE& operator=(TYPE &t)\
- { this->operator=(static_cast<const ::boost::rv<TYPE> &>(const_cast<const TYPE &>(t))); return *this;}\
+ { this->operator=(const_cast<const TYPE &>(t)); return *this;}\
public:\
operator ::boost::rv<TYPE>&() \
- { return *static_cast< ::boost::rv<TYPE>* >(this); }\
+ { return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this); }\
operator const ::boost::rv<TYPE>&() const \
- { return *static_cast<const ::boost::rv<TYPE>* >(this); }\
+ { return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this); }\
private:\
//
#define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
public:\
operator ::boost::rv<TYPE>&() \
- { return *static_cast< ::boost::rv<TYPE>* >(this); }\
+ { return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this); }\
operator const ::boost::rv<TYPE>&() const \
- { return *static_cast<const ::boost::rv<TYPE>* >(this); }\
+ { return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this); }\
private:\
//
@@ -295,6 +321,12 @@
static const bool value = false;
};
+ template<class T>
+ struct has_move_emulation_disabled
+ {
+ static const bool value = true;
+ };
+
} //namespace boost{
//!This macro is used to achieve portable syntax in move
@@ -322,6 +354,19 @@
//!and ended with BOOST_RV_REF_END
#define BOOST_RV_REF_END\
&& \
+ //
+
+ //!This macro expands to BOOST_RV_REF_BEG if BOOST_NO_CXX11_RVALUE_REFERENCES
+ //!is not defined, empty otherwise
+ #define BOOST_RV_REF_BEG_IF_CXX11 \
+ BOOST_RV_REF_BEG \
+ //
+
+ //!This macro expands to BOOST_RV_REF_END if BOOST_NO_CXX11_RVALUE_REFERENCES
+ //!is not defined, empty otherwise
+ #define BOOST_RV_REF_END_IF_CXX11 \
+ BOOST_RV_REF_END \
+ //
//!This macro is used to achieve portable syntax in copy
//!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE.
diff --git a/boost/move/detail/meta_utils.hpp b/boost/move/detail/meta_utils.hpp
index 682c89cfe8..a8a61dbd7b 100644
--- a/boost/move/detail/meta_utils.hpp
+++ b/boost/move/detail/meta_utils.hpp
@@ -34,11 +34,53 @@ template <class T> class rv;
namespace move_detail {
//////////////////////////////////////
+// is_different
+//////////////////////////////////////
+template<class T, class U>
+struct is_different
+{
+ static const bool value = !is_same<T, U>::value;
+};
+
+//////////////////////////////////////
+// apply
+//////////////////////////////////////
+template<class F, class Param>
+struct apply
+{
+ typedef typename F::template apply<Param>::type type;
+};
+
+//////////////////////////////////////
+// bool_
+//////////////////////////////////////
+
+template< bool C_ >
+struct bool_ : integral_constant<bool, C_>
+{
+ operator bool() const { return C_; }
+ bool operator()() const { return C_; }
+};
+
+typedef bool_<true> true_;
+typedef bool_<false> false_;
+
+//////////////////////////////////////
// nat
//////////////////////////////////////
struct nat{};
//////////////////////////////////////
+// yes_type/no_type
+//////////////////////////////////////
+typedef char yes_type;
+
+struct no_type
+{
+ char _[2];
+};
+
+//////////////////////////////////////
// natify
//////////////////////////////////////
template <class T> struct natify{};
@@ -86,10 +128,28 @@ struct remove_reference< const rv<T> &>
typedef T type;
};
-
#endif
//////////////////////////////////////
+// remove_pointer
+//////////////////////////////////////
+
+template< class T > struct remove_pointer { typedef T type; };
+template< class T > struct remove_pointer<T*> { typedef T type; };
+template< class T > struct remove_pointer<T* const> { typedef T type; };
+template< class T > struct remove_pointer<T* volatile> { typedef T type; };
+template< class T > struct remove_pointer<T* const volatile> { typedef T type; };
+
+//////////////////////////////////////
+// add_pointer
+//////////////////////////////////////
+template< class T >
+struct add_pointer
+{
+ typedef typename remove_reference<T>::type* type;
+};
+
+//////////////////////////////////////
// add_const
//////////////////////////////////////
template<class T>
@@ -151,6 +211,19 @@ struct is_lvalue_reference<T&>
static const bool value = true;
};
+
+//////////////////////////////////////
+// identity
+//////////////////////////////////////
+template <class T>
+struct identity
+{
+ typedef T type;
+ typedef typename add_const_lvalue_reference<T>::type reference;
+ reference operator()(reference t)
+ { return t; }
+};
+
//////////////////////////////////////
// is_class_or_union
//////////////////////////////////////
@@ -241,9 +314,128 @@ class is_convertible
#endif
+template<
+ bool C
+ , typename F1
+ , typename F2
+ >
+struct eval_if_c
+ : if_c<C,F1,F2>::type
+{};
+
+template<
+ typename C
+ , typename T1
+ , typename T2
+ >
+struct eval_if
+ : if_<C,T1,T2>::type
+{};
+
+template<class T, class U, class R = void>
+struct enable_if_convertible
+ : enable_if< is_convertible<T, U>, R>
+{};
+
+template<class T, class U, class R = void>
+struct disable_if_convertible
+ : disable_if< is_convertible<T, U>, R>
+{};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// and_
+//
+//////////////////////////////////////////////////////////////////////////////
+template<bool, class B = true_, class C = true_, class D = true_>
+struct and_impl
+ : and_impl<B::value, C, D>
+{};
+
+template<>
+struct and_impl<true, true_, true_, true_>
+{
+ static const bool value = true;
+};
+
+template<class B, class C, class D>
+struct and_impl<false, B, C, D>
+{
+ static const bool value = false;
+};
+
+template<class A, class B, class C = true_, class D = true_>
+struct and_
+ : and_impl<A::value, B, C, D>
+{};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// or_
+//
+//////////////////////////////////////////////////////////////////////////////
+template<bool, class B = false_, class C = false_, class D = false_>
+struct or_impl
+ : or_impl<B::value, C, D>
+{};
+
+template<>
+struct or_impl<false, false_, false_, false_>
+{
+ static const bool value = false;
+};
+
+template<class B, class C, class D>
+struct or_impl<true, B, C, D>
+{
+ static const bool value = true;
+};
+
+template<class A, class B, class C = false_, class D = false_>
+struct or_
+ : or_impl<A::value, B, C, D>
+{};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// not_
+//
+//////////////////////////////////////////////////////////////////////////////
+template<class T>
+struct not_
+{
+ static const bool value = !T::value;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// enable_if_and / disable_if_and / enable_if_or / disable_if_or
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template<class R, class A, class B, class C = true_, class D = true_>
+struct enable_if_and
+ : enable_if_c< and_<A, B, C, D>::value, R>
+{};
+
+template<class R, class A, class B, class C = true_, class D = true_>
+struct disable_if_and
+ : disable_if_c< and_<A, B, C, D>::value, R>
+{};
+
+template<class R, class A, class B, class C = false_, class D = false_>
+struct enable_if_or
+ : enable_if_c< or_<A, B, C, D>::value, R>
+{};
+
+template<class R, class A, class B, class C = false_, class D = false_>
+struct disable_if_or
+ : disable_if_c< or_<A, B, C, D>::value, R>
+{};
+
//////////////////////////////////////////////////////////////////////////////
//
-// has_move_emulation_enabled_impl
+// has_move_emulation_enabled_impl
//
//////////////////////////////////////////////////////////////////////////////
template<class T>
diff --git a/boost/move/detail/meta_utils_core.hpp b/boost/move/detail/meta_utils_core.hpp
index 283242bd03..4d715a060a 100644
--- a/boost/move/detail/meta_utils_core.hpp
+++ b/boost/move/detail/meta_utils_core.hpp
@@ -49,16 +49,15 @@ template<typename T1, typename T2, typename T3>
struct if_ : if_c<0 != T1::value, T2, T3>
{};
-//enable_if_
+//////////////////////////////////////
+// enable_if_c
+//////////////////////////////////////
template <bool B, class T = void>
struct enable_if_c
{
typedef T type;
};
-//////////////////////////////////////
-// enable_if_c
-//////////////////////////////////////
template <class T>
struct enable_if_c<false, T> {};
@@ -69,6 +68,14 @@ template <class Cond, class T = void>
struct enable_if : enable_if_c<Cond::value, T> {};
//////////////////////////////////////
+// disable_if_c
+//////////////////////////////////////
+template <bool B, class T = void>
+struct disable_if_c
+ : enable_if_c<!B, T>
+{};
+
+//////////////////////////////////////
// disable_if
//////////////////////////////////////
template <class Cond, class T = void>
@@ -83,19 +90,14 @@ struct integral_constant
static const T value = v;
typedef T value_type;
typedef integral_constant<T, v> type;
+
+ operator T() const { return value; }
+ T operator()() const { return value; }
};
typedef integral_constant<bool, true > true_type;
typedef integral_constant<bool, false > false_type;
-//////////////////////////////////////
-// identity
-//////////////////////////////////////
-template <class T>
-struct identity
-{
- typedef T type;
-};
//////////////////////////////////////
// is_same
diff --git a/boost/move/detail/move_helpers.hpp b/boost/move/detail/move_helpers.hpp
index f4fd26c154..e3b8883159 100644
--- a/boost/move/detail/move_helpers.hpp
+++ b/boost/move/detail/move_helpers.hpp
@@ -48,20 +48,24 @@
{ return FWD_FUNCTION(const_cast<const TYPE &>(x)); }\
\
template<class BOOST_MOVE_TEMPL_PARAM>\
- typename ::boost::move_detail::enable_if_c\
- < ::boost::move_detail::is_class_or_union<TYPE>::value &&\
- ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>::value &&\
- !::boost::has_move_emulation_enabled<BOOST_MOVE_TEMPL_PARAM>::value\
- , RETURN_VALUE >::type\
+ typename ::boost::move_detail::enable_if_and\
+ < RETURN_VALUE \
+ , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>\
+ , ::boost::move_detail::is_class_or_union<TYPE>\
+ , ::boost::has_move_emulation_disabled<BOOST_MOVE_TEMPL_PARAM>\
+ >::type\
PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\
{ return FWD_FUNCTION(u); }\
\
template<class BOOST_MOVE_TEMPL_PARAM>\
- typename ::boost::move_detail::enable_if_c\
- < (!::boost::move_detail::is_class_or_union<BOOST_MOVE_TEMPL_PARAM>::value || \
- !::boost::move_detail::is_rv<BOOST_MOVE_TEMPL_PARAM>::value) && \
- !::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>::value \
- , RETURN_VALUE >::type\
+ typename ::boost::move_detail::disable_if_or\
+ < RETURN_VALUE \
+ , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM> \
+ , ::boost::move_detail::and_ \
+ < ::boost::move_detail::is_rv<BOOST_MOVE_TEMPL_PARAM> \
+ , ::boost::move_detail::is_class_or_union<BOOST_MOVE_TEMPL_PARAM> \
+ > \
+ >::type\
PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\
{\
TYPE t(u);\
@@ -115,19 +119,21 @@
{ return FWD_FUNCTION(arg1, const_cast<const TYPE &>(x)); }\
\
template<class BOOST_MOVE_TEMPL_PARAM>\
- typename ::boost::move_detail::enable_if_c<\
- ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>::value &&\
- !::boost::has_move_emulation_enabled<BOOST_MOVE_TEMPL_PARAM>::value\
- , RETURN_VALUE >::type\
+ typename ::boost::move_detail::enable_if_and\
+ < RETURN_VALUE \
+ , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>\
+ , ::boost::has_move_emulation_disabled<BOOST_MOVE_TEMPL_PARAM>\
+ >::type\
PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\
{ return FWD_FUNCTION(arg1, u); }\
\
template<class BOOST_MOVE_TEMPL_PARAM>\
- typename ::boost::move_detail::enable_if_c<\
- !::boost::move_detail::is_rv<BOOST_MOVE_TEMPL_PARAM>::value && \
- !::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>::value && \
- !::boost::move_detail::is_convertible<BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO>::value \
- , RETURN_VALUE >::type\
+ typename ::boost::move_detail::disable_if_or\
+ < RETURN_VALUE \
+ , ::boost::move_detail::is_rv<BOOST_MOVE_TEMPL_PARAM>\
+ , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>\
+ , ::boost::move_detail::is_convertible<BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO>\
+ >::type\
PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\
{\
TYPE t(u);\
@@ -145,10 +151,11 @@
{ return FWD_FUNCTION(arg1, ::boost::move(x)); }\
\
template<class BOOST_MOVE_TEMPL_PARAM>\
- typename ::boost::move_detail::enable_if_c\
- < !::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>::value && \
- !::boost::move_detail::is_convertible<BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO>::value \
- , RETURN_VALUE >::type\
+ typename ::boost::move_detail::disable_if_or\
+ < RETURN_VALUE \
+ , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM> \
+ , ::boost::move_detail::is_convertible<BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO> \
+ >::type\
PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\
{\
TYPE t(u);\
diff --git a/boost/move/detail/type_traits.hpp b/boost/move/detail/type_traits.hpp
index ac0bbcd493..ab79fb128b 100644
--- a/boost/move/detail/type_traits.hpp
+++ b/boost/move/detail/type_traits.hpp
@@ -219,7 +219,10 @@
#endif
#ifdef BOOST_MOVE_IS_POD
- #define BOOST_MOVE_IS_POD_IMPL(T) BOOST_MOVE_IS_POD(T)
+ //in some compilers the intrinsic is limited to class types so add scalar and void
+ #define BOOST_MOVE_IS_POD_IMPL(T) (::boost::move_detail::is_scalar<T>::value ||\
+ ::boost::move_detail::is_void<T>::value ||\
+ BOOST_MOVE_IS_POD(T))
#else
#define BOOST_MOVE_IS_POD_IMPL(T) \
(::boost::move_detail::is_scalar<T>::value || ::boost::move_detail::is_void<T>::value)
@@ -341,23 +344,28 @@ struct is_pointer<T*>
{ static const bool value = true; };
//////////////////////////
-// add_reference
+// is_const
//////////////////////////
-template <typename T>
-struct add_reference
-{ typedef T& type; };
+template<class T>
+struct is_const
+{ static const bool value = false; };
template<class T>
-struct add_reference<T&>
-{ typedef T& type; };
+struct is_const<const T>
+{ static const bool value = true; };
-template<>
-struct add_reference<void>
-{ typedef nat &type; };
+//////////////////////////
+// unvoid_ref
+//////////////////////////
+template <typename T> struct unvoid_ref : add_lvalue_reference<T>{};
+template <> struct unvoid_ref<void> { typedef unvoid_ref & type; };
+template <> struct unvoid_ref<const void> { typedef unvoid_ref & type; };
+template <> struct unvoid_ref<volatile void> { typedef unvoid_ref & type; };
+template <> struct unvoid_ref<const volatile void> { typedef unvoid_ref & type; };
-template<>
-struct add_reference<const void>
-{ typedef const nat &type; };
+template <typename T>
+struct add_reference : add_lvalue_reference<T>
+{};
//////////////////////////
// add_const_reference
@@ -371,6 +379,14 @@ struct add_const_reference<T&>
{ typedef T& type; };
//////////////////////////
+// add_const_if_c
+//////////////////////////
+template<class T, bool Add>
+struct add_const_if_c
+ : if_c<Add, typename add_const<T>::type, T>
+{};
+
+//////////////////////////
// remove_const
//////////////////////////
template<class T>
@@ -700,16 +716,31 @@ template <class T>
struct is_empty
{ static const bool value = BOOST_MOVE_IS_EMPTY_IMPL(T); };
+
+template<class T>
+struct has_boost_move_no_copy_constructor_or_assign_type
+{
+ template <class U>
+ static yes_type test(typename U::boost_move_no_copy_constructor_or_assign*);
+
+ template <class U>
+ static no_type test(...);
+
+ static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
+};
+
//////////////////////////////////////
// is_copy_constructible
//////////////////////////////////////
+#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \
+ && !defined(BOOST_INTEL_CXX_VERSION) && \
+ !(defined(BOOST_MSVC) && _MSC_VER == 1800)
+#define BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE
+#endif
+
template<class T>
struct is_copy_constructible
{
- typedef char yes_type;
- struct no_type { char dummy[2]; };
- template<class U> static typename add_reference<U>::type source();
-
// Intel compiler has problems with SFINAE for copy constructors and deleted functions:
//
// error: function *function_name* cannot be referenced -- it is a deleted function
@@ -717,8 +748,8 @@ struct is_copy_constructible
// ^
// MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See:
// https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken
- #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_INTEL_CXX_VERSION) &&\
- !(defined(BOOST_MSVC) && _MSC_VER == 1800)
+ #if defined(BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE)
+ template<class U> static typename add_reference<U>::type source();
static no_type test(...);
#ifdef BOOST_NO_CXX11_DECLTYPE
template <class U>
@@ -727,13 +758,45 @@ struct is_copy_constructible
template <class U>
static yes_type test(U&, decltype(U(source<U>()))* = 0);
#endif
+ static const bool value = sizeof(test(source<T>())) == sizeof(yes_type);
#else
- template <class U>
- static no_type test(U&, typename U::boost_move_no_copy_constructor_or_assign* = 0);
- static yes_type test(...);
+ static const bool value = !has_boost_move_no_copy_constructor_or_assign_type<T>::value;
#endif
+};
+
+
+//////////////////////////////////////
+// is_copy_assignable
+//////////////////////////////////////
+#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \
+ && !defined(BOOST_INTEL_CXX_VERSION) && \
+ !(defined(BOOST_MSVC) && _MSC_VER == 1800)
+#define BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE
+#endif
+
+template <class T>
+struct is_copy_assignable
+{
+// Intel compiler has problems with SFINAE for copy constructors and deleted functions:
+//
+// error: function *function_name* cannot be referenced -- it is a deleted function
+// static boost::type_traits::yes_type test(T1&, decltype(T1(boost::declval<T1&>()))* = 0);
+// ^
+//
+// MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See:
+// https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken
+#if defined(BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE)
+ typedef char yes_type;
+ struct no_type { char dummy[2]; };
+
+ template <class U> static typename add_reference<U>::type source();
+ template <class U> static decltype(source<U&>() = source<const U&>(), yes_type() ) test(int);
+ template <class> static no_type test(...);
- static const bool value = sizeof(test(source<T>())) == sizeof(yes_type);
+ static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
+#else
+ static const bool value = !has_boost_move_no_copy_constructor_or_assign_type<T>::value;
+#endif
};
//////////////////////////////////////
@@ -755,7 +818,13 @@ struct is_trivially_default_constructible
//////////////////////////////////////
template<class T>
struct is_trivially_copy_constructible
-{ static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T); };
+{
+ //In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with
+ //deleted copy constructors so make sure the type is copy constructible.
+ static const bool value = ::boost::move_detail::is_pod<T>::value ||
+ ( ::boost::move_detail::is_copy_constructible<T>::value &&
+ BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) );
+};
//////////////////////////////////////
// is_trivially_move_constructible
@@ -769,7 +838,13 @@ struct is_trivially_move_constructible
//////////////////////////////////////
template<class T>
struct is_trivially_copy_assignable
-{ static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T); };
+{
+ //In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with
+ //deleted copy constructors so make sure the type is copy constructible.
+ static const bool value = ::boost::move_detail::is_pod<T>::value ||
+ ( ::boost::move_detail::is_copy_assignable<T>::value &&
+ BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) );
+};
//////////////////////////////////////
// is_trivially_move_assignable
diff --git a/boost/move/detail/workaround.hpp b/boost/move/detail/workaround.hpp
index 67ba161345..b3f81b117f 100644
--- a/boost/move/detail/workaround.hpp
+++ b/boost/move/detail/workaround.hpp
@@ -23,6 +23,16 @@
#define BOOST_MOVE_PERFECT_FORWARDING
#endif
+#if defined(__has_feature)
+ #define BOOST_MOVE_HAS_FEATURE __has_feature
+#else
+ #define BOOST_MOVE_HAS_FEATURE(x) 0
+#endif
+
+#if BOOST_MOVE_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+ #define BOOST_MOVE_ADDRESS_SANITIZER_ON
+#endif
+
//Macros for documentation purposes. For code, expands to the argument
#define BOOST_MOVE_IMPDEF(TYPE) TYPE
#define BOOST_MOVE_SEEDOC(TYPE) TYPE
diff --git a/boost/move/unique_ptr.hpp b/boost/move/unique_ptr.hpp
index cbac2aace1..bcf4faeea0 100644
--- a/boost/move/unique_ptr.hpp
+++ b/boost/move/unique_ptr.hpp
@@ -105,8 +105,8 @@ struct unique_ptr_data
{}
template <class U>
- unique_ptr_data(P p, BOOST_FWD_REF(U) d) BOOST_NOEXCEPT
- : m_p(p), d(::boost::forward<U>(d))
+ unique_ptr_data(P p, BOOST_FWD_REF(U) d1) BOOST_NOEXCEPT
+ : m_p(p), d(::boost::forward<U>(d1))
{}
del_ref deleter() { return d; }
@@ -219,9 +219,14 @@ struct enable_up_ptr
template<class T, class D, class U, class E>
struct unique_moveconvert_assignable
{
- static const bool value = (bmupmu::extent<T>::value == bmupmu::extent<U>::value) && is_unique_ptr_convertible
- < bmupmu::is_array<T>::value
- , typename bmupmu::pointer_type<U, E>::type, typename bmupmu::pointer_type<T, D>::type>::value;
+ static const bool t_is_array = bmupmu::is_array<T>::value;
+ static const bool value =
+ t_is_array == bmupmu::is_array<U>::value &&
+ bmupmu::extent<T>::value == bmupmu::extent<U>::value &&
+ is_unique_ptr_convertible
+ < t_is_array
+ , typename bmupmu::pointer_type<U, E>::type, typename bmupmu::pointer_type<T, D>::type
+ >::value;
};
template<class T, class D, class U, class E, std::size_t N>
@@ -290,8 +295,9 @@ struct unique_deleter_is_initializable<D, E, false>
template<class T, class D, class U, class E, class Type = bmupmu::nat>
struct enable_up_moveconv_constr
- : bmupmu::enable_if_c<unique_moveconvert_assignable<T, D, U, E>::value &&
- unique_deleter_is_initializable<D, E>::value, Type>
+ : bmupmu::enable_if_c
+ < unique_moveconvert_assignable<T, D, U, E>::value && unique_deleter_is_initializable<D, E>::value
+ , Type>
{};
} //namespace move_upd {
@@ -538,7 +544,7 @@ class unique_ptr
//! <b>Postconditions</b>: <tt>get()</tt> yields the value <tt>u.get()</tt> yielded before the construction. <tt>get_deleter()</tt>
//! returns a reference to the stored deleter that was constructed from <tt>u.get_deleter()</tt>.
template <class U, class E>
- unique_ptr( BOOST_RV_REF_BEG unique_ptr<U, E> BOOST_RV_REF_END u
+ unique_ptr( BOOST_RV_REF_BEG_IF_CXX11 unique_ptr<U, E> BOOST_RV_REF_END_IF_CXX11 u
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_moveconv_constr<T BOOST_MOVE_I D BOOST_MOVE_I U BOOST_MOVE_I E>::type* =0)
) BOOST_NOEXCEPT
: m_data(u.release(), ::boost::move_if_not_lvalue_reference<E>(u.get_deleter()))
diff --git a/boost/move/utility_core.hpp b/boost/move/utility_core.hpp
index 7b88bc142a..89e4f07f8b 100644
--- a/boost/move/utility_core.hpp
+++ b/boost/move/utility_core.hpp
@@ -47,24 +47,33 @@
//////////////////////////////////////////////////////////////////////////////
template <class T>
- inline typename ::boost::move_detail::enable_if_c
- < enable_move_utility_emulation<T>::value && !has_move_emulation_enabled<T>::value, T&>::type
+ inline typename ::boost::move_detail::enable_if_and
+ < T &
+ , enable_move_utility_emulation<T>
+ , has_move_emulation_disabled<T>
+ >::type
move(T& x) BOOST_NOEXCEPT
{
return x;
}
template <class T>
- inline typename ::boost::move_detail::enable_if_c
- < enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value, rv<T>&>::type
+ inline typename ::boost::move_detail::enable_if_and
+ < rv<T>&
+ , enable_move_utility_emulation<T>
+ , has_move_emulation_enabled<T>
+ >::type
move(T& x) BOOST_NOEXCEPT
{
- return *static_cast<rv<T>* >(::boost::move_detail::addressof(x));
+ return *BOOST_MOVE_TO_RV_CAST(::boost::rv<T>*, ::boost::move_detail::addressof(x) );
}
template <class T>
- inline typename ::boost::move_detail::enable_if_c
- < enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value, rv<T>&>::type
+ inline typename ::boost::move_detail::enable_if_and
+ < rv<T>&
+ , enable_move_utility_emulation<T>
+ , has_move_emulation_enabled<T>
+ >::type
move(rv<T>& x) BOOST_NOEXCEPT
{
return x;
@@ -77,17 +86,23 @@
//////////////////////////////////////////////////////////////////////////////
template <class T>
- inline typename ::boost::move_detail::enable_if_c
- < enable_move_utility_emulation<T>::value && ::boost::move_detail::is_rv<T>::value, T &>::type
+ inline typename ::boost::move_detail::enable_if_and
+ < T &
+ , enable_move_utility_emulation<T>
+ , ::boost::move_detail::is_rv<T>
+ >::type
forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
{
return const_cast<T&>(x);
}
template <class T>
- inline typename ::boost::move_detail::enable_if_c
- < enable_move_utility_emulation<T>::value && !::boost::move_detail::is_rv<T>::value, const T &>::type
- forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
+ inline typename ::boost::move_detail::enable_if_and
+ < const T &
+ , enable_move_utility_emulation<T>
+ , ::boost::move_detail::is_not_rv<T>
+ >::type
+ forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
{
return x;
}
@@ -99,22 +114,25 @@
//////////////////////////////////////////////////////////////////////////////
template <class T>
- inline typename ::boost::move_detail::enable_if_c
- < enable_move_utility_emulation<T>::value &&
- ::boost::move_detail::is_rv<T>::value
- , T &>::type
+ inline typename ::boost::move_detail::enable_if_and
+ < T &
+ , enable_move_utility_emulation<T>
+ , ::boost::move_detail::is_rv<T>
+ >::type
move_if_not_lvalue_reference(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
{
return const_cast<T&>(x);
}
template <class T>
- inline typename ::boost::move_detail::enable_if_c
- < enable_move_utility_emulation<T>::value &&
- !::boost::move_detail::is_rv<T>::value &&
- (::boost::move_detail::is_lvalue_reference<T>::value ||
- !has_move_emulation_enabled<T>::value)
- , typename ::boost::move_detail::add_lvalue_reference<T>::type
+ inline typename ::boost::move_detail::enable_if_and
+ < typename ::boost::move_detail::add_lvalue_reference<T>::type
+ , enable_move_utility_emulation<T>
+ , ::boost::move_detail::is_not_rv<T>
+ , ::boost::move_detail::or_
+ < ::boost::move_detail::is_lvalue_reference<T>
+ , has_move_emulation_disabled<T>
+ >
>::type
move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type &x) BOOST_NOEXCEPT
{
@@ -122,12 +140,14 @@
}
template <class T>
- inline typename ::boost::move_detail::enable_if_c
- < enable_move_utility_emulation<T>::value &&
- !::boost::move_detail::is_rv<T>::value &&
- (!::boost::move_detail::is_lvalue_reference<T>::value &&
- has_move_emulation_enabled<T>::value)
- , rv<T>&
+ inline typename ::boost::move_detail::enable_if_and
+ < rv<T>&
+ , enable_move_utility_emulation<T>
+ , ::boost::move_detail::is_not_rv<T>
+ , ::boost::move_detail::and_
+ < ::boost::move_detail::not_< ::boost::move_detail::is_lvalue_reference<T> >
+ , has_move_emulation_enabled<T>
+ >
>::type
move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type &x) BOOST_NOEXCEPT
{
diff --git a/boost/mpi/collectives.hpp b/boost/mpi/collectives.hpp
index e74fd72bb0..72c4294606 100644
--- a/boost/mpi/collectives.hpp
+++ b/boost/mpi/collectives.hpp
@@ -333,6 +333,75 @@ template<typename T>
void gather(const communicator& comm, const T* in_values, int n, int root);
/**
+ * @brief Similar to boost::mpi::gather with the difference that the number
+ * of values to be send by non-root processes can vary.
+ *
+ * @param comm The communicator over which the gather will occur.
+ *
+ * @param in_values The array of values to be transmitted by each process.
+ *
+ * @param in_size For each non-root process this specifies the size
+ * of @p in_values.
+ *
+ * @param out_values A pointer to storage that will be populated with
+ * the values from each process. For non-root processes, this parameter
+ * may be omitted. If it is still provided, however, it will be unchanged.
+ *
+ * @param sizes A vector containing the number of elements each non-root
+ * process will send.
+ *
+ * @param displs A vector such that the i-th entry specifies the
+ * displacement (relative to @p out_values) from which to take the ingoing
+ * data at the @p root process. Overloaded versions for which @p displs is
+ * omitted assume that the data is to be placed contiguously at the root process.
+ *
+ * @param root The process ID number that will collect the
+ * values. This value must be the same on all processes.
+ */
+template<typename T>
+void
+gatherv(const communicator& comm, const std::vector<T>& in_values,
+ T* out_values, const std::vector<int>& sizes, const std::vector<int>& displs,
+ int root);
+
+/**
+ * \overload
+ */
+template<typename T>
+void
+gatherv(const communicator& comm, const T* in_values, int in_size,
+ T* out_values, const std::vector<int>& sizes, const std::vector<int>& displs,
+ int root);
+
+/**
+ * \overload
+ */
+template<typename T>
+void gatherv(const communicator& comm, const std::vector<T>& in_values, int root);
+
+/**
+ * \overload
+ */
+template<typename T>
+void gatherv(const communicator& comm, const T* in_values, int in_size, int root);
+
+/**
+ * \overload
+ */
+template<typename T>
+void
+gatherv(const communicator& comm, const T* in_values, int in_size,
+ T* out_values, const std::vector<int>& sizes, int root);
+
+/**
+ * \overload
+ */
+template<typename T>
+void
+gatherv(const communicator& comm, const std::vector<T>& in_values,
+ T* out_values, const std::vector<int>& sizes, int root);
+
+/**
* @brief Scatter the values stored at the root to all processes
* within the communicator.
*
@@ -347,7 +416,7 @@ void gather(const communicator& comm, const T* in_values, int n, int root);
* When the type @c T has an associated MPI data type, this routine
* invokes @c MPI_Scatter to scatter the values.
*
- * @param comm The communicator over which the gather will occur.
+ * @param comm The communicator over which the scatter will occur.
*
* @param in_values A vector or pointer to storage that will contain
* the values to send to each process, indexed by the process rank.
@@ -402,6 +471,71 @@ template<typename T>
void scatter(const communicator& comm, T* out_values, int n, int root);
/**
+ * @brief Similar to boost::mpi::scatter with the difference that the number
+ * of values stored at the root process does not need to be a multiple of
+ * the communicator's size.
+ *
+ * @param comm The communicator over which the scatter will occur.
+ *
+ * @param in_values A vector or pointer to storage that will contain
+ * the values to send to each process, indexed by the process rank.
+ * For non-root processes, this parameter may be omitted. If it is
+ * still provided, however, it will be unchanged.
+ *
+ * @param sizes A vector containing the number of elements each non-root
+ * process will receive.
+ *
+ * @param displs A vector such that the i-th entry specifies the
+ * displacement (relative to @p in_values) from which to take the outgoing
+ * data to process i. Overloaded versions for which @p displs is omitted
+ * assume that the data is contiguous at the @p root process.
+ *
+ * @param out_values The array of values received by each process.
+ *
+ * @param out_size For each non-root process this will contain the size
+ * of @p out_values.
+ *
+ * @param root The process ID number that will scatter the
+ * values. This value must be the same on all processes.
+ */
+template<typename T>
+void
+scatterv(const communicator& comm, const std::vector<T>& in_values,
+ const std::vector<int>& sizes, const std::vector<int>& displs,
+ T* out_values, int out_size, int root);
+
+/**
+ * \overload
+ */
+template<typename T>
+void
+scatterv(const communicator& comm, const T* in_values,
+ const std::vector<int>& sizes, const std::vector<int>& displs,
+ T* out_values, int out_size, int root);
+
+/**
+ * \overload
+ */
+template<typename T>
+void scatterv(const communicator& comm, T* out_values, int out_size, int root);
+
+/**
+ * \overload
+ */
+template<typename T>
+void
+scatterv(const communicator& comm, const T* in_values,
+ const std::vector<int>& sizes, T* out_values, int root);
+
+/**
+ * \overload
+ */
+template<typename T>
+void
+scatterv(const communicator& comm, const std::vector<T>& in_values,
+ const std::vector<int>& sizes, T* out_values, int root);
+
+/**
* @brief Combine the values stored by each process into a single
* value at the root.
*
@@ -554,7 +688,9 @@ scan(const communicator& comm, const T* in_values, int n, T* out_values, Op op);
# include <boost/mpi/collectives/all_to_all.hpp>
# include <boost/mpi/collectives/broadcast.hpp>
# include <boost/mpi/collectives/gather.hpp>
+# include <boost/mpi/collectives/gatherv.hpp>
# include <boost/mpi/collectives/scatter.hpp>
+# include <boost/mpi/collectives/scatterv.hpp>
# include <boost/mpi/collectives/reduce.hpp>
# include <boost/mpi/collectives/scan.hpp>
#endif
diff --git a/boost/mpi/collectives/gatherv.hpp b/boost/mpi/collectives/gatherv.hpp
new file mode 100644
index 0000000000..eb5f9c16dc
--- /dev/null
+++ b/boost/mpi/collectives/gatherv.hpp
@@ -0,0 +1,164 @@
+// Copyright (C) 2011 Júlio Hoffimann.
+
+// 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)
+
+// Message Passing Interface 1.1 -- Section 4.5. Gatherv
+#ifndef BOOST_MPI_GATHERV_HPP
+#define BOOST_MPI_GATHERV_HPP
+
+#include <boost/mpi/exception.hpp>
+#include <boost/mpi/datatype.hpp>
+#include <vector>
+#include <boost/mpi/packed_oarchive.hpp>
+#include <boost/mpi/packed_iarchive.hpp>
+#include <boost/mpi/detail/point_to_point.hpp>
+#include <boost/mpi/communicator.hpp>
+#include <boost/mpi/environment.hpp>
+#include <boost/assert.hpp>
+
+namespace boost { namespace mpi {
+
+namespace detail {
+ // We're gathering at the root for a type that has an associated MPI
+ // datatype, so we'll use MPI_Gatherv to do all of the work.
+ template<typename T>
+ void
+ gatherv_impl(const communicator& comm, const T* in_values, int in_size,
+ T* out_values, const int* sizes, const int* displs, int root, mpl::true_)
+ {
+ MPI_Datatype type = get_mpi_datatype<T>(*in_values);
+ BOOST_MPI_CHECK_RESULT(MPI_Gatherv,
+ (const_cast<T*>(in_values), in_size, type,
+ out_values, const_cast<int*>(sizes), const_cast<int*>(displs),
+ type, root, comm));
+ }
+
+ // We're gathering from a non-root for a type that has an associated MPI
+ // datatype, so we'll use MPI_Gatherv to do all of the work.
+ template<typename T>
+ void
+ gatherv_impl(const communicator& comm, const T* in_values, int in_size, int root,
+ mpl::true_)
+ {
+ MPI_Datatype type = get_mpi_datatype<T>(*in_values);
+ BOOST_MPI_CHECK_RESULT(MPI_Gatherv,
+ (const_cast<T*>(in_values), in_size, type,
+ 0, 0, 0, type, root, comm));
+ }
+
+ // We're gathering at the root for a type that does not have an
+ // associated MPI datatype, so we'll need to serialize
+ // it. Unfortunately, this means that we cannot use MPI_Gatherv, so
+ // we'll just have all of the non-root nodes send individual
+ // messages to the root.
+ template<typename T>
+ void
+ gatherv_impl(const communicator& comm, const T* in_values, int in_size,
+ T* out_values, const int* sizes, const int* displs, int root, mpl::false_)
+ {
+ int tag = environment::collectives_tag();
+ int nprocs = comm.size();
+
+ for (int src = 0; src < nprocs; ++src) {
+ if (src == root)
+ // Our own values will never be transmitted: just copy them.
+ std::copy(in_values, in_values + in_size, out_values + displs[src]);
+ else {
+// comm.recv(src, tag, out_values + displs[src], sizes[src]);
+ // Receive archive
+ packed_iarchive ia(comm);
+ MPI_Status status;
+ detail::packed_archive_recv(comm, src, tag, ia, status);
+ for (int i = 0; i < sizes[src]; ++i)
+ ia >> out_values[ displs[src] + i ];
+ }
+ }
+ }
+
+ // We're gathering at a non-root for a type that does not have an
+ // associated MPI datatype, so we'll need to serialize
+ // it. Unfortunately, this means that we cannot use MPI_Gatherv, so
+ // we'll just have all of the non-root nodes send individual
+ // messages to the root.
+ template<typename T>
+ void
+ gatherv_impl(const communicator& comm, const T* in_values, int in_size, int root,
+ mpl::false_)
+ {
+ int tag = environment::collectives_tag();
+// comm.send(root, tag, in_values, in_size);
+ packed_oarchive oa(comm);
+ for (int i = 0; i < in_size; ++i)
+ oa << in_values[i];
+ detail::packed_archive_send(comm, root, tag, oa);
+ }
+} // end namespace detail
+
+template<typename T>
+void
+gatherv(const communicator& comm, const T* in_values, int in_size,
+ T* out_values, const std::vector<int>& sizes, const std::vector<int>& displs,
+ int root)
+{
+ if (comm.rank() == root)
+ detail::gatherv_impl(comm, in_values, in_size,
+ out_values, &sizes[0], &displs[0],
+ root, is_mpi_datatype<T>());
+ else
+ detail::gatherv_impl(comm, in_values, in_size, root, is_mpi_datatype<T>());
+}
+
+template<typename T>
+void
+gatherv(const communicator& comm, const std::vector<T>& in_values,
+ T* out_values, const std::vector<int>& sizes, const std::vector<int>& displs,
+ int root)
+{
+ ::boost::mpi::gatherv(comm, &in_values[0], in_values.size(), out_values, sizes, displs, root);
+}
+
+template<typename T>
+void gatherv(const communicator& comm, const T* in_values, int in_size, int root)
+{
+ BOOST_ASSERT(comm.rank() != root);
+ detail::gatherv_impl(comm, in_values, in_size, root, is_mpi_datatype<T>());
+}
+
+template<typename T>
+void gatherv(const communicator& comm, const std::vector<T>& in_values, int root)
+{
+ BOOST_ASSERT(comm.rank() != root);
+ detail::gatherv_impl(comm, &in_values[0], in_values.size(), root, is_mpi_datatype<T>());
+}
+
+///////////////////////
+// common use versions
+///////////////////////
+template<typename T>
+void
+gatherv(const communicator& comm, const T* in_values, int in_size,
+ T* out_values, const std::vector<int>& sizes, int root)
+{
+ int nprocs = comm.size();
+
+ std::vector<int> displs( nprocs );
+ for (int rank = 0, aux = 0; rank < nprocs; ++rank) {
+ displs[rank] = aux;
+ aux += sizes[rank];
+ }
+ ::boost::mpi::gatherv(comm, in_values, in_size, out_values, sizes, displs, root);
+}
+
+template<typename T>
+void
+gatherv(const communicator& comm, const std::vector<T>& in_values,
+ T* out_values, const std::vector<int>& sizes, int root)
+{
+ ::boost::mpi::gatherv(comm, &in_values[0], in_values.size(), out_values, sizes, root);
+}
+
+} } // end namespace boost::mpi
+
+#endif // BOOST_MPI_GATHERV_HPP
diff --git a/boost/mpi/collectives/reduce.hpp b/boost/mpi/collectives/reduce.hpp
index 8fc2fe6eb6..4a94d71c12 100644
--- a/boost/mpi/collectives/reduce.hpp
+++ b/boost/mpi/collectives/reduce.hpp
@@ -45,7 +45,7 @@ namespace detail {
// datatype and operation, so we'll use MPI_Reduce directly.
template<typename T, typename Op>
void
- reduce_impl(const communicator& comm, const T* in_values, int n,
+ reduce_impl(const communicator& comm, const T* in_values, int n,
T* out_values, Op op, int root, mpl::true_ /*is_mpi_op*/,
mpl::true_/*is_mpi_datatype*/)
{
@@ -59,7 +59,7 @@ namespace detail {
// datatype and operation, so we'll use MPI_Reduce directly.
template<typename T, typename Op>
void
- reduce_impl(const communicator& comm, const T* in_values, int n, Op op,
+ reduce_impl(const communicator& comm, const T* in_values, int n, Op op,
int root, mpl::true_ /*is_mpi_op*/, mpl::true_/*is_mpi_datatype*/)
{
BOOST_MPI_CHECK_RESULT(MPI_Reduce,
@@ -77,7 +77,7 @@ namespace detail {
// directly, but we'll need to create an MPI_Op manually.
template<typename T, typename Op>
void
- reduce_impl(const communicator& comm, const T* in_values, int n,
+ reduce_impl(const communicator& comm, const T* in_values, int n,
T* out_values, Op op, int root, mpl::false_ /*is_mpi_op*/,
mpl::true_/*is_mpi_datatype*/)
{
@@ -93,7 +93,7 @@ namespace detail {
// directly, but we'll need to create an MPI_Op manually.
template<typename T, typename Op>
void
- reduce_impl(const communicator& comm, const T* in_values, int n, Op op,
+ reduce_impl(const communicator& comm, const T* in_values, int n, Op op,
int root, mpl::false_/*is_mpi_op*/, mpl::true_/*is_mpi_datatype*/)
{
user_op<Op, T> mpi_op(op);
@@ -111,7 +111,7 @@ namespace detail {
template<typename T, typename Op>
void
tree_reduce_impl(const communicator& comm, const T* in_values, int n,
- T* out_values, Op op, int root,
+ T* out_values, Op op, int root,
mpl::true_ /*is_commutative*/)
{
std::copy(in_values, in_values + n, out_values);
@@ -156,7 +156,7 @@ namespace detail {
int root, mpl::true_ /*is_commutative*/)
{
scoped_array<T> results(new T[n]);
- detail::tree_reduce_impl(comm, in_values, n, results.get(), op, root,
+ detail::tree_reduce_impl(comm, in_values, n, results.get(), op, root,
mpl::true_());
}
@@ -164,7 +164,7 @@ namespace detail {
template<typename T, typename Op>
void
tree_reduce_impl(const communicator& comm, const T* in_values, int n,
- T* out_values, Op op, int root,
+ T* out_values, Op op, int root,
mpl::false_ /*is_commutative*/)
{
int tag = environment::collectives_tag();
@@ -285,7 +285,7 @@ namespace detail {
// algorithm.
template<typename T, typename Op>
void
- reduce_impl(const communicator& comm, const T* in_values, int n,
+ reduce_impl(const communicator& comm, const T* in_values, int n,
T* out_values, Op op, int root, mpl::false_ /*is_mpi_op*/,
mpl::false_ /*is_mpi_datatype*/)
{
@@ -298,8 +298,8 @@ namespace detail {
// algorithm.
template<typename T, typename Op>
void
- reduce_impl(const communicator& comm, const T* in_values, int n, Op op,
- int root, mpl::false_ /*is_mpi_op*/,
+ reduce_impl(const communicator& comm, const T* in_values, int n, Op op,
+ int root, mpl::false_ /*is_mpi_op*/,
mpl::false_ /*is_mpi_datatype*/)
{
detail::tree_reduce_impl(comm, in_values, n, op, root,
@@ -309,7 +309,7 @@ namespace detail {
template<typename T, typename Op>
void
-reduce(const communicator& comm, const T* in_values, int n, T* out_values,
+reduce(const communicator& comm, const T* in_values, int n, T* out_values,
Op op, int root)
{
if (comm.rank() == root)
@@ -321,7 +321,7 @@ reduce(const communicator& comm, const T* in_values, int n, T* out_values,
}
template<typename T, typename Op>
-void
+void
reduce(const communicator& comm, const T* in_values, int n, Op op, int root)
{
BOOST_ASSERT(comm.rank() != root);
@@ -330,21 +330,21 @@ reduce(const communicator& comm, const T* in_values, int n, Op op, int root)
is_mpi_op<Op, T>(), is_mpi_datatype<T>());
}
-template<typename T, typename Op>
-void
-reduce(const communicator & comm, std::vector<T> const & in_values, Op op,
- int root)
+template<typename T, typename Op>
+void
+reduce(const communicator & comm, std::vector<T> const & in_values, Op op,
+ int root)
{
reduce(comm, &in_values.front(), in_values.size(), op, root);
}
-template<typename T, typename Op>
-void
-reduce(const communicator & comm, std::vector<T> const & in_values,
- std::vector<T> & out_values, Op op, int root)
+template<typename T, typename Op>
+void
+reduce(const communicator & comm, std::vector<T> const & in_values,
+ std::vector<T> & out_values, Op op, int root)
{
- out_values.resize(in_values.size());
- reduce(comm, &in_values.front(), in_values.size(), &out_values.front(), op,
+ if (root == comm.rank()) out_values.resize(in_values.size());
+ reduce(comm, &in_values.front(), in_values.size(), &out_values.front(), op,
root);
}
diff --git a/boost/mpi/collectives/scatterv.hpp b/boost/mpi/collectives/scatterv.hpp
new file mode 100644
index 0000000000..6e6f27002b
--- /dev/null
+++ b/boost/mpi/collectives/scatterv.hpp
@@ -0,0 +1,166 @@
+// Copyright (C) 2011 Júlio Hoffimann.
+
+// 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)
+
+// Message Passing Interface 1.1 -- Section 4.6. Scatterv
+#ifndef BOOST_MPI_SCATTERV_HPP
+#define BOOST_MPI_SCATTERV_HPP
+
+#include <boost/mpi/exception.hpp>
+#include <boost/mpi/datatype.hpp>
+#include <vector>
+#include <boost/mpi/packed_oarchive.hpp>
+#include <boost/mpi/packed_iarchive.hpp>
+#include <boost/mpi/detail/point_to_point.hpp>
+#include <boost/mpi/communicator.hpp>
+#include <boost/mpi/environment.hpp>
+#include <boost/assert.hpp>
+
+namespace boost { namespace mpi {
+
+namespace detail {
+ // We're scattering from the root for a type that has an associated MPI
+ // datatype, so we'll use MPI_Scatterv to do all of the work.
+ template<typename T>
+ void
+ scatterv_impl(const communicator& comm, const T* in_values, const int* sizes,
+ const int* displs, T* out_values, int out_size, int root, mpl::true_)
+ {
+ MPI_Datatype type = get_mpi_datatype<T>(*in_values);
+ BOOST_MPI_CHECK_RESULT(MPI_Scatterv,
+ (const_cast<T*>(in_values), const_cast<int*>(sizes),
+ const_cast<int*>(displs), type,
+ out_values, out_size, type, root, comm));
+ }
+
+ // We're scattering from a non-root for a type that has an associated MPI
+ // datatype, so we'll use MPI_Scatterv to do all of the work.
+ template<typename T>
+ void
+ scatterv_impl(const communicator& comm, T* out_values, int out_size, int root,
+ mpl::true_)
+ {
+ MPI_Datatype type = get_mpi_datatype<T>(*out_values);
+ BOOST_MPI_CHECK_RESULT(MPI_Scatterv,
+ (0, 0, 0, type,
+ out_values, out_size, type,
+ root, comm));
+ }
+
+ // We're scattering from the root for a type that does not have an
+ // associated MPI datatype, so we'll need to serialize
+ // it. Unfortunately, this means that we cannot use MPI_Scatterv, so
+ // we'll just have the root send individual messages to the other
+ // processes.
+ template<typename T>
+ void
+ scatterv_impl(const communicator& comm, const T* in_values, const int* sizes,
+ const int* displs, T* out_values, int out_size, int root, mpl::false_)
+ {
+ int tag = environment::collectives_tag();
+ int nprocs = comm.size();
+
+ for (int dest = 0; dest < nprocs; ++dest) {
+ if (dest == root) {
+ // Our own values will never be transmitted: just copy them.
+ std::copy(in_values + displs[dest],
+ in_values + displs[dest] + out_size, out_values);
+ } else {
+ // Send archive
+ packed_oarchive oa(comm);
+ for (int i = 0; i < sizes[dest]; ++i)
+ oa << in_values[ displs[dest] + i ];
+ detail::packed_archive_send(comm, dest, tag, oa);
+ }
+ }
+ }
+
+ // We're scattering to a non-root for a type that does not have an
+ // associated MPI datatype, so we'll need to de-serialize
+ // it. Unfortunately, this means that we cannot use MPI_Scatterv, so
+ // we'll just have all of the non-root nodes send individual
+ // messages to the root.
+ template<typename T>
+ void
+ scatterv_impl(const communicator& comm, T* out_values, int out_size, int root,
+ mpl::false_)
+ {
+ int tag = environment::collectives_tag();
+
+ packed_iarchive ia(comm);
+ MPI_Status status;
+ detail::packed_archive_recv(comm, root, tag, ia, status);
+ for (int i = 0; i < out_size; ++i)
+ ia >> out_values[i];
+ }
+} // end namespace detail
+
+template<typename T>
+void
+scatterv(const communicator& comm, const T* in_values,
+ const std::vector<int>& sizes, const std::vector<int>& displs,
+ T* out_values, int out_size, int root)
+{
+ int rank = comm.rank();
+ if (rank == root)
+ detail::scatterv_impl(comm, in_values, &sizes[0], &displs[0],
+ out_values, out_size, root, is_mpi_datatype<T>());
+ else
+ detail::scatterv_impl(comm, out_values, out_size, root,
+ is_mpi_datatype<T>());
+}
+
+template<typename T>
+void
+scatterv(const communicator& comm, const std::vector<T>& in_values,
+ const std::vector<int>& sizes, const std::vector<int>& displs,
+ T* out_values, int out_size, int root)
+{
+ if (comm.rank() == root)
+ ::boost::mpi::scatterv(comm, &in_values[0], sizes, displs,
+ out_values, out_size, root);
+ else
+ ::boost::mpi::scatterv(comm, static_cast<const T*>(0), sizes, displs,
+ out_values, out_size, root);
+}
+
+template<typename T>
+void scatterv(const communicator& comm, T* out_values, int out_size, int root)
+{
+ BOOST_ASSERT(comm.rank() != root);
+ detail::scatterv_impl(comm, out_values, out_size, root, is_mpi_datatype<T>());
+}
+
+///////////////////////
+// common use versions
+///////////////////////
+template<typename T>
+void
+scatterv(const communicator& comm, const T* in_values,
+ const std::vector<int>& sizes, T* out_values, int root)
+{
+ int nprocs = comm.size();
+ int myrank = comm.rank();
+
+ std::vector<int> displs(nprocs);
+ for (int rank = 0, aux = 0; rank < nprocs; ++rank) {
+ displs[rank] = aux;
+ aux += sizes[rank];
+ }
+ ::boost::mpi::scatterv(comm, in_values, sizes, displs, out_values,
+ sizes[myrank], root);
+}
+
+template<typename T>
+void
+scatterv(const communicator& comm, const std::vector<T>& in_values,
+ const std::vector<int>& sizes, T* out_values, int root)
+{
+ ::boost::mpi::scatterv(comm, &in_values[0], sizes, out_values, root);
+}
+
+} } // end namespace boost::mpi
+
+#endif // BOOST_MPI_SCATTERV_HPP
diff --git a/boost/mpi/communicator.hpp b/boost/mpi/communicator.hpp
index 65de3a47f2..fcef0866a9 100644
--- a/boost/mpi/communicator.hpp
+++ b/boost/mpi/communicator.hpp
@@ -19,6 +19,7 @@
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/mpi/datatype.hpp>
+#include <boost/mpi/nonblocking.hpp>
#include <utility>
#include <iterator>
#include <stdexcept> // for std::range_error
@@ -486,6 +487,12 @@ class BOOST_MPI_DECL communicator
*/
status recv(int source, int tag) const;
+ /** @brief Send a message to remote process nd receive another message
+ * from another process.
+ */
+ template<typename T>
+ status sendrecv(int dest, int stag, const T& sval, int src, int rtag, T& rval) const;
+
/**
* @brief Send a message to a remote process without blocking.
*
@@ -859,6 +866,25 @@ class BOOST_MPI_DECL communicator
void abort(int errcode) const;
protected:
+
+ /**
+ * INTERNAL ONLY
+ *
+ * Implementation of sendrecv for mpi type.
+ */
+ template<typename T>
+ status sendrecv_impl(int dest, int stag, const T& sval, int src, int rtag, T& rval,
+ mpl::true_) const;
+
+ /**
+ * INTERNAL ONLY
+ *
+ * Implementation of sendrecv for complex types, which must be passed as archives.
+ */
+ template<typename T>
+ status sendrecv_impl(int dest, int stag, const T& sval, int src, int rtag, T& rval,
+ mpl::false_) const;
+
/**
* INTERNAL ONLY
*
@@ -1250,6 +1276,44 @@ status communicator::recv(int source, int tag, T* values, int n) const
return this->array_recv_impl(source, tag, values, n, is_mpi_datatype<T>());
}
+
+template<typename T>
+status communicator::sendrecv_impl(int dest, int stag, const T& sval, int src, int rtag, T& rval,
+ mpl::true_) const
+{
+ status stat;
+ BOOST_MPI_CHECK_RESULT(MPI_Sendrecv,
+ (const_cast<T*>(&sval), 1,
+ get_mpi_datatype<T>(sval),
+ dest, stag,
+ &rval, 1,
+ get_mpi_datatype<T>(rval),
+ src, rtag,
+ MPI_Comm(*this), &stat.m_status));
+ return stat;
+}
+
+template<typename T>
+status communicator::sendrecv_impl(int dest, int stag, const T& sval, int src, int rtag, T& rval,
+ mpl::false_) const
+{
+ int const SEND = 0;
+ int const RECV = 1;
+ request srrequests[2];
+ srrequests[SEND] = this->isend_impl(dest, stag, sval, mpl::false_());
+ srrequests[RECV] = this->irecv_impl(src, rtag, rval, mpl::false_());
+ status srstatuses[2];
+ wait_all(srrequests, srrequests + 2, srstatuses);
+ return srstatuses[RECV];
+}
+
+template<typename T>
+status communicator::sendrecv(int dest, int stag, const T& sval, int src, int rtag, T& rval) const
+{
+ return this->sendrecv_impl(dest, stag, sval, src, rtag, rval, is_mpi_datatype<T>());
+}
+
+
// We're sending a type that has an associated MPI datatype, so we
// map directly to that datatype.
template<typename T>
diff --git a/boost/mpi/config.hpp b/boost/mpi/config.hpp
index acbdc78daa..ff91b17c35 100644
--- a/boost/mpi/config.hpp
+++ b/boost/mpi/config.hpp
@@ -20,10 +20,17 @@
#include <mpi.h>
#include <boost/config.hpp>
-/** @brief Define this macro to avoid expensice MPI_Pack/Unpack calls on
- * homogeneous machines.
-*/
-//#define BOOST_MPI_HOMOGENEOUS
+/** @brief Comment this macro is you are running in an heterogeneous environement.
+ *
+ * When this flags is enabled, we assume some simple, POD like, type can be
+ * transmited without paying the cost of portable serialization.
+ *
+ * Comment this if your platform is not homogeneous and that portable
+ * serialization/deserialization must be performed.
+ *
+ * It you do so, check that you MPI implementation supports thats kind of environement.
+ */
+#define BOOST_MPI_HOMOGENEOUS
// If this is an MPI-2 implementation, define configuration macros for
// the features we are interested in.
@@ -71,10 +78,20 @@
# define BOOST_MPI_CALLING_CONVENTION
#endif
+/** @brief Indicates that MPI_Bcast supports MPI_BOTTOM.
+ *
+ * Some implementations have a broken MPI_Bcast wrt to MPI_BOTTOM.
+ * BullX MPI and LAM seems to be among them, at least for some versions.
+ * The `broacast_test.cpp` test `test_skeleton_and_content` can be used to
+ * detect that.
+ */
+#define BOOST_MPI_BCAST_BOTTOM_WORKS_FINE
+
#if defined(LAM_MPI)
// Configuration for LAM/MPI
# define BOOST_MPI_HAS_MEMORY_ALLOCATION
# define BOOST_MPI_HAS_NOARG_INITIALIZATION
+# undef BOOST_MPI_BCAST_BOTTOM_WORKS_FINE
#elif defined(MPICH_NAME)
// Configuration for MPICH
#endif
diff --git a/boost/mpi/datatype.hpp b/boost/mpi/datatype.hpp
index 7fa7e1c3d0..c26dfdfc3b 100644
--- a/boost/mpi/datatype.hpp
+++ b/boost/mpi/datatype.hpp
@@ -36,7 +36,7 @@ namespace boost { namespace mpi {
* @brief Type trait that determines if there exists a built-in
* integer MPI data type for a given C++ type.
*
- * This ytpe trait determines when there is a direct mapping from a
+ * This type trait determines when there is a direct mapping from a
* C++ type to an MPI data type that is classified as an integer data
* type. See @c is_mpi_builtin_datatype for general information about
* built-in MPI data types.
@@ -49,7 +49,7 @@ struct is_mpi_integer_datatype
* @brief Type trait that determines if there exists a built-in
* floating point MPI data type for a given C++ type.
*
- * This ytpe trait determines when there is a direct mapping from a
+ * This type trait determines when there is a direct mapping from a
* C++ type to an MPI data type that is classified as a floating
* point data type. See @c is_mpi_builtin_datatype for general
* information about built-in MPI data types.
@@ -62,7 +62,7 @@ struct is_mpi_floating_point_datatype
* @brief Type trait that determines if there exists a built-in
* logical MPI data type for a given C++ type.
*
- * This ytpe trait determines when there is a direct mapping from a
+ * This type trait determines when there is a direct mapping from a
* C++ type to an MPI data type that is classified as an logical data
* type. See @c is_mpi_builtin_datatype for general information about
* built-in MPI data types.
@@ -75,7 +75,7 @@ struct is_mpi_logical_datatype
* @brief Type trait that determines if there exists a built-in
* complex MPI data type for a given C++ type.
*
- * This ytpe trait determines when there is a direct mapping from a
+ * This type trait determines when there is a direct mapping from a
* C++ type to an MPI data type that is classified as an complex data
* type. See @c is_mpi_builtin_datatype for general information about
* built-in MPI data types.
@@ -88,7 +88,7 @@ struct is_mpi_complex_datatype
* @brief Type trait that determines if there exists a built-in
* byte MPI data type for a given C++ type.
*
- * This ytpe trait determines when there is a direct mapping from a
+ * This type trait determines when there is a direct mapping from a
* C++ type to an MPI data type that is classified as an byte data
* type. See @c is_mpi_builtin_datatype for general information about
* built-in MPI data types.
@@ -198,7 +198,7 @@ get_mpi_datatype< CppType >(const CppType&) { return MPIType; } \
\
template<> \
struct BOOST_JOIN(is_mpi_,BOOST_JOIN(Kind,_datatype))< CppType > \
-: boost::mpl::bool_<true> \
+: boost::mpl::true_ \
{}
/// INTERNAL ONLY
diff --git a/boost/mpi/detail/forward_skeleton_iarchive.hpp b/boost/mpi/detail/forward_skeleton_iarchive.hpp
index 6e1181981d..c4b9e0f2a8 100644
--- a/boost/mpi/detail/forward_skeleton_iarchive.hpp
+++ b/boost/mpi/detail/forward_skeleton_iarchive.hpp
@@ -9,8 +9,6 @@
#ifndef BOOST_MPI_DETAIL_FORWARD_SKELETON_IARCHIVE_HPP
#define BOOST_MPI_DETAIL_FORWARD_SKELETON_IARCHIVE_HPP
-#include <boost/serialization/pfto.hpp>
-
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/detail/iserializer.hpp>
#include <boost/archive/detail/interface_iarchive.hpp>
@@ -41,17 +39,14 @@ public:
protected:
#endif
- // intermediate level to support override of operators
- // for templates in the absence of partial function
- // template ordering
- template<class T>
- void load_override(T & t, BOOST_PFTO int)
- {
- archive::load(* this->This(), t);
- }
+ template<class T>
+ void load_override(T & t)
+ {
+ archive::load(* this->This(), t);
+ }
#define BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(T) \
- void load_override(T & t , int) \
+ void load_override(T & t) \
{ \
implementation_archive >> t; \
}
diff --git a/boost/mpi/detail/forward_skeleton_oarchive.hpp b/boost/mpi/detail/forward_skeleton_oarchive.hpp
index 6aab0538ab..4b0e057266 100644
--- a/boost/mpi/detail/forward_skeleton_oarchive.hpp
+++ b/boost/mpi/detail/forward_skeleton_oarchive.hpp
@@ -9,8 +9,6 @@
#ifndef BOOST_MPI_DETAIL_FORWARD_SKELETON_OARCHIVE_HPP
#define BOOST_MPI_DETAIL_FORWARD_SKELETON_OARCHIVE_HPP
-#include <boost/serialization/pfto.hpp>
-
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/detail/oserializer.hpp>
#include <boost/archive/detail/interface_oarchive.hpp>
@@ -41,17 +39,14 @@ public:
protected:
#endif
- // intermediate level to support override of operators
- // for templates in the absence of partial function
- // template ordering
- template<class T>
- void save_override(T const& t, BOOST_PFTO int)
- {
- archive::save(* this->This(), t);
- }
+ template<class T>
+ void save_override(T const& t)
+ {
+ archive::save(* this->This(), t);
+ }
#define BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(T) \
- void save_override(T const & t , int) \
+ void save_override(T const & t) \
{ \
implementation_archive << t; \
}
diff --git a/boost/mpi/detail/ignore_skeleton_oarchive.hpp b/boost/mpi/detail/ignore_skeleton_oarchive.hpp
index 06a6bd59ca..29248f993d 100644
--- a/boost/mpi/detail/ignore_skeleton_oarchive.hpp
+++ b/boost/mpi/detail/ignore_skeleton_oarchive.hpp
@@ -9,8 +9,6 @@
#ifndef BOOST_MPI_DETAIL_IGNORE_SKELETON_OARCHIVE_HPP
#define BOOST_MPI_DETAIL_IGNORE_SKELETON_OARCHIVE_HPP
-#include <boost/serialization/pfto.hpp>
-
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/detail/common_oarchive.hpp>
#include <boost/archive/basic_archive.hpp>
@@ -38,18 +36,14 @@ public:
friend class archive::save_access;
protected:
#endif
-
- // intermediate level to support override of operators
- // for templates in the absence of partial function
- // template ordering
- template<class T>
- void save_override(T const& t, BOOST_PFTO int)
- {
- archive::save(* this->This(), t);
- }
+ template<class T>
+ void save_override(T const& t)
+ {
+ archive::save(* this->This(), t);
+ }
#define BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(T) \
- void save_override(T const & , int) \
+ void save_override(T const &) \
{}
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(archive::class_id_optional_type)
diff --git a/boost/mpi/detail/mpi_datatype_oarchive.hpp b/boost/mpi/detail/mpi_datatype_oarchive.hpp
index 7079f21a21..68f9abb6b5 100644
--- a/boost/mpi/detail/mpi_datatype_oarchive.hpp
+++ b/boost/mpi/detail/mpi_datatype_oarchive.hpp
@@ -41,12 +41,9 @@ public:
BOOST_MPL_ASSERT((is_mpi_datatype<T>));
*this << x; // serialize the object
}
-
- // intermediate level to support override of operators
- // for templates in the absence of partial function
- // template ordering
+
template<class T>
- void save_override(T const& t, BOOST_PFTO int)
+ void save_override(T const& t)
{
save_enum(t,boost::is_enum<T>());
}
@@ -54,7 +51,7 @@ public:
template<class T>
void save_enum(T const& t, mpl::false_)
{
- ignore_skeleton_oarchive<mpi_datatype_oarchive>::save_override(t, 0);
+ ignore_skeleton_oarchive<mpi_datatype_oarchive>::save_override(t);
}
template<class T>
diff --git a/boost/mpi/nonblocking.hpp b/boost/mpi/nonblocking.hpp
index a2d2e34313..1fc1ecd038 100644
--- a/boost/mpi/nonblocking.hpp
+++ b/boost/mpi/nonblocking.hpp
@@ -60,9 +60,11 @@ wait_any(ForwardIterator first, ForwardIterator last)
while (true) {
// Check if we have found a completed request. If so, return it.
if (current->m_requests[0] != MPI_REQUEST_NULL &&
- current->m_requests[1] != MPI_REQUEST_NULL)
+ (current->m_requests[1] != MPI_REQUEST_NULL ||
+ current->m_handler)) {
if (optional<status> result = current->test())
return std::make_pair(*result, current);
+ }
// Check if this request (and all others before it) are "trivial"
// requests, e.g., they can be represented with a single
@@ -138,10 +140,12 @@ template<typename ForwardIterator>
optional<std::pair<status, ForwardIterator> >
test_any(ForwardIterator first, ForwardIterator last)
{
- for (ForwardIterator current = first; first != last; ++first) {
+ while (first != last) {
// Check if we have found a completed request. If so, return it.
- if (optional<status> result = current->test())
- return std::make_pair(*result, current);
+ if (optional<status> result = first->test()) {
+ return std::make_pair(*result, first);
+ }
+ ++first;
}
// We found nothing
diff --git a/boost/mpi/packed_iarchive.hpp b/boost/mpi/packed_iarchive.hpp
index 23d6468c55..bb8094b41c 100644
--- a/boost/mpi/packed_iarchive.hpp
+++ b/boost/mpi/packed_iarchive.hpp
@@ -94,48 +94,48 @@ public:
// Load everything else in the usual way, forwarding on to the Base class
template<class T>
- void load_override(T& x, int version, mpl::false_)
+ void load_override(T& x, mpl::false_)
{
- archive::detail::common_iarchive<packed_iarchive>::load_override(x,version);
+ archive::detail::common_iarchive<packed_iarchive>::load_override(x);
}
// Load it directly using the primnivites
template<class T>
- void load_override(T& x, int /*version*/, mpl::true_)
+ void load_override(T& x, mpl::true_)
{
iprimitive::load(x);
}
// Load all supported datatypes directly
template<class T>
- void load_override(T& x, int version)
+ void load_override(T& x)
{
typedef typename mpl::apply1<use_array_optimization
, BOOST_DEDUCED_TYPENAME remove_const<T>::type
>::type use_optimized;
- load_override(x, version, use_optimized());
+ load_override(x, use_optimized());
}
// input archives need to ignore the optional information
- void load_override(archive::class_id_optional_type & /*t*/, int){}
+ void load_override(archive::class_id_optional_type & /*t*/){}
- void load_override(archive::class_id_type & t, int version){
+ void load_override(archive::class_id_type & t){
int_least16_t x=0;
* this->This() >> x;
t = boost::archive::class_id_type(x);
}
- void load_override(archive::version_type & t, int version){
+ void load_override(archive::version_type & t){
int_least8_t x=0;
* this->This() >> x;
t = boost::archive::version_type(x);
}
- void load_override(archive::class_id_reference_type & t, int version){
- load_override(static_cast<archive::class_id_type &>(t), version);
+ void load_override(archive::class_id_reference_type & t){
+ load_override(static_cast<archive::class_id_type &>(t));
}
- void load_override(archive::class_name_type & t, int)
+ void load_override(archive::class_name_type & t)
{
std::string cn;
cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
diff --git a/boost/mpi/packed_oarchive.hpp b/boost/mpi/packed_oarchive.hpp
index 887aeac6e3..c6c0173ae6 100644
--- a/boost/mpi/packed_oarchive.hpp
+++ b/boost/mpi/packed_oarchive.hpp
@@ -92,41 +92,41 @@ public:
// Save everything else in the usual way, forwarding on to the Base class
template<class T>
- void save_override(T const& x, int version, mpl::false_)
+ void save_override(T const& x, mpl::false_)
{
- archive::detail::common_oarchive<packed_oarchive>::save_override(x,version);
+ archive::detail::common_oarchive<packed_oarchive>::save_override(x);
}
// Save it directly using the primitives
template<class T>
- void save_override(T const& x, int /*version*/, mpl::true_)
+ void save_override(T const& x, mpl::true_)
{
oprimitive::save(x);
}
// Save all supported datatypes directly
template<class T>
- void save_override(T const& x, int version)
+ void save_override(T const& x)
{
typedef typename mpl::apply1<use_array_optimization,T>::type use_optimized;
- save_override(x, version, use_optimized());
+ save_override(x, use_optimized());
}
- // input archives need to ignore the optional information
- void save_override(const archive::class_id_optional_type & /*t*/, int){}
+ // output archives need to ignore the optional information
+ void save_override(const archive::class_id_optional_type & ){}
// explicitly convert to char * to avoid compile ambiguities
- void save_override(const archive::class_name_type & t, int){
+ void save_override(const archive::class_name_type & t){
const std::string s(t);
* this->This() << s;
}
- void save_override(archive::class_id_type & t, int version){
+ void save_override(const archive::class_id_type & t){
const boost::int_least16_t x = t;
* this->This() << x;
}
- void save_override(archive::version_type & t, int version){
+ void save_override(const archive::version_type & t){
const boost::int_least8_t x = t;
* this->This() << x;
}
diff --git a/boost/mpl/aux_/insert_range_impl.hpp b/boost/mpl/aux_/insert_range_impl.hpp
index baffb54a2d..fa4331562d 100644
--- a/boost/mpl/aux_/insert_range_impl.hpp
+++ b/boost/mpl/aux_/insert_range_impl.hpp
@@ -14,9 +14,10 @@
// $Date$
// $Revision$
-#include <boost/mpl/copy.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/mpl/insert.hpp>
#include <boost/mpl/clear.hpp>
-#include <boost/mpl/front_inserter.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/iterator_range.hpp>
#include <boost/mpl/aux_/na_spec.hpp>
@@ -43,29 +44,31 @@ struct insert_range_impl
>
struct apply
#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING)
- : reverse_copy<
- joint_view<
+ : reverse_fold<
+ joint_view<
iterator_range<typename begin<Sequence>::type,Pos>
- , joint_view<
+ , joint_view<
Range
, iterator_range<Pos,typename end<Sequence>::type>
>
>
- , front_inserter< typename clear<Sequence>::type >
+ , typename clear<Sequence>::type
+ , insert<_1, begin<_1>, _2>
>
{
#else
{
- typedef typename reverse_copy<
- joint_view<
- iterator_range<typename begin<Sequence>::type,Pos>
- , joint_view<
- Range
- , iterator_range<Pos,typename end<Sequence>::type>
- >
- >
- , front_inserter< typename clear<Sequence>::type >
- >::type type;
+ typedef typename reverse_fold<
+ joint_view<
+ iterator_range<typename begin<Sequence>::type,Pos>
+ , joint_view<
+ Range
+ , iterator_range<Pos,typename end<Sequence>::type>
+ >
+ >
+ , typename clear<Sequence>::type
+ , insert<_1, begin<_1>, _2>
+ >::type type;
#endif
};
};
diff --git a/boost/mpl/empty_base.hpp b/boost/mpl/empty_base.hpp
index a5841cf17a..cb56ef676c 100644
--- a/boost/mpl/empty_base.hpp
+++ b/boost/mpl/empty_base.hpp
@@ -17,12 +17,11 @@
#include <boost/mpl/bool.hpp>
#include <boost/mpl/aux_/config/msvc.hpp>
#include <boost/mpl/aux_/config/workaround.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_empty.hpp>
-// should be always the last #include directive
-#include <boost/type_traits/detail/bool_trait_def.hpp>
-
namespace boost { namespace mpl {
// empty base class, guaranteed to have no members; inheritance from
@@ -51,9 +50,14 @@ struct is_empty_base<empty_base>
}}
namespace boost {
-BOOST_TT_AUX_BOOL_TRAIT_SPEC1(is_empty, mpl::empty_base, true)
-}
-#include <boost/type_traits/detail/bool_trait_undef.hpp>
+template<> struct is_empty< mpl::empty_base >
+ : public ::boost::integral_constant<bool,true>
+{
+public:
+ BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(1,is_empty,(mpl::empty_base))
+};
+
+}
#endif // BOOST_MPL_EMPTY_BASE_HPP_INCLUDED
diff --git a/boost/mpl/empty_sequence.hpp b/boost/mpl/empty_sequence.hpp
index 94f5f5a387..f32cc6ee81 100644
--- a/boost/mpl/empty_sequence.hpp
+++ b/boost/mpl/empty_sequence.hpp
@@ -23,7 +23,8 @@ namespace boost { namespace mpl {
struct empty_sequence
{
- struct tag;
+ struct tag;
+ typedef empty_sequence type;
struct begin { typedef random_access_iterator_tag category; };
typedef begin end;
};
diff --git a/boost/mpl/map/aux_/insert_range_impl.hpp b/boost/mpl/map/aux_/insert_range_impl.hpp
new file mode 100644
index 0000000000..f1f0437c37
--- /dev/null
+++ b/boost/mpl/map/aux_/insert_range_impl.hpp
@@ -0,0 +1,41 @@
+
+#ifndef BOOST_MPL_MAP_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED
+#define BOOST_MPL_MAP_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED
+
+// Copyright Bruno Dutra 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/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/insert_range_fwd.hpp>
+#include <boost/mpl/map/aux_/tag.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/mpl/insert.hpp>
+
+namespace boost { namespace mpl {
+
+template<>
+struct insert_range_impl< aux::map_tag >
+{
+ template<
+ typename Sequence
+ , typename /*Pos*/
+ , typename Range
+ >
+ struct apply
+ : fold<Range, Sequence, insert<_1, _2> >
+ {
+ };
+};
+
+}}
+
+#endif // BOOST_MPL_MAP_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED
diff --git a/boost/mpl/map/aux_/item.hpp b/boost/mpl/map/aux_/item.hpp
index d0df522cd8..a0a98ca8b6 100644
--- a/boost/mpl/map/aux_/item.hpp
+++ b/boost/mpl/map/aux_/item.hpp
@@ -40,6 +40,7 @@ struct m_item
typedef Key key_;
typedef pair<Key,T> item;
typedef Base base;
+ typedef m_item type;
typedef typename next< typename Base::size >::type size;
typedef typename next< typename Base::order >::type order;
@@ -62,6 +63,7 @@ struct m_mask
{
typedef void_ key_;
typedef Base base;
+ typedef m_mask type;
typedef typename prior< typename Base::size >::type size;
typedef typename x_order_impl<Base,Key>::type key_order_;
@@ -123,6 +125,7 @@ struct m_mask
{
typedef void_ key_;
typedef Base base;
+ typedef m_mask type;
typedef typename prior< typename Base::size >::type size;
typedef typename x_order_impl<Base,Key>::type key_order_;
diff --git a/boost/mpl/map/map0.hpp b/boost/mpl/map/map0.hpp
index e1ea897b21..88ed4b7c83 100644
--- a/boost/mpl/map/map0.hpp
+++ b/boost/mpl/map/map0.hpp
@@ -19,6 +19,7 @@
#include <boost/mpl/map/aux_/at_impl.hpp>
//#include <boost/mpl/map/aux_/O1_size.hpp>
#include <boost/mpl/map/aux_/insert_impl.hpp>
+#include <boost/mpl/map/aux_/insert_range_impl.hpp>
#include <boost/mpl/map/aux_/erase_impl.hpp>
#include <boost/mpl/map/aux_/erase_key_impl.hpp>
#include <boost/mpl/map/aux_/has_key_impl.hpp>
diff --git a/boost/mpl/set/aux_/insert_range_impl.hpp b/boost/mpl/set/aux_/insert_range_impl.hpp
new file mode 100644
index 0000000000..f7150a8714
--- /dev/null
+++ b/boost/mpl/set/aux_/insert_range_impl.hpp
@@ -0,0 +1,41 @@
+
+#ifndef BOOST_MPL_SET_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED
+#define BOOST_MPL_SET_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED
+
+// Copyright Bruno Dutra 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/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/insert_range_fwd.hpp>
+#include <boost/mpl/set/aux_/tag.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/mpl/insert.hpp>
+
+namespace boost { namespace mpl {
+
+template<>
+struct insert_range_impl< aux::set_tag >
+{
+ template<
+ typename Sequence
+ , typename /*Pos*/
+ , typename Range
+ >
+ struct apply
+ : fold<Range, Sequence, insert<_1, _2> >
+ {
+ };
+};
+
+}}
+
+#endif // BOOST_MPL_SET_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED
diff --git a/boost/mpl/set/aux_/item.hpp b/boost/mpl/set/aux_/item.hpp
index e90e4900f6..bd5bc953f4 100644
--- a/boost/mpl/set/aux_/item.hpp
+++ b/boost/mpl/set/aux_/item.hpp
@@ -33,6 +33,7 @@ struct s_item
typedef void_ last_masked_;
typedef T item_type_;
typedef typename Base::item_ base;
+ typedef s_item type;
typedef typename next< typename Base::size >::type size;
typedef typename next< typename Base::order >::type order;
@@ -57,6 +58,7 @@ struct s_mask
typedef void_ item_type_;
typedef typename Base::item_ base;
typedef typename prior< typename Base::size >::type size;
+ typedef s_mask type;
BOOST_MPL_AUX_SET_OVERLOAD( aux::yes_tag, IS_MASKED, s_mask, aux::type_wrapper<T>* );
};
diff --git a/boost/mpl/set/set0.hpp b/boost/mpl/set/set0.hpp
index 8403731040..1c424e4646 100644
--- a/boost/mpl/set/set0.hpp
+++ b/boost/mpl/set/set0.hpp
@@ -21,6 +21,7 @@
#include <boost/mpl/set/aux_/size_impl.hpp>
#include <boost/mpl/set/aux_/empty_impl.hpp>
#include <boost/mpl/set/aux_/insert_impl.hpp>
+#include <boost/mpl/set/aux_/insert_range_impl.hpp>
#include <boost/mpl/set/aux_/erase_impl.hpp>
#include <boost/mpl/set/aux_/erase_key_impl.hpp>
#include <boost/mpl/set/aux_/has_key_impl.hpp>
diff --git a/boost/multi_index/composite_key.hpp b/boost/multi_index/composite_key.hpp
index 0f26a195b2..787cdf8319 100644
--- a/boost/multi_index/composite_key.hpp
+++ b/boost/multi_index/composite_key.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2014 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -731,7 +731,7 @@ inline bool operator==(
key_tuple>::result_type cons_key_tuple;
BOOST_STATIC_ASSERT(
- tuples::length<key_extractor_tuple>::value==
+ static_cast<std::size_t>(tuples::length<key_extractor_tuple>::value)==
std::tuple_size<key_tuple>::value);
return detail::equal_ckey_cval<
@@ -754,7 +754,7 @@ inline bool operator==(
key_tuple>::result_type cons_key_tuple;
BOOST_STATIC_ASSERT(
- tuples::length<key_extractor_tuple>::value==
+ static_cast<std::size_t>(tuples::length<key_extractor_tuple>::value)==
std::tuple_size<key_tuple>::value);
return detail::equal_ckey_cval<
@@ -1049,7 +1049,7 @@ public:
BOOST_STATIC_ASSERT(
tuples::length<key_extractor_tuple>::value<=
tuples::length<key_eq_tuple>::value&&
- tuples::length<key_extractor_tuple>::value==
+ static_cast<std::size_t>(tuples::length<key_extractor_tuple>::value)==
std::tuple_size<key_tuple>::value);
return detail::equal_ckey_cval<
@@ -1073,9 +1073,9 @@ public:
BOOST_STATIC_ASSERT(
std::tuple_size<key_tuple>::value<=
- tuples::length<key_eq_tuple>::value&&
+ static_cast<std::size_t>(tuples::length<key_eq_tuple>::value)&&
std::tuple_size<key_tuple>::value==
- tuples::length<key_extractor_tuple>::value);
+ static_cast<std::size_t>(tuples::length<key_extractor_tuple>::value));
return detail::equal_ckey_cval<
key_extractor_tuple,value_type,
@@ -1225,7 +1225,7 @@ public:
tuples::length<key_extractor_tuple>::value<=
tuples::length<key_comp_tuple>::value||
std::tuple_size<key_tuple>::value<=
- tuples::length<key_comp_tuple>::value);
+ static_cast<std::size_t>(tuples::length<key_comp_tuple>::value));
return detail::compare_ckey_cval<
key_extractor_tuple,value_type,
@@ -1248,7 +1248,7 @@ public:
BOOST_STATIC_ASSERT(
std::tuple_size<key_tuple>::value<=
- tuples::length<key_comp_tuple>::value||
+ static_cast<std::size_t>(tuples::length<key_comp_tuple>::value)||
tuples::length<key_extractor_tuple>::value<=
tuples::length<key_comp_tuple>::value);
@@ -1329,7 +1329,7 @@ public:
BOOST_STATIC_ASSERT(
std::tuple_size<key_tuple>::value==
- tuples::length<key_hasher_tuple>::value);
+ static_cast<std::size_t>(tuples::length<key_hasher_tuple>::value));
return detail::hash_cval<
cons_key_tuple,key_hasher_tuple
diff --git a/boost/multi_index/detail/archive_constructed.hpp b/boost/multi_index/detail/archive_constructed.hpp
index 0cf7991e86..c3891bb32a 100644
--- a/boost/multi_index/detail/archive_constructed.hpp
+++ b/boost/multi_index/detail/archive_constructed.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -64,7 +64,7 @@ struct archive_constructed:private noncopyable
(&get())->~T();
}
- T& get(){return *static_cast<T*>(static_cast<void*>(&space));}
+ T& get(){return *reinterpret_cast<T*>(&space);}
private:
typename aligned_storage<sizeof(T),alignment_of<T>::value>::type space;
diff --git a/boost/multi_index/detail/bucket_array.hpp b/boost/multi_index/detail/bucket_array.hpp
index f688ba1621..d9fa434d9a 100644
--- a/boost/multi_index/detail/bucket_array.hpp
+++ b/boost/multi_index/detail/bucket_array.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2014 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -77,7 +77,8 @@ template<bool _=true> /* templatized to have in-header static var defs */
class bucket_array_base:private noncopyable
{
protected:
- static const std::size_t sizes[];
+ static const std::size_t sizes[
+ BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES)];
static std::size_t size_index(std::size_t n)
{
diff --git a/boost/multi_index/detail/copy_map.hpp b/boost/multi_index/detail/copy_map.hpp
index a0b6cad590..9a34b259cf 100644
--- a/boost/multi_index/detail/copy_map.hpp
+++ b/boost/multi_index/detail/copy_map.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -17,6 +17,7 @@
#include <algorithm>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/multi_index/detail/auto_space.hpp>
+#include <boost/multi_index/detail/raw_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <cstddef>
#include <functional>
@@ -75,13 +76,13 @@ public:
}
}
- const_iterator begin()const{return &*spc.data();}
- const_iterator end()const{return &*(spc.data()+n);}
+ const_iterator begin()const{return raw_ptr<const_iterator>(spc.data());}
+ const_iterator end()const{return raw_ptr<const_iterator>(spc.data()+n);}
void clone(Node* node)
{
(spc.data()+n)->first=node;
- (spc.data()+n)->second=&*al_.allocate(1);
+ (spc.data()+n)->second=raw_ptr<Node*>(al_.allocate(1));
BOOST_TRY{
boost::detail::allocator::construct(
&(spc.data()+n)->second->value(),node->value());
@@ -93,7 +94,11 @@ public:
BOOST_CATCH_END
++n;
- if(n==size_)std::sort(&*spc.data(),&*spc.data()+size_);
+ if(n==size_){
+ std::sort(
+ raw_ptr<copy_map_entry<Node>*>(spc.data()),
+ raw_ptr<copy_map_entry<Node>*>(spc.data())+size_);
+ }
}
Node* find(Node* node)const
diff --git a/boost/multi_index/detail/hash_index_node.hpp b/boost/multi_index/detail/hash_index_node.hpp
index cfc60f6488..7788e810ac 100644
--- a/boost/multi_index/detail/hash_index_node.hpp
+++ b/boost/multi_index/detail/hash_index_node.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2014 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -15,6 +15,7 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/allocator_utilities.hpp>
+#include <boost/multi_index/detail/raw_ptr.hpp>
#include <utility>
namespace boost{
@@ -143,12 +144,15 @@ public:
static pointer pointer_from(base_pointer x)
{
- return static_cast<pointer>(static_cast<hashed_index_node_impl*>(&*x));
+ return static_cast<pointer>(
+ static_cast<hashed_index_node_impl*>(
+ raw_ptr<super*>(x)));
}
static base_pointer base_pointer_from(pointer x)
{
- return static_cast<base_pointer>(&*x);
+ return static_cast<base_pointer>(
+ raw_ptr<hashed_index_node_impl*>(x));
}
private:
@@ -738,14 +742,18 @@ public:
static hashed_index_node* from_impl(impl_pointer x)
{
- return static_cast<hashed_index_node*>(
- static_cast<trampoline*>(&*x));
+ return
+ static_cast<hashed_index_node*>(
+ static_cast<trampoline*>(
+ raw_ptr<impl_type*>(x)));
}
static const hashed_index_node* from_impl(const_impl_pointer x)
{
- return static_cast<const hashed_index_node*>(
- static_cast<const trampoline*>(&*x));
+ return
+ static_cast<const hashed_index_node*>(
+ static_cast<const trampoline*>(
+ raw_ptr<const impl_type*>(x)));
}
/* interoperability with hashed_index_iterator */
diff --git a/boost/multi_index/detail/index_loader.hpp b/boost/multi_index/detail/index_loader.hpp
index 3f0428c595..71418a10e1 100644
--- a/boost/multi_index/detail/index_loader.hpp
+++ b/boost/multi_index/detail/index_loader.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -18,6 +18,7 @@
#include <boost/archive/archive_exception.hpp>
#include <boost/noncopyable.hpp>
#include <boost/multi_index/detail/auto_space.hpp>
+#include <boost/multi_index/detail/raw_ptr.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/throw_exception.hpp>
#include <cstddef>
@@ -91,7 +92,7 @@ public:
}
private:
- Node** entries()const{return &*spc.data();}
+ Node** entries()const{return raw_ptr<Node**>(spc.data());}
/* We try to delay sorting as much as possible just in case it
* is not necessary, hence this version of load_node.
diff --git a/boost/multi_index/detail/index_matcher.hpp b/boost/multi_index/detail/index_matcher.hpp
index f3675acd40..34d1f9d5a8 100644
--- a/boost/multi_index/detail/index_matcher.hpp
+++ b/boost/multi_index/detail/index_matcher.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -17,6 +17,7 @@
#include <algorithm>
#include <boost/noncopyable.hpp>
#include <boost/multi_index/detail/auto_space.hpp>
+#include <boost/multi_index/detail/raw_ptr.hpp>
#include <cstddef>
#include <functional>
@@ -179,7 +180,7 @@ protected:
}
private:
- entry* entries()const{return &*spc.data();}
+ entry* entries()const{return raw_ptr<entry*>(spc.data());}
auto_space<entry,Allocator> spc;
std::size_t size_;
diff --git a/boost/multi_index/detail/index_node_base.hpp b/boost/multi_index/detail/index_node_base.hpp
index 150eb75e79..e6fabe62bb 100644
--- a/boost/multi_index/detail/index_node_base.hpp
+++ b/boost/multi_index/detail/index_node_base.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -51,14 +51,12 @@ struct index_node_base:private pod_value_holder<Value>
value_type& value()
{
- return *static_cast<value_type*>(
- static_cast<void*>(&this->space));
+ return *reinterpret_cast<value_type*>(&this->space);
}
const value_type& value()const
{
- return *static_cast<const value_type*>(
- static_cast<const void*>(&this->space));
+ return *reinterpret_cast<const value_type*>(&this->space);
}
static index_node_base* from_value(const value_type* p)
diff --git a/boost/multi_index/detail/ord_index_impl.hpp b/boost/multi_index/detail/ord_index_impl.hpp
new file mode 100644
index 0000000000..8ebaccb2cf
--- /dev/null
+++ b/boost/multi_index/detail/ord_index_impl.hpp
@@ -0,0 +1,1567 @@
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ *
+ * The internal implementation of red-black trees is based on that of SGI STL
+ * stl_tree.h file:
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP
+#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <boost/call_traits.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/foreach_fwd.hpp>
+#include <boost/iterator/reverse_iterator.hpp>
+#include <boost/move/core.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/push_front.hpp>
+#include <boost/multi_index/detail/access_specifier.hpp>
+#include <boost/multi_index/detail/bidir_node_iterator.hpp>
+#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
+#include <boost/multi_index/detail/index_node_base.hpp>
+#include <boost/multi_index/detail/modify_key_adaptor.hpp>
+#include <boost/multi_index/detail/ord_index_node.hpp>
+#include <boost/multi_index/detail/ord_index_ops.hpp>
+#include <boost/multi_index/detail/safe_mode.hpp>
+#include <boost/multi_index/detail/scope_guard.hpp>
+#include <boost/multi_index/detail/unbounded.hpp>
+#include <boost/multi_index/detail/value_compare.hpp>
+#include <boost/multi_index/detail/vartempl_support.hpp>
+#include <boost/multi_index/detail/ord_index_impl_fwd.hpp>
+#include <boost/ref.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <utility>
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>
+#endif
+
+#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
+#include <boost/archive/archive_exception.hpp>
+#include <boost/bind.hpp>
+#include <boost/multi_index/detail/duplicates_iterator.hpp>
+#include <boost/throw_exception.hpp>
+#endif
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
+#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \
+ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
+ detail::make_obj_guard(x,&ordered_index_impl::check_invariant_); \
+ BOOST_JOIN(check_invariant_,__LINE__).touch();
+#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this)
+#else
+#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x)
+#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
+#endif
+
+namespace boost{
+
+namespace multi_index{
+
+namespace detail{
+
+/* ordered_index adds a layer of ordered indexing to a given Super and accepts
+ * an augmenting policy for optional addition of order statistics.
+ */
+
+/* Most of the implementation of unique and non-unique indices is
+ * shared. We tell from one another on instantiation time by using
+ * these tags.
+ */
+
+struct ordered_unique_tag{};
+struct ordered_non_unique_tag{};
+
+template<
+ typename KeyFromValue,typename Compare,
+ typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
+>
+class ordered_index;
+
+template<
+ typename KeyFromValue,typename Compare,
+ typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
+>
+class ordered_index_impl:
+ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ ,public safe_mode::safe_container<
+ ordered_index_impl<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy> >
+#endif
+
+{
+#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
+ BOOST_WORKAROUND(__MWERKS__,<=0x3003)
+/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
+ * lifetime of const references bound to temporaries --precisely what
+ * scopeguards are.
+ */
+
+#pragma parse_mfunc_templ off
+#endif
+
+ typedef typename SuperMeta::type super;
+
+protected:
+ typedef ordered_index_node<
+ AugmentPolicy,typename super::node_type> node_type;
+
+protected: /* for the benefit of AugmentPolicy::augmented_interface */
+ typedef typename node_type::impl_type node_impl_type;
+ typedef typename node_impl_type::pointer node_impl_pointer;
+
+public:
+ /* types */
+
+ typedef typename KeyFromValue::result_type key_type;
+ typedef typename node_type::value_type value_type;
+ typedef KeyFromValue key_from_value;
+ typedef Compare key_compare;
+ typedef value_comparison<
+ value_type,KeyFromValue,Compare> value_compare;
+ typedef tuple<key_from_value,key_compare> ctor_args;
+ typedef typename super::final_allocator_type allocator_type;
+ typedef typename allocator_type::reference reference;
+ typedef typename allocator_type::const_reference const_reference;
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ typedef safe_mode::safe_iterator<
+ bidir_node_iterator<node_type>,
+ ordered_index_impl> iterator;
+#else
+ typedef bidir_node_iterator<node_type> iterator;
+#endif
+
+ typedef iterator const_iterator;
+
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef typename allocator_type::pointer pointer;
+ typedef typename allocator_type::const_pointer const_pointer;
+ typedef typename
+ boost::reverse_iterator<iterator> reverse_iterator;
+ typedef typename
+ boost::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef TagList tag_list;
+
+protected:
+ typedef typename super::final_node_type final_node_type;
+ typedef tuples::cons<
+ ctor_args,
+ typename super::ctor_args_list> ctor_args_list;
+ typedef typename mpl::push_front<
+ typename super::index_type_list,
+ ordered_index<
+ KeyFromValue,Compare,
+ SuperMeta,TagList,Category,AugmentPolicy
+ > >::type index_type_list;
+ typedef typename mpl::push_front<
+ typename super::iterator_type_list,
+ iterator>::type iterator_type_list;
+ typedef typename mpl::push_front<
+ typename super::const_iterator_type_list,
+ const_iterator>::type const_iterator_type_list;
+ typedef typename super::copy_map_type copy_map_type;
+
+#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
+ typedef typename super::index_saver_type index_saver_type;
+ typedef typename super::index_loader_type index_loader_type;
+#endif
+
+protected:
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ typedef safe_mode::safe_container<
+ ordered_index_impl> safe_super;
+#endif
+
+ typedef typename call_traits<
+ value_type>::param_type value_param_type;
+ typedef typename call_traits<
+ key_type>::param_type key_param_type;
+
+ /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
+ * expansion.
+ */
+
+ typedef std::pair<iterator,bool> emplace_return_type;
+
+public:
+
+ /* construct/copy/destroy
+ * Default and copy ctors are in the protected section as indices are
+ * not supposed to be created on their own. No range ctor either.
+ * Assignment operators defined at ordered_index rather than here.
+ */
+
+ allocator_type get_allocator()const BOOST_NOEXCEPT
+ {
+ return this->final().get_allocator();
+ }
+
+ /* iterators */
+
+ iterator
+ begin()BOOST_NOEXCEPT{return make_iterator(leftmost());}
+ const_iterator
+ begin()const BOOST_NOEXCEPT{return make_iterator(leftmost());}
+ iterator
+ end()BOOST_NOEXCEPT{return make_iterator(header());}
+ const_iterator
+ end()const BOOST_NOEXCEPT{return make_iterator(header());}
+ reverse_iterator
+ rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
+ const_reverse_iterator
+ rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
+ reverse_iterator
+ rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
+ const_reverse_iterator
+ rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
+ const_iterator
+ cbegin()const BOOST_NOEXCEPT{return begin();}
+ const_iterator
+ cend()const BOOST_NOEXCEPT{return end();}
+ const_reverse_iterator
+ crbegin()const BOOST_NOEXCEPT{return rbegin();}
+ const_reverse_iterator
+ crend()const BOOST_NOEXCEPT{return rend();}
+
+ iterator iterator_to(const value_type& x)
+ {
+ return make_iterator(node_from_value<node_type>(&x));
+ }
+
+ const_iterator iterator_to(const value_type& x)const
+ {
+ return make_iterator(node_from_value<node_type>(&x));
+ }
+
+ /* capacity */
+
+ bool empty()const BOOST_NOEXCEPT{return this->final_empty_();}
+ size_type size()const BOOST_NOEXCEPT{return this->final_size_();}
+ size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();}
+
+ /* modifiers */
+
+ BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
+ emplace_return_type,emplace,emplace_impl)
+
+ BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
+ iterator,emplace_hint,emplace_hint_impl,iterator,position)
+
+ std::pair<iterator,bool> insert(const value_type& x)
+ {
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ std::pair<final_node_type*,bool> p=this->final_insert_(x);
+ return std::pair<iterator,bool>(make_iterator(p.first),p.second);
+ }
+
+ std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
+ {
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
+ return std::pair<iterator,bool>(make_iterator(p.first),p.second);
+ }
+
+ iterator insert(iterator position,const value_type& x)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ std::pair<final_node_type*,bool> p=this->final_insert_(
+ x,static_cast<final_node_type*>(position.get_node()));
+ return make_iterator(p.first);
+ }
+
+ iterator insert(iterator position,BOOST_RV_REF(value_type) x)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ std::pair<final_node_type*,bool> p=this->final_insert_rv_(
+ x,static_cast<final_node_type*>(position.get_node()));
+ return make_iterator(p.first);
+ }
+
+ template<typename InputIterator>
+ void insert(InputIterator first,InputIterator last)
+ {
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ node_type* hint=header(); /* end() */
+ for(;first!=last;++first){
+ hint=this->final_insert_ref_(
+ *first,static_cast<final_node_type*>(hint)).first;
+ node_type::increment(hint);
+ }
+ }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ void insert(std::initializer_list<value_type> list)
+ {
+ insert(list.begin(),list.end());
+ }
+#endif
+
+ iterator erase(iterator position)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
+ return position;
+ }
+
+ size_type erase(key_param_type x)
+ {
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ std::pair<iterator,iterator> p=equal_range(x);
+ size_type s=0;
+ while(p.first!=p.second){
+ p.first=erase(p.first);
+ ++s;
+ }
+ return s;
+ }
+
+ iterator erase(iterator first,iterator last)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
+ BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ while(first!=last){
+ first=erase(first);
+ }
+ return first;
+ }
+
+ bool replace(iterator position,const value_type& x)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ return this->final_replace_(
+ x,static_cast<final_node_type*>(position.get_node()));
+ }
+
+ bool replace(iterator position,BOOST_RV_REF(value_type) x)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ return this->final_replace_rv_(
+ x,static_cast<final_node_type*>(position.get_node()));
+ }
+
+ template<typename Modifier>
+ bool modify(iterator position,Modifier mod)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ /* MSVC++ 6.0 optimizer on safe mode code chokes if this
+ * this is not added. Left it for all compilers as it does no
+ * harm.
+ */
+
+ position.detach();
+#endif
+
+ return this->final_modify_(
+ mod,static_cast<final_node_type*>(position.get_node()));
+ }
+
+ template<typename Modifier,typename Rollback>
+ bool modify(iterator position,Modifier mod,Rollback back_)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ /* MSVC++ 6.0 optimizer on safe mode code chokes if this
+ * this is not added. Left it for all compilers as it does no
+ * harm.
+ */
+
+ position.detach();
+#endif
+
+ return this->final_modify_(
+ mod,back_,static_cast<final_node_type*>(position.get_node()));
+ }
+
+ template<typename Modifier>
+ bool modify_key(iterator position,Modifier mod)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ return modify(
+ position,modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key));
+ }
+
+ template<typename Modifier,typename Rollback>
+ bool modify_key(iterator position,Modifier mod,Rollback back_)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ return modify(
+ position,
+ modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key),
+ modify_key_adaptor<Rollback,value_type,KeyFromValue>(back_,key));
+ }
+
+ void swap(
+ ordered_index<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
+ {
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x);
+ this->final_swap_(x.final());
+ }
+
+ void clear()BOOST_NOEXCEPT
+ {
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ this->final_clear_();
+ }
+
+ /* observers */
+
+ key_from_value key_extractor()const{return key;}
+ key_compare key_comp()const{return comp_;}
+ value_compare value_comp()const{return value_compare(key,comp_);}
+
+ /* set operations */
+
+ /* Internally, these ops rely on const_iterator being the same
+ * type as iterator.
+ */
+
+ template<typename CompatibleKey>
+ iterator find(const CompatibleKey& x)const
+ {
+ return make_iterator(ordered_index_find(root(),header(),key,x,comp_));
+ }
+
+ template<typename CompatibleKey,typename CompatibleCompare>
+ iterator find(
+ const CompatibleKey& x,const CompatibleCompare& comp)const
+ {
+ return make_iterator(ordered_index_find(root(),header(),key,x,comp));
+ }
+
+ template<typename CompatibleKey>
+ size_type count(const CompatibleKey& x)const
+ {
+ return count(x,comp_);
+ }
+
+ template<typename CompatibleKey,typename CompatibleCompare>
+ size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const
+ {
+ std::pair<iterator,iterator> p=equal_range(x,comp);
+ size_type n=std::distance(p.first,p.second);
+ return n;
+ }
+
+ template<typename CompatibleKey>
+ iterator lower_bound(const CompatibleKey& x)const
+ {
+ return make_iterator(
+ ordered_index_lower_bound(root(),header(),key,x,comp_));
+ }
+
+ template<typename CompatibleKey,typename CompatibleCompare>
+ iterator lower_bound(
+ const CompatibleKey& x,const CompatibleCompare& comp)const
+ {
+ return make_iterator(
+ ordered_index_lower_bound(root(),header(),key,x,comp));
+ }
+
+ template<typename CompatibleKey>
+ iterator upper_bound(const CompatibleKey& x)const
+ {
+ return make_iterator(
+ ordered_index_upper_bound(root(),header(),key,x,comp_));
+ }
+
+ template<typename CompatibleKey,typename CompatibleCompare>
+ iterator upper_bound(
+ const CompatibleKey& x,const CompatibleCompare& comp)const
+ {
+ return make_iterator(
+ ordered_index_upper_bound(root(),header(),key,x,comp));
+ }
+
+ template<typename CompatibleKey>
+ std::pair<iterator,iterator> equal_range(
+ const CompatibleKey& x)const
+ {
+ std::pair<node_type*,node_type*> p=
+ ordered_index_equal_range(root(),header(),key,x,comp_);
+ return std::pair<iterator,iterator>(
+ make_iterator(p.first),make_iterator(p.second));
+ }
+
+ template<typename CompatibleKey,typename CompatibleCompare>
+ std::pair<iterator,iterator> equal_range(
+ const CompatibleKey& x,const CompatibleCompare& comp)const
+ {
+ std::pair<node_type*,node_type*> p=
+ ordered_index_equal_range(root(),header(),key,x,comp);
+ return std::pair<iterator,iterator>(
+ make_iterator(p.first),make_iterator(p.second));
+ }
+
+ /* range */
+
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<iterator,iterator>
+ range(LowerBounder lower,UpperBounder upper)const
+ {
+ typedef typename mpl::if_<
+ is_same<LowerBounder,unbounded_type>,
+ BOOST_DEDUCED_TYPENAME mpl::if_<
+ is_same<UpperBounder,unbounded_type>,
+ both_unbounded_tag,
+ lower_unbounded_tag
+ >::type,
+ BOOST_DEDUCED_TYPENAME mpl::if_<
+ is_same<UpperBounder,unbounded_type>,
+ upper_unbounded_tag,
+ none_unbounded_tag
+ >::type
+ >::type dispatch;
+
+ return range(lower,upper,dispatch());
+ }
+
+BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
+ ordered_index_impl(const ctor_args_list& args_list,const allocator_type& al):
+ super(args_list.get_tail(),al),
+ key(tuples::get<0>(args_list.get_head())),
+ comp_(tuples::get<1>(args_list.get_head()))
+ {
+ empty_initialize();
+ }
+
+ ordered_index_impl(
+ const ordered_index_impl<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x):
+ super(x),
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ safe_super(),
+#endif
+
+ key(x.key),
+ comp_(x.comp_)
+ {
+ /* Copy ctor just takes the key and compare objects from x. The rest is
+ * done in a subsequent call to copy_().
+ */
+ }
+
+ ordered_index_impl(
+ const ordered_index_impl<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
+ do_not_copy_elements_tag):
+ super(x,do_not_copy_elements_tag()),
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ safe_super(),
+#endif
+
+ key(x.key),
+ comp_(x.comp_)
+ {
+ empty_initialize();
+ }
+
+ ~ordered_index_impl()
+ {
+ /* the container is guaranteed to be empty by now */
+ }
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ iterator make_iterator(node_type* node){return iterator(node,this);}
+ const_iterator make_iterator(node_type* node)const
+ {return const_iterator(node,const_cast<ordered_index_impl*>(this));}
+#else
+ iterator make_iterator(node_type* node){return iterator(node);}
+ const_iterator make_iterator(node_type* node)const
+ {return const_iterator(node);}
+#endif
+
+ void copy_(
+ const ordered_index_impl<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
+ const copy_map_type& map)
+ {
+ if(!x.root()){
+ empty_initialize();
+ }
+ else{
+ header()->color()=x.header()->color();
+ AugmentPolicy::copy(x.header()->impl(),header()->impl());
+
+ node_type* root_cpy=map.find(static_cast<final_node_type*>(x.root()));
+ header()->parent()=root_cpy->impl();
+
+ node_type* leftmost_cpy=map.find(
+ static_cast<final_node_type*>(x.leftmost()));
+ header()->left()=leftmost_cpy->impl();
+
+ node_type* rightmost_cpy=map.find(
+ static_cast<final_node_type*>(x.rightmost()));
+ header()->right()=rightmost_cpy->impl();
+
+ typedef typename copy_map_type::const_iterator copy_map_iterator;
+ for(copy_map_iterator it=map.begin(),it_end=map.end();it!=it_end;++it){
+ node_type* org=it->first;
+ node_type* cpy=it->second;
+
+ cpy->color()=org->color();
+ AugmentPolicy::copy(org->impl(),cpy->impl());
+
+ node_impl_pointer parent_org=org->parent();
+ if(parent_org==node_impl_pointer(0))cpy->parent()=node_impl_pointer(0);
+ else{
+ node_type* parent_cpy=map.find(
+ static_cast<final_node_type*>(node_type::from_impl(parent_org)));
+ cpy->parent()=parent_cpy->impl();
+ if(parent_org->left()==org->impl()){
+ parent_cpy->left()=cpy->impl();
+ }
+ else if(parent_org->right()==org->impl()){
+ /* header() does not satisfy this nor the previous check */
+ parent_cpy->right()=cpy->impl();
+ }
+ }
+
+ if(org->left()==node_impl_pointer(0))
+ cpy->left()=node_impl_pointer(0);
+ if(org->right()==node_impl_pointer(0))
+ cpy->right()=node_impl_pointer(0);
+ }
+ }
+
+ super::copy_(x,map);
+ }
+
+ template<typename Variant>
+ final_node_type* insert_(
+ value_param_type v,final_node_type*& x,Variant variant)
+ {
+ link_info inf;
+ if(!link_point(key(v),inf,Category())){
+ return static_cast<final_node_type*>(node_type::from_impl(inf.pos));
+ }
+
+ final_node_type* res=super::insert_(v,x,variant);
+ if(res==x){
+ node_impl_type::link(
+ static_cast<node_type*>(x)->impl(),inf.side,inf.pos,header()->impl());
+ }
+ return res;
+ }
+
+ template<typename Variant>
+ final_node_type* insert_(
+ value_param_type v,node_type* position,final_node_type*& x,Variant variant)
+ {
+ link_info inf;
+ if(!hinted_link_point(key(v),position,inf,Category())){
+ return static_cast<final_node_type*>(node_type::from_impl(inf.pos));
+ }
+
+ final_node_type* res=super::insert_(v,position,x,variant);
+ if(res==x){
+ node_impl_type::link(
+ static_cast<node_type*>(x)->impl(),inf.side,inf.pos,header()->impl());
+ }
+ return res;
+ }
+
+ void erase_(node_type* x)
+ {
+ node_impl_type::rebalance_for_erase(
+ x->impl(),header()->parent(),header()->left(),header()->right());
+ super::erase_(x);
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ detach_iterators(x);
+#endif
+ }
+
+ void delete_all_nodes_()
+ {
+ delete_all_nodes(root());
+ }
+
+ void clear_()
+ {
+ super::clear_();
+ empty_initialize();
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ safe_super::detach_dereferenceable_iterators();
+#endif
+ }
+
+ void swap_(
+ ordered_index_impl<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
+ {
+ std::swap(key,x.key);
+ std::swap(comp_,x.comp_);
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ safe_super::swap(x);
+#endif
+
+ super::swap_(x);
+ }
+
+ void swap_elements_(
+ ordered_index_impl<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
+ {
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ safe_super::swap(x);
+#endif
+
+ super::swap_elements_(x);
+ }
+
+ template<typename Variant>
+ bool replace_(value_param_type v,node_type* x,Variant variant)
+ {
+ if(in_place(v,x,Category())){
+ return super::replace_(v,x,variant);
+ }
+
+ node_type* next=x;
+ node_type::increment(next);
+
+ node_impl_type::rebalance_for_erase(
+ x->impl(),header()->parent(),header()->left(),header()->right());
+
+ BOOST_TRY{
+ link_info inf;
+ if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){
+ node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
+ return true;
+ }
+ node_impl_type::restore(x->impl(),next->impl(),header()->impl());
+ return false;
+ }
+ BOOST_CATCH(...){
+ node_impl_type::restore(x->impl(),next->impl(),header()->impl());
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ }
+
+ bool modify_(node_type* x)
+ {
+ bool b;
+ BOOST_TRY{
+ b=in_place(x->value(),x,Category());
+ }
+ BOOST_CATCH(...){
+ erase_(x);
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ if(!b){
+ node_impl_type::rebalance_for_erase(
+ x->impl(),header()->parent(),header()->left(),header()->right());
+ BOOST_TRY{
+ link_info inf;
+ if(!link_point(key(x->value()),inf,Category())){
+ super::erase_(x);
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ detach_iterators(x);
+#endif
+ return false;
+ }
+ node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
+ }
+ BOOST_CATCH(...){
+ super::erase_(x);
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ detach_iterators(x);
+#endif
+
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ }
+
+ BOOST_TRY{
+ if(!super::modify_(x)){
+ node_impl_type::rebalance_for_erase(
+ x->impl(),header()->parent(),header()->left(),header()->right());
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ detach_iterators(x);
+#endif
+
+ return false;
+ }
+ else return true;
+ }
+ BOOST_CATCH(...){
+ node_impl_type::rebalance_for_erase(
+ x->impl(),header()->parent(),header()->left(),header()->right());
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ detach_iterators(x);
+#endif
+
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ }
+
+ bool modify_rollback_(node_type* x)
+ {
+ if(in_place(x->value(),x,Category())){
+ return super::modify_rollback_(x);
+ }
+
+ node_type* next=x;
+ node_type::increment(next);
+
+ node_impl_type::rebalance_for_erase(
+ x->impl(),header()->parent(),header()->left(),header()->right());
+
+ BOOST_TRY{
+ link_info inf;
+ if(link_point(key(x->value()),inf,Category())&&
+ super::modify_rollback_(x)){
+ node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
+ return true;
+ }
+ node_impl_type::restore(x->impl(),next->impl(),header()->impl());
+ return false;
+ }
+ BOOST_CATCH(...){
+ node_impl_type::restore(x->impl(),next->impl(),header()->impl());
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ }
+
+#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
+ /* serialization */
+
+ template<typename Archive>
+ void save_(
+ Archive& ar,const unsigned int version,const index_saver_type& sm)const
+ {
+ save_(ar,version,sm,Category());
+ }
+
+ template<typename Archive>
+ void load_(Archive& ar,const unsigned int version,const index_loader_type& lm)
+ {
+ load_(ar,version,lm,Category());
+ }
+#endif
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
+ /* invariant stuff */
+
+ bool invariant_()const
+ {
+ if(size()==0||begin()==end()){
+ if(size()!=0||begin()!=end()||
+ header()->left()!=header()->impl()||
+ header()->right()!=header()->impl())return false;
+ }
+ else{
+ if((size_type)std::distance(begin(),end())!=size())return false;
+
+ std::size_t len=node_impl_type::black_count(
+ leftmost()->impl(),root()->impl());
+ for(const_iterator it=begin(),it_end=end();it!=it_end;++it){
+ node_type* x=it.get_node();
+ node_type* left_x=node_type::from_impl(x->left());
+ node_type* right_x=node_type::from_impl(x->right());
+
+ if(x->color()==red){
+ if((left_x&&left_x->color()==red)||
+ (right_x&&right_x->color()==red))return false;
+ }
+ if(left_x&&comp_(key(x->value()),key(left_x->value())))return false;
+ if(right_x&&comp_(key(right_x->value()),key(x->value())))return false;
+ if(!left_x&&!right_x&&
+ node_impl_type::black_count(x->impl(),root()->impl())!=len)
+ return false;
+ if(!AugmentPolicy::invariant(x->impl()))return false;
+ }
+
+ if(leftmost()->impl()!=node_impl_type::minimum(root()->impl()))
+ return false;
+ if(rightmost()->impl()!=node_impl_type::maximum(root()->impl()))
+ return false;
+ }
+
+ return super::invariant_();
+ }
+
+
+ /* This forwarding function eases things for the boost::mem_fn construct
+ * in BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT. Actually,
+ * final_check_invariant is already an inherited member function of
+ * ordered_index_impl.
+ */
+ void check_invariant_()const{this->final_check_invariant_();}
+#endif
+
+protected: /* for the benefit of AugmentPolicy::augmented_interface */
+ node_type* header()const{return this->final_header();}
+ node_type* root()const{return node_type::from_impl(header()->parent());}
+ node_type* leftmost()const{return node_type::from_impl(header()->left());}
+ node_type* rightmost()const{return node_type::from_impl(header()->right());}
+
+private:
+ void empty_initialize()
+ {
+ header()->color()=red;
+ /* used to distinguish header() from root, in iterator.operator++ */
+
+ header()->parent()=node_impl_pointer(0);
+ header()->left()=header()->impl();
+ header()->right()=header()->impl();
+ }
+
+ struct link_info
+ {
+ /* coverity[uninit_ctor]: suppress warning */
+ link_info():side(to_left){}
+
+ ordered_index_side side;
+ node_impl_pointer pos;
+ };
+
+ bool link_point(key_param_type k,link_info& inf,ordered_unique_tag)
+ {
+ node_type* y=header();
+ node_type* x=root();
+ bool c=true;
+ while(x){
+ y=x;
+ c=comp_(k,key(x->value()));
+ x=node_type::from_impl(c?x->left():x->right());
+ }
+ node_type* yy=y;
+ if(c){
+ if(yy==leftmost()){
+ inf.side=to_left;
+ inf.pos=y->impl();
+ return true;
+ }
+ else node_type::decrement(yy);
+ }
+
+ if(comp_(key(yy->value()),k)){
+ inf.side=c?to_left:to_right;
+ inf.pos=y->impl();
+ return true;
+ }
+ else{
+ inf.pos=yy->impl();
+ return false;
+ }
+ }
+
+ bool link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
+ {
+ node_type* y=header();
+ node_type* x=root();
+ bool c=true;
+ while (x){
+ y=x;
+ c=comp_(k,key(x->value()));
+ x=node_type::from_impl(c?x->left():x->right());
+ }
+ inf.side=c?to_left:to_right;
+ inf.pos=y->impl();
+ return true;
+ }
+
+ bool lower_link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
+ {
+ node_type* y=header();
+ node_type* x=root();
+ bool c=false;
+ while (x){
+ y=x;
+ c=comp_(key(x->value()),k);
+ x=node_type::from_impl(c?x->right():x->left());
+ }
+ inf.side=c?to_right:to_left;
+ inf.pos=y->impl();
+ return true;
+ }
+
+ bool hinted_link_point(
+ key_param_type k,node_type* position,link_info& inf,ordered_unique_tag)
+ {
+ if(position->impl()==header()->left()){
+ if(size()>0&&comp_(k,key(position->value()))){
+ inf.side=to_left;
+ inf.pos=position->impl();
+ return true;
+ }
+ else return link_point(k,inf,ordered_unique_tag());
+ }
+ else if(position==header()){
+ if(comp_(key(rightmost()->value()),k)){
+ inf.side=to_right;
+ inf.pos=rightmost()->impl();
+ return true;
+ }
+ else return link_point(k,inf,ordered_unique_tag());
+ }
+ else{
+ node_type* before=position;
+ node_type::decrement(before);
+ if(comp_(key(before->value()),k)&&comp_(k,key(position->value()))){
+ if(before->right()==node_impl_pointer(0)){
+ inf.side=to_right;
+ inf.pos=before->impl();
+ return true;
+ }
+ else{
+ inf.side=to_left;
+ inf.pos=position->impl();
+ return true;
+ }
+ }
+ else return link_point(k,inf,ordered_unique_tag());
+ }
+ }
+
+ bool hinted_link_point(
+ key_param_type k,node_type* position,link_info& inf,ordered_non_unique_tag)
+ {
+ if(position->impl()==header()->left()){
+ if(size()>0&&!comp_(key(position->value()),k)){
+ inf.side=to_left;
+ inf.pos=position->impl();
+ return true;
+ }
+ else return lower_link_point(k,inf,ordered_non_unique_tag());
+ }
+ else if(position==header()){
+ if(!comp_(k,key(rightmost()->value()))){
+ inf.side=to_right;
+ inf.pos=rightmost()->impl();
+ return true;
+ }
+ else return link_point(k,inf,ordered_non_unique_tag());
+ }
+ else{
+ node_type* before=position;
+ node_type::decrement(before);
+ if(!comp_(k,key(before->value()))){
+ if(!comp_(key(position->value()),k)){
+ if(before->right()==node_impl_pointer(0)){
+ inf.side=to_right;
+ inf.pos=before->impl();
+ return true;
+ }
+ else{
+ inf.side=to_left;
+ inf.pos=position->impl();
+ return true;
+ }
+ }
+ else return lower_link_point(k,inf,ordered_non_unique_tag());
+ }
+ else return link_point(k,inf,ordered_non_unique_tag());
+ }
+ }
+
+ void delete_all_nodes(node_type* x)
+ {
+ if(!x)return;
+
+ delete_all_nodes(node_type::from_impl(x->left()));
+ delete_all_nodes(node_type::from_impl(x->right()));
+ this->final_delete_node_(static_cast<final_node_type*>(x));
+ }
+
+ bool in_place(value_param_type v,node_type* x,ordered_unique_tag)
+ {
+ node_type* y;
+ if(x!=leftmost()){
+ y=x;
+ node_type::decrement(y);
+ if(!comp_(key(y->value()),key(v)))return false;
+ }
+
+ y=x;
+ node_type::increment(y);
+ return y==header()||comp_(key(v),key(y->value()));
+ }
+
+ bool in_place(value_param_type v,node_type* x,ordered_non_unique_tag)
+ {
+ node_type* y;
+ if(x!=leftmost()){
+ y=x;
+ node_type::decrement(y);
+ if(comp_(key(v),key(y->value())))return false;
+ }
+
+ y=x;
+ node_type::increment(y);
+ return y==header()||!comp_(key(y->value()),key(v));
+ }
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ void detach_iterators(node_type* x)
+ {
+ iterator it=make_iterator(x);
+ safe_mode::detach_equivalent_iterators(it);
+ }
+#endif
+
+ template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
+ std::pair<iterator,bool> emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
+ {
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ std::pair<final_node_type*,bool>p=
+ this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
+ return std::pair<iterator,bool>(make_iterator(p.first),p.second);
+ }
+
+ template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
+ iterator emplace_hint_impl(
+ iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ std::pair<final_node_type*,bool>p=
+ this->final_emplace_hint_(
+ static_cast<final_node_type*>(position.get_node()),
+ BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
+ return make_iterator(p.first);
+ }
+
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<iterator,iterator>
+ range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
+ {
+ node_type* y=header();
+ node_type* z=root();
+
+ while(z){
+ if(!lower(key(z->value()))){
+ z=node_type::from_impl(z->right());
+ }
+ else if(!upper(key(z->value()))){
+ y=z;
+ z=node_type::from_impl(z->left());
+ }
+ else{
+ return std::pair<iterator,iterator>(
+ make_iterator(
+ lower_range(node_type::from_impl(z->left()),z,lower)),
+ make_iterator(
+ upper_range(node_type::from_impl(z->right()),y,upper)));
+ }
+ }
+
+ return std::pair<iterator,iterator>(make_iterator(y),make_iterator(y));
+ }
+
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<iterator,iterator>
+ range(LowerBounder,UpperBounder upper,lower_unbounded_tag)const
+ {
+ return std::pair<iterator,iterator>(
+ begin(),
+ make_iterator(upper_range(root(),header(),upper)));
+ }
+
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<iterator,iterator>
+ range(LowerBounder lower,UpperBounder,upper_unbounded_tag)const
+ {
+ return std::pair<iterator,iterator>(
+ make_iterator(lower_range(root(),header(),lower)),
+ end());
+ }
+
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<iterator,iterator>
+ range(LowerBounder,UpperBounder,both_unbounded_tag)const
+ {
+ return std::pair<iterator,iterator>(begin(),end());
+ }
+
+ template<typename LowerBounder>
+ node_type * lower_range(node_type* top,node_type* y,LowerBounder lower)const
+ {
+ while(top){
+ if(lower(key(top->value()))){
+ y=top;
+ top=node_type::from_impl(top->left());
+ }
+ else top=node_type::from_impl(top->right());
+ }
+
+ return y;
+ }
+
+ template<typename UpperBounder>
+ node_type * upper_range(node_type* top,node_type* y,UpperBounder upper)const
+ {
+ while(top){
+ if(!upper(key(top->value()))){
+ y=top;
+ top=node_type::from_impl(top->left());
+ }
+ else top=node_type::from_impl(top->right());
+ }
+
+ return y;
+ }
+
+#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
+ template<typename Archive>
+ void save_(
+ Archive& ar,const unsigned int version,const index_saver_type& sm,
+ ordered_unique_tag)const
+ {
+ super::save_(ar,version,sm);
+ }
+
+ template<typename Archive>
+ void load_(
+ Archive& ar,const unsigned int version,const index_loader_type& lm,
+ ordered_unique_tag)
+ {
+ super::load_(ar,version,lm);
+ }
+
+ template<typename Archive>
+ void save_(
+ Archive& ar,const unsigned int version,const index_saver_type& sm,
+ ordered_non_unique_tag)const
+ {
+ typedef duplicates_iterator<node_type,value_compare> dup_iterator;
+
+ sm.save(
+ dup_iterator(begin().get_node(),end().get_node(),value_comp()),
+ dup_iterator(end().get_node(),value_comp()),
+ ar,version);
+ super::save_(ar,version,sm);
+ }
+
+ template<typename Archive>
+ void load_(
+ Archive& ar,const unsigned int version,const index_loader_type& lm,
+ ordered_non_unique_tag)
+ {
+ lm.load(
+ ::boost::bind(
+ &ordered_index_impl::rearranger,this,
+ ::boost::arg<1>(),::boost::arg<2>()),
+ ar,version);
+ super::load_(ar,version,lm);
+ }
+
+ void rearranger(node_type* position,node_type *x)
+ {
+ if(!position||comp_(key(position->value()),key(x->value()))){
+ position=lower_bound(key(x->value())).get_node();
+ }
+ else if(comp_(key(x->value()),key(position->value()))){
+ /* inconsistent rearrangement */
+ throw_exception(
+ archive::archive_exception(
+ archive::archive_exception::other_exception));
+ }
+ else node_type::increment(position);
+
+ if(position!=x){
+ node_impl_type::rebalance_for_erase(
+ x->impl(),header()->parent(),header()->left(),header()->right());
+ node_impl_type::restore(
+ x->impl(),position->impl(),header()->impl());
+ }
+ }
+#endif /* serialization */
+
+protected: /* for the benefit of AugmentPolicy::augmented_interface */
+ key_from_value key;
+ key_compare comp_;
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
+ BOOST_WORKAROUND(__MWERKS__,<=0x3003)
+#pragma parse_mfunc_templ reset
+#endif
+};
+
+template<
+ typename KeyFromValue,typename Compare,
+ typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
+>
+class ordered_index:
+ public AugmentPolicy::template augmented_interface<
+ ordered_index_impl<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy
+ >
+ >::type
+{
+ typedef typename AugmentPolicy::template
+ augmented_interface<
+ ordered_index_impl<
+ KeyFromValue,Compare,
+ SuperMeta,TagList,Category,AugmentPolicy
+ >
+ >::type super;
+public:
+ typedef typename super::ctor_args_list ctor_args_list;
+ typedef typename super::allocator_type allocator_type;
+ typedef typename super::iterator iterator;
+
+ /* construct/copy/destroy
+ * Default and copy ctors are in the protected section as indices are
+ * not supposed to be created on their own. No range ctor either.
+ */
+
+ ordered_index& operator=(const ordered_index& x)
+ {
+ this->final()=x.final();
+ return *this;
+ }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ ordered_index& operator=(
+ std::initializer_list<BOOST_DEDUCED_TYPENAME super::value_type> list)
+ {
+ this->final()=list;
+ return *this;
+ }
+#endif
+
+protected:
+ ordered_index(
+ const ctor_args_list& args_list,const allocator_type& al):
+ super(args_list,al){}
+
+ ordered_index(const ordered_index& x):super(x){};
+
+ ordered_index(const ordered_index& x,do_not_copy_elements_tag):
+ super(x,do_not_copy_elements_tag()){};
+};
+
+/* comparison */
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator==(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
+{
+ return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
+}
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator<(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
+{
+ return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
+}
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator!=(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
+{
+ return !(x==y);
+}
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator>(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
+{
+ return y<x;
+}
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator>=(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
+{
+ return !(x<y);
+}
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator<=(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
+{
+ return !(x>y);
+}
+
+/* specialized algorithms */
+
+template<
+ typename KeyFromValue,typename Compare,
+ typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
+>
+void swap(
+ ordered_index<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
+ ordered_index<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y)
+{
+ x.swap(y);
+}
+
+} /* namespace multi_index::detail */
+
+} /* namespace multi_index */
+
+} /* namespace boost */
+
+/* Boost.Foreach compatibility */
+
+template<
+ typename KeyFromValue,typename Compare,
+ typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
+>
+inline boost::mpl::true_* boost_foreach_is_noncopyable(
+ boost::multi_index::detail::ordered_index<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>*&,
+ boost::foreach::tag)
+{
+ return 0;
+}
+
+#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
+#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF
+
+#endif
diff --git a/boost/multi_index/detail/ord_index_impl_fwd.hpp b/boost/multi_index/detail/ord_index_impl_fwd.hpp
new file mode 100644
index 0000000000..6590ef05fd
--- /dev/null
+++ b/boost/multi_index/detail/ord_index_impl_fwd.hpp
@@ -0,0 +1,128 @@
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP
+#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+namespace boost{
+
+namespace multi_index{
+
+namespace detail{
+
+template<
+ typename KeyFromValue,typename Compare,
+ typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
+>
+class ordered_index;
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator==(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator<(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator!=(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator>(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator>=(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator<=(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
+
+template<
+ typename KeyFromValue,typename Compare,
+ typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
+>
+void swap(
+ ordered_index<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
+ ordered_index<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y);
+
+} /* namespace multi_index::detail */
+
+} /* namespace multi_index */
+
+} /* namespace boost */
+
+#endif
diff --git a/boost/multi_index/detail/ord_index_node.hpp b/boost/multi_index/detail/ord_index_node.hpp
index 60727e04ed..e7af0377fb 100644
--- a/boost/multi_index/detail/ord_index_node.hpp
+++ b/boost/multi_index/detail/ord_index_node.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -43,6 +43,7 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <cstddef>
#include <boost/detail/allocator_utilities.hpp>
+#include <boost/multi_index/detail/raw_ptr.hpp>
#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
#include <boost/mpl/and.hpp>
@@ -63,24 +64,24 @@ namespace detail{
enum ordered_index_color{red=false,black=true};
enum ordered_index_side{to_left=false,to_right=true};
-template<typename Allocator>
+template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_impl; /* fwd decl. */
-template<typename Allocator>
+template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_std_base
{
typedef typename
boost::detail::allocator::rebind_to<
Allocator,
- ordered_index_node_impl<Allocator>
- >::type::pointer pointer;
+ ordered_index_node_impl<AugmentPolicy,Allocator>
+ >::type::pointer pointer;
typedef typename
boost::detail::allocator::rebind_to<
Allocator,
- ordered_index_node_impl<Allocator>
- >::type::const_pointer const_pointer;
- typedef ordered_index_color& color_ref;
- typedef pointer& parent_ref;
+ ordered_index_node_impl<AugmentPolicy,Allocator>
+ >::type::const_pointer const_pointer;
+ typedef ordered_index_color& color_ref;
+ typedef pointer& parent_ref;
ordered_index_color& color(){return color_;}
ordered_index_color color()const{return color_;}
@@ -116,11 +117,13 @@ private:
#pragma warning(disable:4312 4311)
#endif
-template<typename Allocator>
+template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_compressed_base
{
- typedef ordered_index_node_impl<Allocator>* pointer;
- typedef const ordered_index_node_impl<Allocator>* const_pointer;
+ typedef ordered_index_node_impl<
+ AugmentPolicy,Allocator>* pointer;
+ typedef const ordered_index_node_impl<
+ AugmentPolicy,Allocator>* const_pointer;
struct color_ref
{
@@ -179,7 +182,7 @@ struct ordered_index_node_compressed_base
color_ref color(){return color_ref(&parentcolor_);}
ordered_index_color color()const
{
- return ordered_index_color(parentcolor_&std::size_t(1ul));
+ return ordered_index_color(parentcolor_&uintptr_type(1));
}
parent_ref parent(){return parent_ref(&parentcolor_);}
@@ -203,39 +206,46 @@ private:
#endif
#endif
-template<typename Allocator>
+template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_impl_base:
#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
- mpl::if_c<
- !(has_uintptr_type::value)||
- (alignment_of<ordered_index_node_compressed_base<Allocator> >::value%2)||
- !(is_same<
- typename boost::detail::allocator::rebind_to<
- Allocator,
- ordered_index_node_impl<Allocator>
- >::type::pointer,
- ordered_index_node_impl<Allocator>*>::value),
- ordered_index_node_std_base<Allocator>,
- ordered_index_node_compressed_base<Allocator>
+ AugmentPolicy::template augmented_node<
+ typename mpl::if_c<
+ !(has_uintptr_type::value)||
+ (alignment_of<
+ ordered_index_node_compressed_base<AugmentPolicy,Allocator>
+ >::value%2)||
+ !(is_same<
+ typename boost::detail::allocator::rebind_to<
+ Allocator,
+ ordered_index_node_impl<AugmentPolicy,Allocator>
+ >::type::pointer,
+ ordered_index_node_impl<AugmentPolicy,Allocator>*>::value),
+ ordered_index_node_std_base<AugmentPolicy,Allocator>,
+ ordered_index_node_compressed_base<AugmentPolicy,Allocator>
+ >::type
>::type
#else
- ordered_index_node_std_base<Allocator>
+ AugmentPolicy::template augmented_node<
+ ordered_index_node_std_base<AugmentPolicy,Allocator>
+ >::type
#endif
{};
-template<typename Allocator>
-struct ordered_index_node_impl:ordered_index_node_impl_base<Allocator>
+template<typename AugmentPolicy,typename Allocator>
+struct ordered_index_node_impl:
+ ordered_index_node_impl_base<AugmentPolicy,Allocator>
{
private:
- typedef ordered_index_node_impl_base<Allocator> super;
+ typedef ordered_index_node_impl_base<AugmentPolicy,Allocator> super;
public:
- typedef typename super::color_ref color_ref;
- typedef typename super::parent_ref parent_ref;
- typedef typename super::pointer pointer;
- typedef typename super::const_pointer const_pointer;
+ typedef typename super::color_ref color_ref;
+ typedef typename super::parent_ref parent_ref;
+ typedef typename super::pointer pointer;
+ typedef typename super::const_pointer const_pointer;
/* interoperability with bidir_node_iterator */
@@ -288,6 +298,7 @@ public:
else x->parent()->right()=y;
y->left()=x;
x->parent()=y;
+ AugmentPolicy::rotate_left(x,y);
}
static pointer minimum(pointer x)
@@ -314,6 +325,7 @@ public:
else x->parent()->left()=y;
y->right()=x;
x->parent()=y;
+ AugmentPolicy::rotate_right(x,y);
}
static void rebalance(pointer x,parent_ref root)
@@ -382,6 +394,7 @@ public:
x->parent()=position;
x->left()=pointer(0);
x->right()=pointer(0);
+ AugmentPolicy::add(x,pointer(header->parent()));
ordered_index_node_impl::rebalance(x,header->parent());
}
@@ -404,7 +417,9 @@ public:
x=y->right();
}
}
+ AugmentPolicy::remove(y,pointer(root));
if(y!=z){
+ AugmentPolicy::copy(z,y);
z->left()->parent()=y; /* relink y in place of z. y is z's successor */
y->left()=z->left();
if(y!=z->right()){
@@ -547,9 +562,10 @@ public:
#endif
};
-template<typename Super>
+template<typename AugmentPolicy,typename Super>
struct ordered_index_node_trampoline:
ordered_index_node_impl<
+ AugmentPolicy,
typename boost::detail::allocator::rebind_to<
typename Super::allocator_type,
char
@@ -557,6 +573,7 @@ struct ordered_index_node_trampoline:
>
{
typedef ordered_index_node_impl<
+ AugmentPolicy,
typename boost::detail::allocator::rebind_to<
typename Super::allocator_type,
char
@@ -564,11 +581,12 @@ struct ordered_index_node_trampoline:
> impl_type;
};
-template<typename Super>
-struct ordered_index_node:Super,ordered_index_node_trampoline<Super>
+template<typename AugmentPolicy,typename Super>
+struct ordered_index_node:
+ Super,ordered_index_node_trampoline<AugmentPolicy,Super>
{
private:
- typedef ordered_index_node_trampoline<Super> trampoline;
+ typedef ordered_index_node_trampoline<AugmentPolicy,Super> trampoline;
public:
typedef typename trampoline::impl_type impl_type;
@@ -600,14 +618,18 @@ public:
static ordered_index_node* from_impl(impl_pointer x)
{
- return static_cast<ordered_index_node*>(
- static_cast<trampoline*>(&*x));
+ return
+ static_cast<ordered_index_node*>(
+ static_cast<trampoline*>(
+ raw_ptr<impl_type*>(x)));
}
static const ordered_index_node* from_impl(const_impl_pointer x)
{
- return static_cast<const ordered_index_node*>(
- static_cast<const trampoline*>(&*x));
+ return
+ static_cast<const ordered_index_node*>(
+ static_cast<const trampoline*>(
+ raw_ptr<const impl_type*>(x)));
}
/* interoperability with bidir_node_iterator */
diff --git a/boost/multi_index/detail/raw_ptr.hpp b/boost/multi_index/detail/raw_ptr.hpp
new file mode 100644
index 0000000000..c32007435c
--- /dev/null
+++ b/boost/multi_index/detail/raw_ptr.hpp
@@ -0,0 +1,52 @@
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_DETAIL_RAW_PTR_HPP
+#define BOOST_MULTI_INDEX_DETAIL_RAW_PTR_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/mpl/bool.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost{
+
+namespace multi_index{
+
+namespace detail{
+
+/* gets the underlying pointer of a pointer-like value */
+
+template<typename RawPointer>
+inline RawPointer raw_ptr(RawPointer const& p,mpl::true_)
+{
+ return p;
+}
+
+template<typename RawPointer,typename Pointer>
+inline RawPointer raw_ptr(Pointer const& p,mpl::false_)
+{
+ return p==Pointer(0)?0:&*p;
+}
+
+template<typename RawPointer,typename Pointer>
+inline RawPointer raw_ptr(Pointer const& p)
+{
+ return raw_ptr<RawPointer>(p,is_same<RawPointer,Pointer>());
+}
+
+} /* namespace multi_index::detail */
+
+} /* namespace multi_index */
+
+} /* namespace boost */
+
+#endif
diff --git a/boost/multi_index/detail/rnd_index_node.hpp b/boost/multi_index/detail/rnd_index_node.hpp
index def057583a..ad61ea25dd 100644
--- a/boost/multi_index/detail/rnd_index_node.hpp
+++ b/boost/multi_index/detail/rnd_index_node.hpp
@@ -17,6 +17,7 @@
#include <algorithm>
#include <boost/detail/allocator_utilities.hpp>
#include <boost/integer/common_factor_rt.hpp>
+#include <boost/multi_index/detail/raw_ptr.hpp>
#include <cstddef>
#include <functional>
@@ -219,14 +220,18 @@ public:
static random_access_index_node* from_impl(impl_pointer x)
{
- return static_cast<random_access_index_node*>(
- static_cast<trampoline*>(&*x));
+ return
+ static_cast<random_access_index_node*>(
+ static_cast<trampoline*>(
+ raw_ptr<impl_type*>(x)));
}
static const random_access_index_node* from_impl(const_impl_pointer x)
{
- return static_cast<const random_access_index_node*>(
- static_cast<const trampoline*>(&*x));
+ return
+ static_cast<const random_access_index_node*>(
+ static_cast<const trampoline*>(
+ raw_ptr<const impl_type*>(x)));
}
/* interoperability with rnd_node_iterator */
diff --git a/boost/multi_index/detail/rnd_index_ops.hpp b/boost/multi_index/detail/rnd_index_ops.hpp
index d05386d747..f5e76e4441 100644
--- a/boost/multi_index/detail/rnd_index_ops.hpp
+++ b/boost/multi_index/detail/rnd_index_ops.hpp
@@ -16,7 +16,6 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/multi_index/detail/rnd_index_ptr_array.hpp>
-#include <functional>
namespace boost{
@@ -123,11 +122,12 @@ void random_access_index_inplace_merge(
/* auxiliary stuff */
template<typename Node,typename Compare>
-struct random_access_index_sort_compare:
- std::binary_function<
- typename Node::impl_pointer,
- typename Node::impl_pointer,bool>
+struct random_access_index_sort_compare
{
+ typedef typename Node::impl_pointer first_argument_type;
+ typedef typename Node::impl_pointer second_argument_type;
+ typedef bool result_type;
+
random_access_index_sort_compare(Compare comp_=Compare()):comp(comp_){}
bool operator()(
diff --git a/boost/multi_index/detail/rnk_index_ops.hpp b/boost/multi_index/detail/rnk_index_ops.hpp
new file mode 100644
index 0000000000..275642236b
--- /dev/null
+++ b/boost/multi_index/detail/rnk_index_ops.hpp
@@ -0,0 +1,300 @@
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP
+#define BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/mpl/and.hpp>
+#include <boost/multi_index/detail/promotes_arg.hpp>
+#include <cstddef>
+#include <utility>
+
+namespace boost{
+
+namespace multi_index{
+
+namespace detail{
+
+/* Common code for ranked_index memfuns having templatized and
+ * non-templatized versions.
+ */
+
+template<typename Pointer>
+inline std::size_t ranked_node_size(Pointer x)
+{
+ return x!=Pointer(0)?x->size:0;
+}
+
+template<typename Pointer>
+inline Pointer ranked_index_nth(std::size_t n,Pointer end_)
+{
+ Pointer top=end_->parent();
+ if(top==Pointer(0)||n>=top->size)return end_;
+
+ for(;;){
+ std::size_t s=ranked_node_size(top->left());
+ if(n==s)return top;
+ if(n<s)top=top->left();
+ else{
+ top=top->right();
+ n-=s+1;
+ }
+ }
+}
+
+template<typename Pointer>
+inline std::size_t ranked_index_rank(Pointer x,Pointer end_)
+{
+ Pointer top=end_->parent();
+ if(top==Pointer(0))return 0;
+ if(x==end_)return top->size;
+
+ std::size_t s=ranked_node_size(x->left());
+ while(x!=top){
+ Pointer z=x->parent();
+ if(x==z->right()){
+ s+=ranked_node_size(z->left())+1;
+ }
+ x=z;
+ }
+ return s;
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::size_t ranked_index_find_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp)
+{
+ typedef typename KeyFromValue::result_type key_type;
+
+ return ranked_index_find_rank(
+ top,y,key,x,comp,
+ mpl::and_<
+ promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>,
+ promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleCompare
+>
+inline std::size_t ranked_index_find_rank(
+ Node* top,Node* y,const KeyFromValue& key,
+ const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
+ const CompatibleCompare& comp,mpl::true_)
+{
+ return ranked_index_find_rank(top,y,key,x,comp,mpl::false_());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::size_t ranked_index_find_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp,mpl::false_)
+{
+ if(!top)return 0;
+
+ std::size_t s=top->size,
+ s0=s;
+ Node* y0=y;
+
+ do{
+ if(!comp(key(top->value()),x)){
+ y=top;
+ s-=ranked_node_size(y->right())+1;
+ top=Node::from_impl(top->left());
+ }
+ else top=Node::from_impl(top->right());
+ }while(top);
+
+ return (y==y0||comp(x,key(y->value())))?s0:s;
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::size_t ranked_index_lower_bound_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp)
+{
+ typedef typename KeyFromValue::result_type key_type;
+
+ return ranked_index_lower_bound_rank(
+ top,y,key,x,comp,
+ promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey>());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleCompare
+>
+inline std::size_t ranked_index_lower_bound_rank(
+ Node* top,Node* y,const KeyFromValue& key,
+ const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
+ const CompatibleCompare& comp,mpl::true_)
+{
+ return ranked_index_lower_bound_rank(top,y,key,x,comp,mpl::false_());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::size_t ranked_index_lower_bound_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp,mpl::false_)
+{
+ if(!top)return 0;
+
+ std::size_t s=top->size;
+
+ do{
+ if(!comp(key(top->value()),x)){
+ y=top;
+ s-=ranked_node_size(y->right())+1;
+ top=Node::from_impl(top->left());
+ }
+ else top=Node::from_impl(top->right());
+ }while(top);
+
+ return s;
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::size_t ranked_index_upper_bound_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp)
+{
+ typedef typename KeyFromValue::result_type key_type;
+
+ return ranked_index_upper_bound_rank(
+ top,y,key,x,comp,
+ promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleCompare
+>
+inline std::size_t ranked_index_upper_bound_rank(
+ Node* top,Node* y,const KeyFromValue& key,
+ const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
+ const CompatibleCompare& comp,mpl::true_)
+{
+ return ranked_index_upper_bound_rank(top,y,key,x,comp,mpl::false_());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::size_t ranked_index_upper_bound_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp,mpl::false_)
+{
+ if(!top)return 0;
+
+ std::size_t s=top->size;
+
+ do{
+ if(comp(x,key(top->value()))){
+ y=top;
+ s-=ranked_node_size(y->right())+1;
+ top=Node::from_impl(top->left());
+ }
+ else top=Node::from_impl(top->right());
+ }while(top);
+
+ return s;
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp)
+{
+ typedef typename KeyFromValue::result_type key_type;
+
+ return ranked_index_equal_range_rank(
+ top,y,key,x,comp,
+ mpl::and_<
+ promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>,
+ promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleCompare
+>
+inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
+ Node* top,Node* y,const KeyFromValue& key,
+ const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
+ const CompatibleCompare& comp,mpl::true_)
+{
+ return ranked_index_equal_range_rank(top,y,key,x,comp,mpl::false_());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp,mpl::false_)
+{
+ if(!top)return std::pair<std::size_t,std::size_t>(0,0);
+
+ std::size_t s=top->size;
+
+ do{
+ if(comp(key(top->value()),x)){
+ top=Node::from_impl(top->right());
+ }
+ else if(comp(x,key(top->value()))){
+ y=top;
+ s-=ranked_node_size(y->right())+1;
+ top=Node::from_impl(top->left());
+ }
+ else{
+ return std::pair<std::size_t,std::size_t>(
+ s-top->size+
+ ranked_index_lower_bound_rank(
+ Node::from_impl(top->left()),top,key,x,comp,mpl::false_()),
+ s-ranked_node_size(top->right())+
+ ranked_index_upper_bound_rank(
+ Node::from_impl(top->right()),y,key,x,comp,mpl::false_()));
+ }
+ }while(top);
+
+ return std::pair<std::size_t,std::size_t>(s,s);
+}
+
+} /* namespace multi_index::detail */
+
+} /* namespace multi_index */
+
+} /* namespace boost */
+
+#endif
diff --git a/boost/multi_index/detail/seq_index_node.hpp b/boost/multi_index/detail/seq_index_node.hpp
index 5cb467650f..85b345af93 100644
--- a/boost/multi_index/detail/seq_index_node.hpp
+++ b/boost/multi_index/detail/seq_index_node.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -16,6 +16,7 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/detail/allocator_utilities.hpp>
+#include <boost/multi_index/detail/raw_ptr.hpp>
namespace boost{
@@ -176,14 +177,18 @@ public:
static sequenced_index_node* from_impl(impl_pointer x)
{
- return static_cast<sequenced_index_node*>(
- static_cast<trampoline*>(&*x));
+ return
+ static_cast<sequenced_index_node*>(
+ static_cast<trampoline*>(
+ raw_ptr<impl_type*>(x)));
}
static const sequenced_index_node* from_impl(const_impl_pointer x)
{
- return static_cast<const sequenced_index_node*>(
- static_cast<const trampoline*>(&*x));
+ return
+ static_cast<const sequenced_index_node*>(
+ static_cast<const trampoline*>(
+ raw_ptr<const impl_type*>(x)));
}
/* interoperability with bidir_node_iterator */
diff --git a/boost/multi_index/detail/seq_index_ops.hpp b/boost/multi_index/detail/seq_index_ops.hpp
index 56da408342..a3c2bc1f04 100644
--- a/boost/multi_index/detail/seq_index_ops.hpp
+++ b/boost/multi_index/detail/seq_index_ops.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -135,7 +135,7 @@ void sequenced_index_sort(Node* header,Compare comp)
>::type carry_spc_type;
carry_spc_type carry_spc;
impl_type& carry=
- *static_cast<impl_type*>(static_cast<void*>(&carry_spc));
+ *reinterpret_cast<impl_type*>(&carry_spc);
typedef typename aligned_storage<
sizeof(
impl_type
@@ -147,7 +147,7 @@ void sequenced_index_sort(Node* header,Compare comp)
>::type counter_spc_type;
counter_spc_type counter_spc;
impl_type* counter=
- static_cast<impl_type*>(static_cast<void*>(&counter_spc));
+ reinterpret_cast<impl_type*>(&counter_spc);
std::size_t fill=0;
carry.prior()=carry.next()=static_cast<impl_pointer>(&carry);
diff --git a/boost/multi_index/detail/value_compare.hpp b/boost/multi_index/detail/value_compare.hpp
index 1fde20549f..ac42e8779a 100644
--- a/boost/multi_index/detail/value_compare.hpp
+++ b/boost/multi_index/detail/value_compare.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -15,7 +15,6 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/call_traits.hpp>
-#include <functional>
namespace boost{
@@ -24,8 +23,12 @@ namespace multi_index{
namespace detail{
template<typename Value,typename KeyFromValue,typename Compare>
-struct value_comparison:std::binary_function<Value,Value,bool>
+struct value_comparison
{
+ typedef Value first_argument_type;
+ typedef Value second_argument_type;
+ typedef bool result_type;
+
value_comparison(
const KeyFromValue& key_=KeyFromValue(),const Compare& comp_=Compare()):
key(key_),comp(comp_)
diff --git a/boost/multi_index/global_fun.hpp b/boost/multi_index/global_fun.hpp
index 9333f5891e..3ae2afdafc 100644
--- a/boost/multi_index/global_fun.hpp
+++ b/boost/multi_index/global_fun.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -43,7 +43,7 @@ namespace detail{
* pointer to T we mean a type P such that, given a p of Type P
* *...n...*x is convertible to T&, for some n>=1.
* Examples of chained pointers are raw and smart pointers, iterators and
- * arbitrary combinations of these (vg. T** or auto_ptr<T*>.)
+ * arbitrary combinations of these (vg. T** or unique_ptr<T*>.)
*/
template<class Value,typename Type,Type (*PtrToFunction)(Value)>
diff --git a/boost/multi_index/identity.hpp b/boost/multi_index/identity.hpp
index 1dbaf3b220..370deb928b 100644
--- a/boost/multi_index/identity.hpp
+++ b/boost/multi_index/identity.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -39,7 +39,7 @@ namespace detail{
* mean a type P such that, given a p of type P
* *...n...*x is convertible to Type&, for some n>=1.
* Examples of chained pointers are raw and smart pointers, iterators and
- * arbitrary combinations of these (vg. Type** or auto_ptr<Type*>.)
+ * arbitrary combinations of these (vg. Type** or unique_ptr<Type*>.)
*/
template<typename Type>
diff --git a/boost/multi_index/mem_fun.hpp b/boost/multi_index/mem_fun.hpp
index 71fc217024..111c386c5f 100644
--- a/boost/multi_index/mem_fun.hpp
+++ b/boost/multi_index/mem_fun.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -36,7 +36,7 @@ namespace multi_index{
* to T we mean a type P such that, given a p of Type P
* *...n...*x is convertible to T&, for some n>=1.
* Examples of chained pointers are raw and smart pointers, iterators and
- * arbitrary combinations of these (vg. T** or auto_ptr<T*>.)
+ * arbitrary combinations of these (vg. T** or unique_ptr<T*>.)
*/
template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const>
diff --git a/boost/multi_index/member.hpp b/boost/multi_index/member.hpp
index 192cf1be88..a8e645074a 100644
--- a/boost/multi_index/member.hpp
+++ b/boost/multi_index/member.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -38,7 +38,7 @@ namespace detail{
* a type P such that, given a p of Type P
* *...n...*x is convertible to T&, for some n>=1.
* Examples of chained pointers are raw and smart pointers, iterators and
- * arbitrary combinations of these (vg. T** or auto_ptr<T*>.)
+ * arbitrary combinations of these (vg. T** or unique_ptr<T*>.)
*/
template<class Class,typename Type,Type Class::*PtrToMember>
diff --git a/boost/multi_index/ordered_index.hpp b/boost/multi_index/ordered_index.hpp
index 267f1538fb..5bcd69de8c 100644
--- a/boost/multi_index/ordered_index.hpp
+++ b/boost/multi_index/ordered_index.hpp
@@ -1,36 +1,9 @@
-/* Copyright 2003-2014 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
- *
- * The internal implementation of red-black trees is based on that of SGI STL
- * stl_tree.h file:
- *
- * Copyright (c) 1996,1997
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
*/
#ifndef BOOST_MULTI_INDEX_ORDERED_INDEX_HPP
@@ -41,56 +14,8 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
-#include <algorithm>
-#include <boost/call_traits.hpp>
-#include <boost/detail/no_exceptions_support.hpp>
-#include <boost/detail/workaround.hpp>
-#include <boost/foreach_fwd.hpp>
-#include <boost/iterator/reverse_iterator.hpp>
-#include <boost/move/core.hpp>
-#include <boost/mpl/bool.hpp>
-#include <boost/mpl/if.hpp>
-#include <boost/mpl/push_front.hpp>
-#include <boost/multi_index/detail/access_specifier.hpp>
-#include <boost/multi_index/detail/bidir_node_iterator.hpp>
-#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
-#include <boost/multi_index/detail/index_node_base.hpp>
-#include <boost/multi_index/detail/modify_key_adaptor.hpp>
-#include <boost/multi_index/detail/ord_index_node.hpp>
-#include <boost/multi_index/detail/ord_index_ops.hpp>
-#include <boost/multi_index/detail/safe_mode.hpp>
-#include <boost/multi_index/detail/scope_guard.hpp>
-#include <boost/multi_index/detail/unbounded.hpp>
-#include <boost/multi_index/detail/value_compare.hpp>
-#include <boost/multi_index/detail/vartempl_support.hpp>
+#include <boost/multi_index/detail/ord_index_impl.hpp>
#include <boost/multi_index/ordered_index_fwd.hpp>
-#include <boost/ref.hpp>
-#include <boost/tuple/tuple.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <utility>
-
-#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
-#include <initializer_list>
-#endif
-
-#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
-#include <boost/archive/archive_exception.hpp>
-#include <boost/bind.hpp>
-#include <boost/multi_index/detail/duplicates_iterator.hpp>
-#include <boost/throw_exception.hpp>
-#endif
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
-#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \
- detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
- detail::make_obj_guard(x,&ordered_index::check_invariant_); \
- BOOST_JOIN(check_invariant_,__LINE__).touch();
-#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this)
-#else
-#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x)
-#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
-#endif
namespace boost{
@@ -98,1357 +23,36 @@ namespace multi_index{
namespace detail{
-/* ordered_index adds a layer of ordered indexing to a given Super */
-
-/* Most of the implementation of unique and non-unique indices is
- * shared. We tell from one another on instantiation time by using
- * these tags.
- */
-
-struct ordered_unique_tag{};
-struct ordered_non_unique_tag{};
-
-template<
- typename KeyFromValue,typename Compare,
- typename SuperMeta,typename TagList,typename Category
->
-class ordered_index:
- BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- ,public safe_mode::safe_container<
- ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category> >
-#endif
-
-{
-#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
- BOOST_WORKAROUND(__MWERKS__,<=0x3003)
-/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
- * lifetime of const references bound to temporaries --precisely what
- * scopeguards are.
- */
-
-#pragma parse_mfunc_templ off
-#endif
-
- typedef typename SuperMeta::type super;
-
-protected:
- typedef ordered_index_node<
- typename super::node_type> node_type;
-
-private:
- typedef typename node_type::impl_type node_impl_type;
- typedef typename node_impl_type::pointer node_impl_pointer;
-
-public:
- /* types */
-
- typedef typename KeyFromValue::result_type key_type;
- typedef typename node_type::value_type value_type;
- typedef KeyFromValue key_from_value;
- typedef Compare key_compare;
- typedef value_comparison<
- value_type,KeyFromValue,Compare> value_compare;
- typedef tuple<key_from_value,key_compare> ctor_args;
- typedef typename super::final_allocator_type allocator_type;
- typedef typename allocator_type::reference reference;
- typedef typename allocator_type::const_reference const_reference;
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- typedef safe_mode::safe_iterator<
- bidir_node_iterator<node_type>,
- ordered_index> iterator;
-#else
- typedef bidir_node_iterator<node_type> iterator;
-#endif
-
- typedef iterator const_iterator;
-
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
- typedef typename allocator_type::pointer pointer;
- typedef typename allocator_type::const_pointer const_pointer;
- typedef typename
- boost::reverse_iterator<iterator> reverse_iterator;
- typedef typename
- boost::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef TagList tag_list;
-
-protected:
- typedef typename super::final_node_type final_node_type;
- typedef tuples::cons<
- ctor_args,
- typename super::ctor_args_list> ctor_args_list;
- typedef typename mpl::push_front<
- typename super::index_type_list,
- ordered_index>::type index_type_list;
- typedef typename mpl::push_front<
- typename super::iterator_type_list,
- iterator>::type iterator_type_list;
- typedef typename mpl::push_front<
- typename super::const_iterator_type_list,
- const_iterator>::type const_iterator_type_list;
- typedef typename super::copy_map_type copy_map_type;
-
-#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
- typedef typename super::index_saver_type index_saver_type;
- typedef typename super::index_loader_type index_loader_type;
-#endif
-
-private:
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- typedef safe_mode::safe_container<ordered_index> safe_super;
-#endif
-
- typedef typename call_traits<
- value_type>::param_type value_param_type;
- typedef typename call_traits<
- key_type>::param_type key_param_type;
-
- /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
- * expansion.
- */
-
- typedef std::pair<iterator,bool> emplace_return_type;
-
-public:
-
- /* construct/copy/destroy
- * Default and copy ctors are in the protected section as indices are
- * not supposed to be created on their own. No range ctor either.
- */
-
- ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& operator=(
- const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
- {
- this->final()=x.final();
- return *this;
- }
-
-#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
- ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& operator=(
- std::initializer_list<value_type> list)
- {
- this->final()=list;
- return *this;
- }
-#endif
-
- allocator_type get_allocator()const BOOST_NOEXCEPT
- {
- return this->final().get_allocator();
- }
-
- /* iterators */
-
- iterator
- begin()BOOST_NOEXCEPT{return make_iterator(leftmost());}
- const_iterator
- begin()const BOOST_NOEXCEPT{return make_iterator(leftmost());}
- iterator
- end()BOOST_NOEXCEPT{return make_iterator(header());}
- const_iterator
- end()const BOOST_NOEXCEPT{return make_iterator(header());}
- reverse_iterator
- rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
- const_reverse_iterator
- rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
- reverse_iterator
- rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
- const_reverse_iterator
- rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
- const_iterator
- cbegin()const BOOST_NOEXCEPT{return begin();}
- const_iterator
- cend()const BOOST_NOEXCEPT{return end();}
- const_reverse_iterator
- crbegin()const BOOST_NOEXCEPT{return rbegin();}
- const_reverse_iterator
- crend()const BOOST_NOEXCEPT{return rend();}
-
- iterator iterator_to(const value_type& x)
- {
- return make_iterator(node_from_value<node_type>(&x));
- }
-
- const_iterator iterator_to(const value_type& x)const
- {
- return make_iterator(node_from_value<node_type>(&x));
- }
-
- /* capacity */
-
- bool empty()const BOOST_NOEXCEPT{return this->final_empty_();}
- size_type size()const BOOST_NOEXCEPT{return this->final_size_();}
- size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();}
-
- /* modifiers */
-
- BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
- emplace_return_type,emplace,emplace_impl)
-
- BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
- iterator,emplace_hint,emplace_hint_impl,iterator,position)
-
- std::pair<iterator,bool> insert(const value_type& x)
- {
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- std::pair<final_node_type*,bool> p=this->final_insert_(x);
- return std::pair<iterator,bool>(make_iterator(p.first),p.second);
- }
-
- std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
- {
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
- return std::pair<iterator,bool>(make_iterator(p.first),p.second);
- }
-
- iterator insert(iterator position,const value_type& x)
- {
- BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- std::pair<final_node_type*,bool> p=this->final_insert_(
- x,static_cast<final_node_type*>(position.get_node()));
- return make_iterator(p.first);
- }
-
- iterator insert(iterator position,BOOST_RV_REF(value_type) x)
- {
- BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- std::pair<final_node_type*,bool> p=this->final_insert_rv_(
- x,static_cast<final_node_type*>(position.get_node()));
- return make_iterator(p.first);
- }
-
- template<typename InputIterator>
- void insert(InputIterator first,InputIterator last)
- {
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- node_type* hint=header(); /* end() */
- for(;first!=last;++first){
- hint=this->final_insert_ref_(
- *first,static_cast<final_node_type*>(hint)).first;
- node_type::increment(hint);
- }
- }
-
-#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
- void insert(std::initializer_list<value_type> list)
- {
- insert(list.begin(),list.end());
- }
-#endif
-
- iterator erase(iterator position)
- {
- BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
- return position;
- }
-
- size_type erase(key_param_type x)
- {
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- std::pair<iterator,iterator> p=equal_range(x);
- size_type s=0;
- while(p.first!=p.second){
- p.first=erase(p.first);
- ++s;
- }
- return s;
- }
-
- iterator erase(iterator first,iterator last)
- {
- BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
- BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
- BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
- BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
- BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- while(first!=last){
- first=erase(first);
- }
- return first;
- }
-
- bool replace(iterator position,const value_type& x)
- {
- BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- return this->final_replace_(
- x,static_cast<final_node_type*>(position.get_node()));
- }
-
- bool replace(iterator position,BOOST_RV_REF(value_type) x)
- {
- BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- return this->final_replace_rv_(
- x,static_cast<final_node_type*>(position.get_node()));
- }
-
- template<typename Modifier>
- bool modify(iterator position,Modifier mod)
- {
- BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- /* MSVC++ 6.0 optimizer on safe mode code chokes if this
- * this is not added. Left it for all compilers as it does no
- * harm.
- */
-
- position.detach();
-#endif
-
- return this->final_modify_(
- mod,static_cast<final_node_type*>(position.get_node()));
- }
-
- template<typename Modifier,typename Rollback>
- bool modify(iterator position,Modifier mod,Rollback back_)
- {
- BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- /* MSVC++ 6.0 optimizer on safe mode code chokes if this
- * this is not added. Left it for all compilers as it does no
- * harm.
- */
-
- position.detach();
-#endif
-
- return this->final_modify_(
- mod,back_,static_cast<final_node_type*>(position.get_node()));
- }
-
- template<typename Modifier>
- bool modify_key(iterator position,Modifier mod)
- {
- BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- return modify(
- position,modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key));
- }
-
- template<typename Modifier,typename Rollback>
- bool modify_key(iterator position,Modifier mod,Rollback back_)
- {
- BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- return modify(
- position,
- modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key),
- modify_key_adaptor<Rollback,value_type,KeyFromValue>(back_,key));
- }
-
- void swap(ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
- {
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x);
- this->final_swap_(x.final());
- }
-
- void clear()BOOST_NOEXCEPT
- {
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- this->final_clear_();
- }
-
- /* observers */
-
- key_from_value key_extractor()const{return key;}
- key_compare key_comp()const{return comp_;}
- value_compare value_comp()const{return value_compare(key,comp_);}
-
- /* set operations */
-
- /* Internally, these ops rely on const_iterator being the same
- * type as iterator.
- */
-
- template<typename CompatibleKey>
- iterator find(const CompatibleKey& x)const
- {
- return make_iterator(ordered_index_find(root(),header(),key,x,comp_));
- }
-
- template<typename CompatibleKey,typename CompatibleCompare>
- iterator find(
- const CompatibleKey& x,const CompatibleCompare& comp)const
- {
- return make_iterator(ordered_index_find(root(),header(),key,x,comp));
- }
-
- template<typename CompatibleKey>
- size_type count(const CompatibleKey& x)const
- {
- return count(x,comp_);
- }
-
- template<typename CompatibleKey,typename CompatibleCompare>
- size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const
- {
- std::pair<iterator,iterator> p=equal_range(x,comp);
- size_type n=std::distance(p.first,p.second);
- return n;
- }
-
- template<typename CompatibleKey>
- iterator lower_bound(const CompatibleKey& x)const
- {
- return make_iterator(
- ordered_index_lower_bound(root(),header(),key,x,comp_));
- }
-
- template<typename CompatibleKey,typename CompatibleCompare>
- iterator lower_bound(
- const CompatibleKey& x,const CompatibleCompare& comp)const
- {
- return make_iterator(
- ordered_index_lower_bound(root(),header(),key,x,comp));
- }
-
- template<typename CompatibleKey>
- iterator upper_bound(const CompatibleKey& x)const
- {
- return make_iterator(
- ordered_index_upper_bound(root(),header(),key,x,comp_));
- }
-
- template<typename CompatibleKey,typename CompatibleCompare>
- iterator upper_bound(
- const CompatibleKey& x,const CompatibleCompare& comp)const
- {
- return make_iterator(
- ordered_index_upper_bound(root(),header(),key,x,comp));
- }
-
- template<typename CompatibleKey>
- std::pair<iterator,iterator> equal_range(
- const CompatibleKey& x)const
- {
- std::pair<node_type*,node_type*> p=
- ordered_index_equal_range(root(),header(),key,x,comp_);
- return std::pair<iterator,iterator>(
- make_iterator(p.first),make_iterator(p.second));
- }
-
- template<typename CompatibleKey,typename CompatibleCompare>
- std::pair<iterator,iterator> equal_range(
- const CompatibleKey& x,const CompatibleCompare& comp)const
- {
- std::pair<node_type*,node_type*> p=
- ordered_index_equal_range(root(),header(),key,x,comp);
- return std::pair<iterator,iterator>(
- make_iterator(p.first),make_iterator(p.second));
- }
-
- /* range */
-
- template<typename LowerBounder,typename UpperBounder>
- std::pair<iterator,iterator>
- range(LowerBounder lower,UpperBounder upper)const
- {
- typedef typename mpl::if_<
- is_same<LowerBounder,unbounded_type>,
- BOOST_DEDUCED_TYPENAME mpl::if_<
- is_same<UpperBounder,unbounded_type>,
- both_unbounded_tag,
- lower_unbounded_tag
- >::type,
- BOOST_DEDUCED_TYPENAME mpl::if_<
- is_same<UpperBounder,unbounded_type>,
- upper_unbounded_tag,
- none_unbounded_tag
- >::type
- >::type dispatch;
-
- return range(lower,upper,dispatch());
- }
-
-BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
- ordered_index(const ctor_args_list& args_list,const allocator_type& al):
- super(args_list.get_tail(),al),
- key(tuples::get<0>(args_list.get_head())),
- comp_(tuples::get<1>(args_list.get_head()))
- {
- empty_initialize();
- }
-
- ordered_index(
- const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x):
- super(x),
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- safe_super(),
-#endif
-
- key(x.key),
- comp_(x.comp_)
- {
- /* Copy ctor just takes the key and compare objects from x. The rest is
- * done in a subsequent call to copy_().
- */
- }
-
- ordered_index(
- const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x,
- do_not_copy_elements_tag):
- super(x,do_not_copy_elements_tag()),
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- safe_super(),
-#endif
-
- key(x.key),
- comp_(x.comp_)
- {
- empty_initialize();
- }
-
- ~ordered_index()
- {
- /* the container is guaranteed to be empty by now */
- }
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- iterator make_iterator(node_type* node){return iterator(node,this);}
- const_iterator make_iterator(node_type* node)const
- {return const_iterator(node,const_cast<ordered_index*>(this));}
-#else
- iterator make_iterator(node_type* node){return iterator(node);}
- const_iterator make_iterator(node_type* node)const
- {return const_iterator(node);}
-#endif
-
- void copy_(
- const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x,
- const copy_map_type& map)
- {
- if(!x.root()){
- empty_initialize();
- }
- else{
- header()->color()=x.header()->color();
-
- node_type* root_cpy=map.find(static_cast<final_node_type*>(x.root()));
- header()->parent()=root_cpy->impl();
-
- node_type* leftmost_cpy=map.find(
- static_cast<final_node_type*>(x.leftmost()));
- header()->left()=leftmost_cpy->impl();
+/* no augment policy for plain ordered indices */
- node_type* rightmost_cpy=map.find(
- static_cast<final_node_type*>(x.rightmost()));
- header()->right()=rightmost_cpy->impl();
-
- typedef typename copy_map_type::const_iterator copy_map_iterator;
- for(copy_map_iterator it=map.begin(),it_end=map.end();it!=it_end;++it){
- node_type* org=it->first;
- node_type* cpy=it->second;
-
- cpy->color()=org->color();
-
- node_impl_pointer parent_org=org->parent();
- if(parent_org==node_impl_pointer(0))cpy->parent()=node_impl_pointer(0);
- else{
- node_type* parent_cpy=map.find(
- static_cast<final_node_type*>(node_type::from_impl(parent_org)));
- cpy->parent()=parent_cpy->impl();
- if(parent_org->left()==org->impl()){
- parent_cpy->left()=cpy->impl();
- }
- else if(parent_org->right()==org->impl()){
- /* header() does not satisfy this nor the previous check */
- parent_cpy->right()=cpy->impl();
- }
- }
-
- if(org->left()==node_impl_pointer(0))
- cpy->left()=node_impl_pointer(0);
- if(org->right()==node_impl_pointer(0))
- cpy->right()=node_impl_pointer(0);
- }
- }
-
- super::copy_(x,map);
- }
-
- template<typename Variant>
- final_node_type* insert_(
- value_param_type v,final_node_type*& x,Variant variant)
- {
- link_info inf;
- if(!link_point(key(v),inf,Category())){
- return static_cast<final_node_type*>(node_type::from_impl(inf.pos));
- }
-
- final_node_type* res=super::insert_(v,x,variant);
- if(res==x){
- node_impl_type::link(
- static_cast<node_type*>(x)->impl(),inf.side,inf.pos,header()->impl());
- }
- return res;
- }
-
- template<typename Variant>
- final_node_type* insert_(
- value_param_type v,node_type* position,final_node_type*& x,Variant variant)
- {
- link_info inf;
- if(!hinted_link_point(key(v),position,inf,Category())){
- return static_cast<final_node_type*>(node_type::from_impl(inf.pos));
- }
-
- final_node_type* res=super::insert_(v,position,x,variant);
- if(res==x){
- node_impl_type::link(
- static_cast<node_type*>(x)->impl(),inf.side,inf.pos,header()->impl());
- }
- return res;
- }
-
- void erase_(node_type* x)
- {
- node_impl_type::rebalance_for_erase(
- x->impl(),header()->parent(),header()->left(),header()->right());
- super::erase_(x);
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- detach_iterators(x);
-#endif
- }
-
- void delete_all_nodes_()
- {
- delete_all_nodes(root());
- }
-
- void clear_()
- {
- super::clear_();
- empty_initialize();
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- safe_super::detach_dereferenceable_iterators();
-#endif
- }
-
- void swap_(ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
- {
- std::swap(key,x.key);
- std::swap(comp_,x.comp_);
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- safe_super::swap(x);
-#endif
-
- super::swap_(x);
- }
-
- void swap_elements_(
- ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
- {
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- safe_super::swap(x);
-#endif
-
- super::swap_elements_(x);
- }
-
- template<typename Variant>
- bool replace_(value_param_type v,node_type* x,Variant variant)
- {
- if(in_place(v,x,Category())){
- return super::replace_(v,x,variant);
- }
-
- node_type* next=x;
- node_type::increment(next);
-
- node_impl_type::rebalance_for_erase(
- x->impl(),header()->parent(),header()->left(),header()->right());
-
- BOOST_TRY{
- link_info inf;
- if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){
- node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
- return true;
- }
- node_impl_type::restore(x->impl(),next->impl(),header()->impl());
- return false;
- }
- BOOST_CATCH(...){
- node_impl_type::restore(x->impl(),next->impl(),header()->impl());
- BOOST_RETHROW;
- }
- BOOST_CATCH_END
- }
-
- bool modify_(node_type* x)
- {
- bool b;
- BOOST_TRY{
- b=in_place(x->value(),x,Category());
- }
- BOOST_CATCH(...){
- erase_(x);
- BOOST_RETHROW;
- }
- BOOST_CATCH_END
- if(!b){
- node_impl_type::rebalance_for_erase(
- x->impl(),header()->parent(),header()->left(),header()->right());
- BOOST_TRY{
- link_info inf;
- if(!link_point(key(x->value()),inf,Category())){
- super::erase_(x);
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- detach_iterators(x);
-#endif
- return false;
- }
- node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
- }
- BOOST_CATCH(...){
- super::erase_(x);
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- detach_iterators(x);
-#endif
-
- BOOST_RETHROW;
- }
- BOOST_CATCH_END
- }
-
- BOOST_TRY{
- if(!super::modify_(x)){
- node_impl_type::rebalance_for_erase(
- x->impl(),header()->parent(),header()->left(),header()->right());
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- detach_iterators(x);
-#endif
-
- return false;
- }
- else return true;
- }
- BOOST_CATCH(...){
- node_impl_type::rebalance_for_erase(
- x->impl(),header()->parent(),header()->left(),header()->right());
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- detach_iterators(x);
-#endif
-
- BOOST_RETHROW;
- }
- BOOST_CATCH_END
- }
-
- bool modify_rollback_(node_type* x)
+struct null_augment_policy
+{
+ template<typename OrderedIndexImpl>
+ struct augmented_interface
{
- if(in_place(x->value(),x,Category())){
- return super::modify_rollback_(x);
- }
-
- node_type* next=x;
- node_type::increment(next);
-
- node_impl_type::rebalance_for_erase(
- x->impl(),header()->parent(),header()->left(),header()->right());
-
- BOOST_TRY{
- link_info inf;
- if(link_point(key(x->value()),inf,Category())&&
- super::modify_rollback_(x)){
- node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
- return true;
- }
- node_impl_type::restore(x->impl(),next->impl(),header()->impl());
- return false;
- }
- BOOST_CATCH(...){
- node_impl_type::restore(x->impl(),next->impl(),header()->impl());
- BOOST_RETHROW;
- }
- BOOST_CATCH_END
- }
-
-#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
- /* serialization */
+ typedef OrderedIndexImpl type;
+ };
- template<typename Archive>
- void save_(
- Archive& ar,const unsigned int version,const index_saver_type& sm)const
+ template<typename OrderedIndexNodeImpl>
+ struct augmented_node
{
- save_(ar,version,sm,Category());
- }
+ typedef OrderedIndexNodeImpl type;
+ };
- template<typename Archive>
- void load_(Archive& ar,const unsigned int version,const index_loader_type& lm)
- {
- load_(ar,version,lm,Category());
- }
-#endif
+ template<typename Pointer> static void add(Pointer,Pointer){}
+ template<typename Pointer> static void remove(Pointer,Pointer){}
+ template<typename Pointer> static void copy(Pointer,Pointer){}
+ template<typename Pointer> static void rotate_left(Pointer,Pointer){}
+ template<typename Pointer> static void rotate_right(Pointer,Pointer){}
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
/* invariant stuff */
- bool invariant_()const
- {
- if(size()==0||begin()==end()){
- if(size()!=0||begin()!=end()||
- header()->left()!=header()->impl()||
- header()->right()!=header()->impl())return false;
- }
- else{
- if((size_type)std::distance(begin(),end())!=size())return false;
-
- std::size_t len=node_impl_type::black_count(
- leftmost()->impl(),root()->impl());
- for(const_iterator it=begin(),it_end=end();it!=it_end;++it){
- node_type* x=it.get_node();
- node_type* left_x=node_type::from_impl(x->left());
- node_type* right_x=node_type::from_impl(x->right());
-
- if(x->color()==red){
- if((left_x&&left_x->color()==red)||
- (right_x&&right_x->color()==red))return false;
- }
- if(left_x&&comp_(key(x->value()),key(left_x->value())))return false;
- if(right_x&&comp_(key(right_x->value()),key(x->value())))return false;
- if(!left_x&&!right_x&&
- node_impl_type::black_count(x->impl(),root()->impl())!=len)
- return false;
- }
-
- if(leftmost()->impl()!=node_impl_type::minimum(root()->impl()))
- return false;
- if(rightmost()->impl()!=node_impl_type::maximum(root()->impl()))
- return false;
- }
+ template<typename Pointer> static bool invariant(Pointer){return true;}
- return super::invariant_();
- }
-
-
- /* This forwarding function eases things for the boost::mem_fn construct
- * in BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT. Actually,
- * final_check_invariant is already an inherited member function of
- * ordered_index.
- */
- void check_invariant_()const{this->final_check_invariant_();}
-#endif
-
-private:
- node_type* header()const{return this->final_header();}
- node_type* root()const{return node_type::from_impl(header()->parent());}
- node_type* leftmost()const{return node_type::from_impl(header()->left());}
- node_type* rightmost()const{return node_type::from_impl(header()->right());}
-
- void empty_initialize()
- {
- header()->color()=red;
- /* used to distinguish header() from root, in iterator.operator++ */
-
- header()->parent()=node_impl_pointer(0);
- header()->left()=header()->impl();
- header()->right()=header()->impl();
- }
-
- struct link_info
- {
- /* coverity[uninit_ctor]: suppress warning */
- link_info():side(to_left){}
-
- ordered_index_side side;
- node_impl_pointer pos;
- };
-
- bool link_point(key_param_type k,link_info& inf,ordered_unique_tag)
- {
- node_type* y=header();
- node_type* x=root();
- bool c=true;
- while(x){
- y=x;
- c=comp_(k,key(x->value()));
- x=node_type::from_impl(c?x->left():x->right());
- }
- node_type* yy=y;
- if(c){
- if(yy==leftmost()){
- inf.side=to_left;
- inf.pos=y->impl();
- return true;
- }
- else node_type::decrement(yy);
- }
-
- if(comp_(key(yy->value()),k)){
- inf.side=c?to_left:to_right;
- inf.pos=y->impl();
- return true;
- }
- else{
- inf.pos=yy->impl();
- return false;
- }
- }
-
- bool link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
- {
- node_type* y=header();
- node_type* x=root();
- bool c=true;
- while (x){
- y=x;
- c=comp_(k,key(x->value()));
- x=node_type::from_impl(c?x->left():x->right());
- }
- inf.side=c?to_left:to_right;
- inf.pos=y->impl();
- return true;
- }
-
- bool lower_link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
- {
- node_type* y=header();
- node_type* x=root();
- bool c=false;
- while (x){
- y=x;
- c=comp_(key(x->value()),k);
- x=node_type::from_impl(c?x->right():x->left());
- }
- inf.side=c?to_right:to_left;
- inf.pos=y->impl();
- return true;
- }
-
- bool hinted_link_point(
- key_param_type k,node_type* position,link_info& inf,ordered_unique_tag)
- {
- if(position->impl()==header()->left()){
- if(size()>0&&comp_(k,key(position->value()))){
- inf.side=to_left;
- inf.pos=position->impl();
- return true;
- }
- else return link_point(k,inf,ordered_unique_tag());
- }
- else if(position==header()){
- if(comp_(key(rightmost()->value()),k)){
- inf.side=to_right;
- inf.pos=rightmost()->impl();
- return true;
- }
- else return link_point(k,inf,ordered_unique_tag());
- }
- else{
- node_type* before=position;
- node_type::decrement(before);
- if(comp_(key(before->value()),k)&&comp_(k,key(position->value()))){
- if(before->right()==node_impl_pointer(0)){
- inf.side=to_right;
- inf.pos=before->impl();
- return true;
- }
- else{
- inf.side=to_left;
- inf.pos=position->impl();
- return true;
- }
- }
- else return link_point(k,inf,ordered_unique_tag());
- }
- }
-
- bool hinted_link_point(
- key_param_type k,node_type* position,link_info& inf,ordered_non_unique_tag)
- {
- if(position->impl()==header()->left()){
- if(size()>0&&!comp_(key(position->value()),k)){
- inf.side=to_left;
- inf.pos=position->impl();
- return true;
- }
- else return lower_link_point(k,inf,ordered_non_unique_tag());
- }
- else if(position==header()){
- if(!comp_(k,key(rightmost()->value()))){
- inf.side=to_right;
- inf.pos=rightmost()->impl();
- return true;
- }
- else return link_point(k,inf,ordered_non_unique_tag());
- }
- else{
- node_type* before=position;
- node_type::decrement(before);
- if(!comp_(k,key(before->value()))){
- if(!comp_(key(position->value()),k)){
- if(before->right()==node_impl_pointer(0)){
- inf.side=to_right;
- inf.pos=before->impl();
- return true;
- }
- else{
- inf.side=to_left;
- inf.pos=position->impl();
- return true;
- }
- }
- else return lower_link_point(k,inf,ordered_non_unique_tag());
- }
- else return link_point(k,inf,ordered_non_unique_tag());
- }
- }
-
- void delete_all_nodes(node_type* x)
- {
- if(!x)return;
-
- delete_all_nodes(node_type::from_impl(x->left()));
- delete_all_nodes(node_type::from_impl(x->right()));
- this->final_delete_node_(static_cast<final_node_type*>(x));
- }
-
- bool in_place(value_param_type v,node_type* x,ordered_unique_tag)
- {
- node_type* y;
- if(x!=leftmost()){
- y=x;
- node_type::decrement(y);
- if(!comp_(key(y->value()),key(v)))return false;
- }
-
- y=x;
- node_type::increment(y);
- return y==header()||comp_(key(v),key(y->value()));
- }
-
- bool in_place(value_param_type v,node_type* x,ordered_non_unique_tag)
- {
- node_type* y;
- if(x!=leftmost()){
- y=x;
- node_type::decrement(y);
- if(comp_(key(v),key(y->value())))return false;
- }
-
- y=x;
- node_type::increment(y);
- return y==header()||!comp_(key(y->value()),key(v));
- }
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
- void detach_iterators(node_type* x)
- {
- iterator it=make_iterator(x);
- safe_mode::detach_equivalent_iterators(it);
- }
-#endif
-
- template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
- std::pair<iterator,bool> emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
- {
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- std::pair<final_node_type*,bool>p=
- this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
- return std::pair<iterator,bool>(make_iterator(p.first),p.second);
- }
-
- template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
- iterator emplace_hint_impl(
- iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
- {
- BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
- BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
- std::pair<final_node_type*,bool>p=
- this->final_emplace_hint_(
- static_cast<final_node_type*>(position.get_node()),
- BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
- return make_iterator(p.first);
- }
-
- template<typename LowerBounder,typename UpperBounder>
- std::pair<iterator,iterator>
- range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
- {
- node_type* y=header();
- node_type* z=root();
-
- while(z){
- if(!lower(key(z->value()))){
- z=node_type::from_impl(z->right());
- }
- else if(!upper(key(z->value()))){
- y=z;
- z=node_type::from_impl(z->left());
- }
- else{
- return std::pair<iterator,iterator>(
- make_iterator(
- lower_range(node_type::from_impl(z->left()),z,lower)),
- make_iterator(
- upper_range(node_type::from_impl(z->right()),y,upper)));
- }
- }
-
- return std::pair<iterator,iterator>(make_iterator(y),make_iterator(y));
- }
-
- template<typename LowerBounder,typename UpperBounder>
- std::pair<iterator,iterator>
- range(LowerBounder,UpperBounder upper,lower_unbounded_tag)const
- {
- return std::pair<iterator,iterator>(
- begin(),
- make_iterator(upper_range(root(),header(),upper)));
- }
-
- template<typename LowerBounder,typename UpperBounder>
- std::pair<iterator,iterator>
- range(LowerBounder lower,UpperBounder,upper_unbounded_tag)const
- {
- return std::pair<iterator,iterator>(
- make_iterator(lower_range(root(),header(),lower)),
- end());
- }
-
- template<typename LowerBounder,typename UpperBounder>
- std::pair<iterator,iterator>
- range(LowerBounder,UpperBounder,both_unbounded_tag)const
- {
- return std::pair<iterator,iterator>(begin(),end());
- }
-
- template<typename LowerBounder>
- node_type * lower_range(node_type* top,node_type* y,LowerBounder lower)const
- {
- while(top){
- if(lower(key(top->value()))){
- y=top;
- top=node_type::from_impl(top->left());
- }
- else top=node_type::from_impl(top->right());
- }
-
- return y;
- }
-
- template<typename UpperBounder>
- node_type * upper_range(node_type* top,node_type* y,UpperBounder upper)const
- {
- while(top){
- if(!upper(key(top->value()))){
- y=top;
- top=node_type::from_impl(top->left());
- }
- else top=node_type::from_impl(top->right());
- }
-
- return y;
- }
-
-#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
- template<typename Archive>
- void save_(
- Archive& ar,const unsigned int version,const index_saver_type& sm,
- ordered_unique_tag)const
- {
- super::save_(ar,version,sm);
- }
-
- template<typename Archive>
- void load_(
- Archive& ar,const unsigned int version,const index_loader_type& lm,
- ordered_unique_tag)
- {
- super::load_(ar,version,lm);
- }
-
- template<typename Archive>
- void save_(
- Archive& ar,const unsigned int version,const index_saver_type& sm,
- ordered_non_unique_tag)const
- {
- typedef duplicates_iterator<node_type,value_compare> dup_iterator;
-
- sm.save(
- dup_iterator(begin().get_node(),end().get_node(),value_comp()),
- dup_iterator(end().get_node(),value_comp()),
- ar,version);
- super::save_(ar,version,sm);
- }
-
- template<typename Archive>
- void load_(
- Archive& ar,const unsigned int version,const index_loader_type& lm,
- ordered_non_unique_tag)
- {
- lm.load(
- ::boost::bind(
- &ordered_index::rearranger,this,::boost::arg<1>(),::boost::arg<2>()),
- ar,version);
- super::load_(ar,version,lm);
- }
-
- void rearranger(node_type* position,node_type *x)
- {
- if(!position||comp_(key(position->value()),key(x->value()))){
- position=lower_bound(key(x->value())).get_node();
- }
- else if(comp_(key(x->value()),key(position->value()))){
- /* inconsistent rearrangement */
- throw_exception(
- archive::archive_exception(
- archive::archive_exception::other_exception));
- }
- else node_type::increment(position);
-
- if(position!=x){
- node_impl_type::rebalance_for_erase(
- x->impl(),header()->parent(),header()->left(),header()->right());
- node_impl_type::restore(
- x->impl(),position->impl(),header()->impl());
- }
- }
-#endif /* serialization */
-
- key_from_value key;
- key_compare comp_;
-
-#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
- BOOST_WORKAROUND(__MWERKS__,<=0x3003)
-#pragma parse_mfunc_templ reset
#endif
};
-/* comparison */
-
-template<
- typename KeyFromValue1,typename Compare1,
- typename SuperMeta1,typename TagList1,typename Category1,
- typename KeyFromValue2,typename Compare2,
- typename SuperMeta2,typename TagList2,typename Category2
->
-bool operator==(
- const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
- const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
-{
- return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
-}
-
-template<
- typename KeyFromValue1,typename Compare1,
- typename SuperMeta1,typename TagList1,typename Category1,
- typename KeyFromValue2,typename Compare2,
- typename SuperMeta2,typename TagList2,typename Category2
->
-bool operator<(
- const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
- const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
-{
- return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
-}
-
-template<
- typename KeyFromValue1,typename Compare1,
- typename SuperMeta1,typename TagList1,typename Category1,
- typename KeyFromValue2,typename Compare2,
- typename SuperMeta2,typename TagList2,typename Category2
->
-bool operator!=(
- const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
- const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
-{
- return !(x==y);
-}
-
-template<
- typename KeyFromValue1,typename Compare1,
- typename SuperMeta1,typename TagList1,typename Category1,
- typename KeyFromValue2,typename Compare2,
- typename SuperMeta2,typename TagList2,typename Category2
->
-bool operator>(
- const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
- const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
-{
- return y<x;
-}
-
-template<
- typename KeyFromValue1,typename Compare1,
- typename SuperMeta1,typename TagList1,typename Category1,
- typename KeyFromValue2,typename Compare2,
- typename SuperMeta2,typename TagList2,typename Category2
->
-bool operator>=(
- const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
- const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
-{
- return !(x<y);
-}
-
-template<
- typename KeyFromValue1,typename Compare1,
- typename SuperMeta1,typename TagList1,typename Category1,
- typename KeyFromValue2,typename Compare2,
- typename SuperMeta2,typename TagList2,typename Category2
->
-bool operator<=(
- const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
- const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
-{
- return !(x>y);
-}
-
-/* specialized algorithms */
-
-template<
- typename KeyFromValue,typename Compare,
- typename SuperMeta,typename TagList,typename Category
->
-void swap(
- ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x,
- ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& y)
-{
- x.swap(y);
-}
-
} /* namespace multi_index::detail */
/* ordered_index specifiers */
@@ -1465,7 +69,7 @@ struct ordered_unique
template<typename Super>
struct node_class
{
- typedef detail::ordered_index_node<Super> type;
+ typedef detail::ordered_index_node<detail::null_augment_policy,Super> type;
};
template<typename SuperMeta>
@@ -1473,7 +77,8 @@ struct ordered_unique
{
typedef detail::ordered_index<
key_from_value_type,compare_type,
- SuperMeta,tag_list_type,detail::ordered_unique_tag> type;
+ SuperMeta,tag_list_type,detail::ordered_unique_tag,
+ detail::null_augment_policy> type;
};
};
@@ -1489,7 +94,7 @@ struct ordered_non_unique
template<typename Super>
struct node_class
{
- typedef detail::ordered_index_node<Super> type;
+ typedef detail::ordered_index_node<detail::null_augment_policy,Super> type;
};
template<typename SuperMeta>
@@ -1497,7 +102,8 @@ struct ordered_non_unique
{
typedef detail::ordered_index<
key_from_value_type,compare_type,
- SuperMeta,tag_list_type,detail::ordered_non_unique_tag> type;
+ SuperMeta,tag_list_type,detail::ordered_non_unique_tag,
+ detail::null_augment_policy> type;
};
};
@@ -1505,21 +111,4 @@ struct ordered_non_unique
} /* namespace boost */
-/* Boost.Foreach compatibility */
-
-template<
- typename KeyFromValue,typename Compare,
- typename SuperMeta,typename TagList,typename Category
->
-inline boost::mpl::true_* boost_foreach_is_noncopyable(
- boost::multi_index::detail::ordered_index<
- KeyFromValue,Compare,SuperMeta,TagList,Category>*&,
- boost::foreach::tag)
-{
- return 0;
-}
-
-#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
-#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF
-
#endif
diff --git a/boost/multi_index/ordered_index_fwd.hpp b/boost/multi_index/ordered_index_fwd.hpp
index dbd040fa36..fe44aaf860 100644
--- a/boost/multi_index/ordered_index_fwd.hpp
+++ b/boost/multi_index/ordered_index_fwd.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -14,101 +14,12 @@
#endif
#include <boost/multi_index/detail/ord_index_args.hpp>
+#include <boost/multi_index/detail/ord_index_impl_fwd.hpp>
namespace boost{
namespace multi_index{
-namespace detail{
-
-template<
- typename KeyFromValue,typename Compare,
- typename SuperMeta,typename TagList,typename Category
->
-class ordered_index;
-
-template<
- typename KeyFromValue1,typename Compare1,
- typename SuperMeta1,typename TagList1,typename Category1,
- typename KeyFromValue2,typename Compare2,
- typename SuperMeta2,typename TagList2,typename Category2
->
-bool operator==(
- const ordered_index<
- KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
- const ordered_index<
- KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y);
-
-template<
- typename KeyFromValue1,typename Compare1,
- typename SuperMeta1,typename TagList1,typename Category1,
- typename KeyFromValue2,typename Compare2,
- typename SuperMeta2,typename TagList2,typename Category2
->
-bool operator<(
- const ordered_index<
- KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
- const ordered_index<
- KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y);
-
-template<
- typename KeyFromValue1,typename Compare1,
- typename SuperMeta1,typename TagList1,typename Category1,
- typename KeyFromValue2,typename Compare2,
- typename SuperMeta2,typename TagList2,typename Category2
->
-bool operator!=(
- const ordered_index<
- KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
- const ordered_index<
- KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y);
-
-template<
- typename KeyFromValue1,typename Compare1,
- typename SuperMeta1,typename TagList1,typename Category1,
- typename KeyFromValue2,typename Compare2,
- typename SuperMeta2,typename TagList2,typename Category2
->
-bool operator>(
- const ordered_index<
- KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
- const ordered_index<
- KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y);
-
-template<
- typename KeyFromValue1,typename Compare1,
- typename SuperMeta1,typename TagList1,typename Category1,
- typename KeyFromValue2,typename Compare2,
- typename SuperMeta2,typename TagList2,typename Category2
->
-bool operator>=(
- const ordered_index<
- KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
- const ordered_index<
- KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y);
-
-template<
- typename KeyFromValue1,typename Compare1,
- typename SuperMeta1,typename TagList1,typename Category1,
- typename KeyFromValue2,typename Compare2,
- typename SuperMeta2,typename TagList2,typename Category2
->
-bool operator<=(
- const ordered_index<
- KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
- const ordered_index<
- KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y);
-
-template<
- typename KeyFromValue,typename Compare,
- typename SuperMeta,typename TagList,typename Category
->
-void swap(
- ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x,
- ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& y);
-
-} /* namespace multi_index::detail */
-
/* ordered_index specifiers */
template<typename Arg1,typename Arg2=mpl::na,typename Arg3=mpl::na>
diff --git a/boost/multi_index/random_access_index.hpp b/boost/multi_index/random_access_index.hpp
index 7702776fba..5a628fb75a 100644
--- a/boost/multi_index/random_access_index.hpp
+++ b/boost/multi_index/random_access_index.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2014 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -15,6 +15,7 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
+#include <boost/bind.hpp>
#include <boost/call_traits.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/detail/workaround.hpp>
@@ -49,7 +50,6 @@
#endif
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
-#include <boost/bind.hpp>
#include <boost/multi_index/detail/rnd_index_loader.hpp>
#endif
@@ -583,7 +583,8 @@ public:
difference_type n=
end()-make_iterator(
random_access_index_remove<node_type>(
- ptrs,std::bind2nd(std::equal_to<value_type>(),value)));
+ ptrs,
+ ::boost::bind(std::equal_to<value_type>(),::boost::arg<1>(),value)));
while(n--)pop_back();
}
diff --git a/boost/multi_index/ranked_index.hpp b/boost/multi_index/ranked_index.hpp
new file mode 100644
index 0000000000..a5da5242ca
--- /dev/null
+++ b/boost/multi_index/ranked_index.hpp
@@ -0,0 +1,382 @@
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_RANKED_INDEX_HPP
+#define BOOST_MULTI_INDEX_RANKED_INDEX_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/multi_index/detail/ord_index_impl.hpp>
+#include <boost/multi_index/detail/rnk_index_ops.hpp>
+#include <boost/multi_index/ranked_index_fwd.hpp>
+
+namespace boost{
+
+namespace multi_index{
+
+namespace detail{
+
+/* ranked_index augments a given ordered index to provide rank operations */
+
+template<typename OrderedIndexNodeImpl>
+struct ranked_node:OrderedIndexNodeImpl
+{
+ std::size_t size;
+};
+
+template<typename OrderedIndexImpl>
+class ranked_index:public OrderedIndexImpl
+{
+ typedef OrderedIndexImpl super;
+
+protected:
+ typedef typename super::node_type node_type;
+ typedef typename super::node_impl_pointer node_impl_pointer;
+
+public:
+ typedef typename super::ctor_args_list ctor_args_list;
+ typedef typename super::allocator_type allocator_type;
+ typedef typename super::iterator iterator;
+
+ /* rank operations */
+
+ iterator nth(std::size_t n)const
+ {
+ return this->make_iterator(node_type::from_impl(
+ ranked_index_nth(n,this->header()->impl())));
+ }
+
+ std::size_t rank(iterator position)const
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+
+ return ranked_index_rank(
+ position.get_node()->impl(),this->header()->impl());
+ }
+
+ template<typename CompatibleKey>
+ std::size_t find_rank(const CompatibleKey& x)const
+ {
+ return ranked_index_find_rank(
+ this->root(),this->header(),this->key,x,this->comp_);
+ }
+
+ template<typename CompatibleKey,typename CompatibleCompare>
+ std::size_t find_rank(
+ const CompatibleKey& x,const CompatibleCompare& comp)const
+ {
+ return ranked_index_find_rank(
+ this->root(),this->header(),this->key,x,comp);
+ }
+
+ template<typename CompatibleKey>
+ std::size_t lower_bound_rank(const CompatibleKey& x)const
+ {
+ return ranked_index_lower_bound_rank(
+ this->root(),this->header(),this->key,x,this->comp_);
+ }
+
+ template<typename CompatibleKey,typename CompatibleCompare>
+ std::size_t lower_bound_rank(
+ const CompatibleKey& x,const CompatibleCompare& comp)const
+ {
+ return ranked_index_lower_bound_rank(
+ this->root(),this->header(),this->key,x,comp);
+ }
+
+ template<typename CompatibleKey>
+ std::size_t upper_bound_rank(const CompatibleKey& x)const
+ {
+ return ranked_index_upper_bound_rank(
+ this->root(),this->header(),this->key,x,this->comp_);
+ }
+
+ template<typename CompatibleKey,typename CompatibleCompare>
+ std::size_t upper_bound_rank(
+ const CompatibleKey& x,const CompatibleCompare& comp)const
+ {
+ return ranked_index_upper_bound_rank(
+ this->root(),this->header(),this->key,x,comp);
+ }
+
+ template<typename CompatibleKey>
+ std::pair<std::size_t,std::size_t> equal_range_rank(
+ const CompatibleKey& x)const
+ {
+ return ranked_index_equal_range_rank(
+ this->root(),this->header(),this->key,x,this->comp_);
+ }
+
+ template<typename CompatibleKey,typename CompatibleCompare>
+ std::pair<std::size_t,std::size_t> equal_range_rank(
+ const CompatibleKey& x,const CompatibleCompare& comp)const
+ {
+ return ranked_index_equal_range_rank(
+ this->root(),this->header(),this->key,x,comp);
+ }
+
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<std::size_t,std::size_t>
+ range_rank(LowerBounder lower,UpperBounder upper)const
+ {
+ typedef typename mpl::if_<
+ is_same<LowerBounder,unbounded_type>,
+ BOOST_DEDUCED_TYPENAME mpl::if_<
+ is_same<UpperBounder,unbounded_type>,
+ both_unbounded_tag,
+ lower_unbounded_tag
+ >::type,
+ BOOST_DEDUCED_TYPENAME mpl::if_<
+ is_same<UpperBounder,unbounded_type>,
+ upper_unbounded_tag,
+ none_unbounded_tag
+ >::type
+ >::type dispatch;
+
+ return range_rank(lower,upper,dispatch());
+ }
+
+protected:
+ ranked_index(const ranked_index& x):super(x){};
+
+ ranked_index(const ranked_index& x,do_not_copy_elements_tag):
+ super(x,do_not_copy_elements_tag()){};
+
+ ranked_index(
+ const ctor_args_list& args_list,const allocator_type& al):
+ super(args_list,al){}
+
+private:
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<std::size_t,std::size_t>
+ range_rank(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
+ {
+ node_type* y=this->header();
+ node_type* z=this->root();
+
+ if(!z)return std::pair<std::size_t,std::size_t>(0,0);
+
+ std::size_t s=z->size;
+
+ do{
+ if(!lower(this->key(z->value()))){
+ z=node_type::from_impl(z->right());
+ }
+ else if(!upper(this->key(z->value()))){
+ y=z;
+ s-=ranked_node_size(y->right())+1;
+ z=node_type::from_impl(z->left());
+ }
+ else{
+ return std::pair<std::size_t,std::size_t>(
+ s-z->size+
+ lower_range_rank(node_type::from_impl(z->left()),z,lower),
+ s-ranked_node_size(z->right())+
+ upper_range_rank(node_type::from_impl(z->right()),y,upper));
+ }
+ }while(z);
+
+ return std::pair<std::size_t,std::size_t>(s,s);
+ }
+
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<std::size_t,std::size_t>
+ range_rank(LowerBounder,UpperBounder upper,lower_unbounded_tag)const
+ {
+ return std::pair<std::size_t,std::size_t>(
+ 0,
+ upper_range_rank(this->root(),this->header(),upper));
+ }
+
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<std::size_t,std::size_t>
+ range_rank(LowerBounder lower,UpperBounder,upper_unbounded_tag)const
+ {
+ return std::pair<std::size_t,std::size_t>(
+ lower_range_rank(this->root(),this->header(),lower),
+ this->size());
+ }
+
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<std::size_t,std::size_t>
+ range_rank(LowerBounder,UpperBounder,both_unbounded_tag)const
+ {
+ return std::pair<std::size_t,std::size_t>(0,this->size());
+ }
+
+ template<typename LowerBounder>
+ std::size_t
+ lower_range_rank(node_type* top,node_type* y,LowerBounder lower)const
+ {
+ if(!top)return 0;
+
+ std::size_t s=top->size;
+
+ do{
+ if(lower(this->key(top->value()))){
+ y=top;
+ s-=ranked_node_size(y->right())+1;
+ top=node_type::from_impl(top->left());
+ }
+ else top=node_type::from_impl(top->right());
+ }while(top);
+
+ return s;
+ }
+
+ template<typename UpperBounder>
+ std::size_t
+ upper_range_rank(node_type* top,node_type* y,UpperBounder upper)const
+ {
+ if(!top)return 0;
+
+ std::size_t s=top->size;
+
+ do{
+ if(!upper(this->key(top->value()))){
+ y=top;
+ s-=ranked_node_size(y->right())+1;
+ top=node_type::from_impl(top->left());
+ }
+ else top=node_type::from_impl(top->right());
+ }while(top);
+
+ return s;
+ }
+};
+
+/* augmenting policy for ordered_index */
+
+struct rank_policy
+{
+ template<typename OrderedIndexNodeImpl>
+ struct augmented_node
+ {
+ typedef ranked_node<OrderedIndexNodeImpl> type;
+ };
+
+ template<typename OrderedIndexImpl>
+ struct augmented_interface
+ {
+ typedef ranked_index<OrderedIndexImpl> type;
+ };
+
+ /* algorihmic stuff */
+
+ template<typename Pointer>
+ static void add(Pointer x,Pointer root)
+ {
+ x->size=1;
+ while(x!=root){
+ x=x->parent();
+ ++(x->size);
+ }
+ }
+
+ template<typename Pointer>
+ static void remove(Pointer x,Pointer root)
+ {
+ while(x!=root){
+ x=x->parent();
+ --(x->size);
+ }
+ }
+
+ template<typename Pointer>
+ static void copy(Pointer x,Pointer y)
+ {
+ y->size=x->size;
+ }
+
+ template<typename Pointer>
+ static void rotate_left(Pointer x,Pointer y) /* in: x==y->left() */
+ {
+ y->size=x->size;
+ x->size=ranked_node_size(x->left())+ranked_node_size(x->right())+1;
+ };
+
+ template<typename Pointer>
+ static void rotate_right(Pointer x,Pointer y) /* in: x==y->right() */
+ {
+ rotate_left(x,y);
+ };
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
+ /* invariant stuff */
+
+ template<typename Pointer>
+ static bool invariant(Pointer x)
+ {
+ return x->size==ranked_node_size(x->left())+ranked_node_size(x->right())+1;
+ }
+#endif
+};
+
+} /* namespace multi_index::detail */
+
+/* ranked_index specifiers */
+
+template<typename Arg1,typename Arg2,typename Arg3>
+struct ranked_unique
+{
+ typedef typename detail::ordered_index_args<
+ Arg1,Arg2,Arg3> index_args;
+ typedef typename index_args::tag_list_type::type tag_list_type;
+ typedef typename index_args::key_from_value_type key_from_value_type;
+ typedef typename index_args::compare_type compare_type;
+
+ template<typename Super>
+ struct node_class
+ {
+ typedef detail::ordered_index_node<detail::rank_policy,Super> type;
+ };
+
+ template<typename SuperMeta>
+ struct index_class
+ {
+ typedef detail::ordered_index<
+ key_from_value_type,compare_type,
+ SuperMeta,tag_list_type,detail::ordered_unique_tag,
+ detail::rank_policy> type;
+ };
+};
+
+template<typename Arg1,typename Arg2,typename Arg3>
+struct ranked_non_unique
+{
+ typedef detail::ordered_index_args<
+ Arg1,Arg2,Arg3> index_args;
+ typedef typename index_args::tag_list_type::type tag_list_type;
+ typedef typename index_args::key_from_value_type key_from_value_type;
+ typedef typename index_args::compare_type compare_type;
+
+ template<typename Super>
+ struct node_class
+ {
+ typedef detail::ordered_index_node<detail::rank_policy,Super> type;
+ };
+
+ template<typename SuperMeta>
+ struct index_class
+ {
+ typedef detail::ordered_index<
+ key_from_value_type,compare_type,
+ SuperMeta,tag_list_type,detail::ordered_non_unique_tag,
+ detail::rank_policy> type;
+ };
+};
+
+} /* namespace multi_index */
+
+} /* namespace boost */
+
+#endif
diff --git a/boost/multi_index/ranked_index_fwd.hpp b/boost/multi_index/ranked_index_fwd.hpp
new file mode 100644
index 0000000000..380d348073
--- /dev/null
+++ b/boost/multi_index/ranked_index_fwd.hpp
@@ -0,0 +1,35 @@
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_RANKED_INDEX_FWD_HPP
+#define BOOST_MULTI_INDEX_RANKED_INDEX_FWD_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/multi_index/detail/ord_index_args.hpp>
+#include <boost/multi_index/detail/ord_index_impl_fwd.hpp>
+
+namespace boost{
+
+namespace multi_index{
+
+/* ranked_index specifiers */
+
+template<typename Arg1,typename Arg2=mpl::na,typename Arg3=mpl::na>
+struct ranked_unique;
+
+template<typename Arg1,typename Arg2=mpl::na,typename Arg3=mpl::na>
+struct ranked_non_unique;
+
+} /* namespace multi_index */
+
+} /* namespace boost */
+
+#endif
diff --git a/boost/multi_index/sequenced_index.hpp b/boost/multi_index/sequenced_index.hpp
index d56edddd17..ce96bb5f9a 100644
--- a/boost/multi_index/sequenced_index.hpp
+++ b/boost/multi_index/sequenced_index.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2014 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -14,6 +14,7 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/bind.hpp>
#include <boost/call_traits.hpp>
#include <boost/detail/allocator_utilities.hpp>
#include <boost/detail/no_exceptions_support.hpp>
@@ -516,7 +517,8 @@ public:
void remove(value_param_type value)
{
sequenced_index_remove(
- *this,std::bind2nd(std::equal_to<value_type>(),value));
+ *this,
+ ::boost::bind(std::equal_to<value_type>(),::boost::arg<1>(),value));
}
template<typename Predicate>
diff --git a/boost/multiprecision/concepts/mp_number_archetypes.hpp b/boost/multiprecision/concepts/mp_number_archetypes.hpp
index e52044adbf..5d5d841710 100644
--- a/boost/multiprecision/concepts/mp_number_archetypes.hpp
+++ b/boost/multiprecision/concepts/mp_number_archetypes.hpp
@@ -26,8 +26,8 @@ namespace concepts{
struct number_backend_float_architype
{
- typedef mpl::list<long long> signed_types;
- typedef mpl::list<unsigned long long> unsigned_types;
+ typedef mpl::list<boost::long_long_type> signed_types;
+ typedef mpl::list<boost::ulong_long_type> unsigned_types;
typedef mpl::list<long double> float_types;
typedef int exponent_type;
@@ -46,13 +46,13 @@ struct number_backend_float_architype
std::cout << "Assignment (" << m_value << ")" << std::endl;
return *this;
}
- number_backend_float_architype& operator = (unsigned long long i)
+ number_backend_float_architype& operator = (boost::ulong_long_type i)
{
m_value = i;
std::cout << "UInt Assignment (" << i << ")" << std::endl;
return *this;
}
- number_backend_float_architype& operator = (long long i)
+ number_backend_float_architype& operator = (boost::long_long_type i)
{
m_value = i;
std::cout << "Int Assignment (" << i << ")" << std::endl;
@@ -112,12 +112,12 @@ struct number_backend_float_architype
std::cout << "Comparison" << std::endl;
return m_value > o.m_value ? 1 : (m_value < o.m_value ? -1 : 0);
}
- int compare(long long i)const
+ int compare(boost::long_long_type i)const
{
std::cout << "Comparison with int" << std::endl;
return m_value > i ? 1 : (m_value < i ? -1 : 0);
}
- int compare(unsigned long long i)const
+ int compare(boost::ulong_long_type i)const
{
std::cout << "Comparison with unsigned" << std::endl;
return m_value > i ? 1 : (m_value < i ? -1 : 0);
@@ -151,13 +151,13 @@ inline void eval_divide(number_backend_float_architype& result, const number_bac
result.m_value /= o.m_value;
}
-inline void eval_convert_to(unsigned long long* result, const number_backend_float_architype& val)
+inline void eval_convert_to(boost::ulong_long_type* result, const number_backend_float_architype& val)
{
- *result = static_cast<unsigned long long>(val.m_value);
+ *result = static_cast<boost::ulong_long_type>(val.m_value);
}
-inline void eval_convert_to(long long* result, const number_backend_float_architype& val)
+inline void eval_convert_to(boost::long_long_type* result, const number_backend_float_architype& val)
{
- *result = static_cast<long long>(val.m_value);
+ *result = static_cast<boost::long_long_type>(val.m_value);
}
inline void eval_convert_to(long double* result, number_backend_float_architype& val)
{
diff --git a/boost/multiprecision/cpp_bin_float.hpp b/boost/multiprecision/cpp_bin_float.hpp
index 9a4ceff587..4c00799843 100644
--- a/boost/multiprecision/cpp_bin_float.hpp
+++ b/boost/multiprecision/cpp_bin_float.hpp
@@ -21,7 +21,7 @@ enum digit_base_type
#ifdef BOOST_MSVC
#pragma warning(push)
-#pragma warning(disable:4522) // multiple assignment operators specified
+#pragma warning(disable:4522 6326) // multiple assignment operators specified, comparison of two constants
#endif
namespace detail{
@@ -37,7 +37,7 @@ template <unsigned Digits, digit_base_type DigitBase = digit_base_10, class Allo
class cpp_bin_float
{
public:
- static const unsigned bit_count = DigitBase == digit_base_2 ? Digits : (Digits * 1000uL) / 301uL + ((Digits * 1000uL) % 301 ? 2u : 1u);
+ static const unsigned bit_count = DigitBase == digit_base_2 ? Digits : (Digits * 1000uL) / 301uL + (((Digits * 1000uL) % 301) ? 2u : 1u);
typedef cpp_int_backend<is_void<Allocator>::value ? bit_count : 0, bit_count, is_void<Allocator>::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator> rep_type;
typedef cpp_int_backend<is_void<Allocator>::value ? 2 * bit_count : 0, 2 * bit_count, is_void<Allocator>::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator> double_rep_type;
@@ -67,9 +67,9 @@ private:
exponent_type m_exponent;
bool m_sign;
public:
- cpp_bin_float() BOOST_NOEXCEPT_IF(noexcept(rep_type())) : m_data(), m_exponent(exponent_nan), m_sign(false) {}
+ cpp_bin_float() BOOST_MP_NOEXCEPT_IF(noexcept(rep_type())) : m_data(), m_exponent(exponent_nan), m_sign(false) {}
- cpp_bin_float(const cpp_bin_float &o) BOOST_NOEXCEPT_IF(noexcept(rep_type(std::declval<const rep_type&>())))
+ cpp_bin_float(const cpp_bin_float &o) BOOST_MP_NOEXCEPT_IF(noexcept(rep_type(std::declval<const rep_type&>())))
: m_data(o.m_data), m_exponent(o.m_exponent), m_sign(o.m_sign) {}
template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
@@ -104,7 +104,7 @@ public:
this->assign_float(f);
}
- cpp_bin_float& operator=(const cpp_bin_float &o) BOOST_NOEXCEPT_IF(noexcept(std::declval<rep_type&>() = std::declval<const rep_type&>()))
+ cpp_bin_float& operator=(const cpp_bin_float &o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<rep_type&>() = std::declval<const rep_type&>()))
{
m_data = o.m_data;
m_exponent = o.m_exponent;
@@ -773,6 +773,10 @@ inline typename enable_if_c<is_signed<S>::value>::type eval_multiply(cpp_bin_flo
template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &u, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &v)
{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:6326) // comparison of two constants
+#endif
using default_ops::eval_subtract;
using default_ops::eval_qr;
using default_ops::eval_bit_test;
@@ -882,7 +886,7 @@ inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, Mi
// how we'll be rounding.
//
BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
- static const unsigned lshift = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits ? 2 : limb_bits;
+ static const unsigned lshift = (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits) ? 2 : limb_bits;
eval_left_shift(q, lshift);
res.exponent() -= lshift;
eval_left_shift(r, 1u);
@@ -893,6 +897,9 @@ inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, Mi
q.limbs()[0] |= (static_cast<limb_type>(1u) << (lshift - 1)) + static_cast<limb_type>(1u);
}
copy_and_round(res, q);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
}
template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
@@ -904,6 +911,10 @@ inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, Mi
template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
inline typename enable_if_c<is_unsigned<U>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &u, const U &v)
{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:6326) // comparison of two constants
+#endif
using default_ops::eval_subtract;
using default_ops::eval_qr;
using default_ops::eval_bit_test;
@@ -1000,6 +1011,9 @@ inline typename enable_if_c<is_unsigned<U>::value>::type eval_divide(cpp_bin_flo
q.limbs()[0] |= (static_cast<limb_type>(1u) << (lshift - 1)) + static_cast<limb_type>(1u);
}
copy_and_round(res, q);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
}
template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
@@ -1045,7 +1059,7 @@ inline bool eval_eq(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent,
}
template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
-inline void eval_convert_to(long long *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
+inline void eval_convert_to(boost::long_long_type *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
{
switch(arg.exponent())
{
@@ -1055,7 +1069,7 @@ inline void eval_convert_to(long long *res, const cpp_bin_float<Digits, DigitBas
case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
- *res = (std::numeric_limits<long long>::max)();
+ *res = (std::numeric_limits<boost::long_long_type>::max)();
if(arg.sign())
*res = -*res;
return;
@@ -1068,14 +1082,14 @@ inline void eval_convert_to(long long *res, const cpp_bin_float<Digits, DigitBas
*res = 0;
return;
}
- if(arg.sign() && (arg.compare((std::numeric_limits<long long>::min)()) <= 0))
+ if(arg.sign() && (arg.compare((std::numeric_limits<boost::long_long_type>::min)()) <= 0))
{
- *res = (std::numeric_limits<long long>::min)();
+ *res = (std::numeric_limits<boost::long_long_type>::min)();
return;
}
- else if(!arg.sign() && (arg.compare((std::numeric_limits<long long>::max)()) >= 0))
+ else if(!arg.sign() && (arg.compare((std::numeric_limits<boost::long_long_type>::max)()) >= 0))
{
- *res = (std::numeric_limits<long long>::max)();
+ *res = (std::numeric_limits<boost::long_long_type>::max)();
return;
}
eval_right_shift(man, shift);
@@ -1087,7 +1101,7 @@ inline void eval_convert_to(long long *res, const cpp_bin_float<Digits, DigitBas
}
template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
-inline void eval_convert_to(unsigned long long *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
+inline void eval_convert_to(boost::ulong_long_type *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg)
{
switch(arg.exponent())
{
@@ -1097,7 +1111,7 @@ inline void eval_convert_to(unsigned long long *res, const cpp_bin_float<Digits,
case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
- *res = (std::numeric_limits<unsigned long long>::max)();
+ *res = (std::numeric_limits<boost::ulong_long_type>::max)();
return;
}
typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type man(arg.bits());
@@ -1110,8 +1124,8 @@ inline void eval_convert_to(unsigned long long *res, const cpp_bin_float<Digits,
}
else if(shift < 0)
{
- // TODO: what if we have fewer cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count than a long long?
- *res = (std::numeric_limits<long long>::max)();
+ // TODO: what if we have fewer cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count than a boost::long_long_type?
+ *res = (std::numeric_limits<boost::long_long_type>::max)();
return;
}
eval_right_shift(man, shift);
@@ -1462,9 +1476,9 @@ public:
return -(max)();
}
BOOST_STATIC_CONSTEXPR int digits = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count;
- BOOST_STATIC_CONSTEXPR int digits10 = digits * 301 / 1000;
+ BOOST_STATIC_CONSTEXPR int digits10 = (digits - 1) * 301 / 1000;
// Is this really correct???
- BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 2;
+ BOOST_STATIC_CONSTEXPR int max_digits10 = (digits * 301 / 1000) + 2;
BOOST_STATIC_CONSTEXPR bool is_signed = true;
BOOST_STATIC_CONSTEXPR bool is_integer = false;
BOOST_STATIC_CONSTEXPR bool is_exact = false;
diff --git a/boost/multiprecision/cpp_bin_float/io.hpp b/boost/multiprecision/cpp_bin_float/io.hpp
index ae3ab38e1d..88d5ddd053 100644
--- a/boost/multiprecision/cpp_bin_float/io.hpp
+++ b/boost/multiprecision/cpp_bin_float/io.hpp
@@ -282,7 +282,7 @@ cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& cpp_bin_float
#ifdef BOOST_MP_STRESS_IO
boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 32;
#else
- boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits ? limb_bits - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits : 0) + limb_bits;
+ boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + ((cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) ? (limb_bits - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) : 0) + limb_bits;
#endif
boost::int64_t error = 0;
boost::intmax_t calc_exp = 0;
@@ -384,9 +384,9 @@ cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& cpp_bin_float
{
// Too many bits in q and the bits in q indicate a tie, but we can break that using r,
// note that the radius of error in r is error/2 * q:
- int shift = gb - (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1;
- q >>= shift;
- final_exponent += static_cast<Exponent>(shift);
+ int lshift = gb - (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1;
+ q >>= lshift;
+ final_exponent += static_cast<Exponent>(lshift);
BOOST_ASSERT((msb(q) >= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
if(error && (r < (error / 2) * q))
roundup = -1;
@@ -525,7 +525,7 @@ std::string cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::s
#ifdef BOOST_MP_STRESS_IO
boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 32;
#else
- boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits ? limb_bits - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits : 0) + limb_bits;
+ boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + ((cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) ? (limb_bits - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) : 0) + limb_bits;
if(power10)
max_bits += (msb(boost::multiprecision::detail::abs(power10)) / 8) * limb_bits;
#endif
diff --git a/boost/multiprecision/cpp_dec_float.hpp b/boost/multiprecision/cpp_dec_float.hpp
index d19abafec4..737f925067 100644
--- a/boost/multiprecision/cpp_dec_float.hpp
+++ b/boost/multiprecision/cpp_dec_float.hpp
@@ -34,6 +34,11 @@
//
#include <boost/math/policies/policy.hpp>
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:6326) // comparison of two constants
+#endif
+
namespace boost{
namespace multiprecision{
namespace backends{
@@ -59,8 +64,8 @@ private:
BOOST_STATIC_ASSERT_MSG(sizeof(ExponentType) > 1, "ExponentType is too small.");
public:
- typedef mpl::list<long long> signed_types;
- typedef mpl::list<unsigned long long> unsigned_types;
+ typedef mpl::list<boost::long_long_type> signed_types;
+ typedef mpl::list<boost::ulong_long_type> unsigned_types;
typedef mpl::list<long double> float_types;
typedef ExponentType exponent_type;
@@ -165,7 +170,7 @@ private:
public:
// Constructors
- cpp_dec_float() BOOST_NOEXCEPT_IF(noexcept(array_type())) :
+ cpp_dec_float() BOOST_MP_NOEXCEPT_IF(noexcept(array_type())) :
data(),
exp (static_cast<ExponentType>(0)),
neg (false),
@@ -210,7 +215,7 @@ public:
from_unsigned_long_long(i);
}
- cpp_dec_float(const cpp_dec_float& f) BOOST_NOEXCEPT_IF(noexcept(array_type(std::declval<const array_type&>()))) :
+ cpp_dec_float(const cpp_dec_float& f) BOOST_MP_NOEXCEPT_IF(noexcept(array_type(std::declval<const array_type&>()))) :
data (f.data),
exp (f.exp),
neg (f.neg),
@@ -284,21 +289,21 @@ public:
static const cpp_dec_float& zero()
{
init.do_nothing();
- static cpp_dec_float val(static_cast<unsigned long long>(0u));
+ static cpp_dec_float val(static_cast<boost::ulong_long_type>(0u));
return val;
}
static const cpp_dec_float& one()
{
init.do_nothing();
- static cpp_dec_float val(static_cast<unsigned long long>(1u));
+ static cpp_dec_float val(static_cast<boost::ulong_long_type>(1u));
return val;
}
static const cpp_dec_float& two()
{
init.do_nothing();
- static cpp_dec_float val(static_cast<unsigned long long>(2u));
+ static cpp_dec_float val(static_cast<boost::ulong_long_type>(2u));
return val;
}
@@ -348,21 +353,21 @@ public:
static const cpp_dec_float& long_long_max()
{
init.do_nothing();
- static cpp_dec_float val((std::numeric_limits<long long>::max)());
+ static cpp_dec_float val((std::numeric_limits<boost::long_long_type>::max)());
return val;
}
static const cpp_dec_float& long_long_min()
{
init.do_nothing();
- static cpp_dec_float val((std::numeric_limits<long long>::min)());
+ static cpp_dec_float val((std::numeric_limits<boost::long_long_type>::min)());
return val;
}
static const cpp_dec_float& ulong_long_max()
{
init.do_nothing();
- static cpp_dec_float val((std::numeric_limits<unsigned long long>::max)());
+ static cpp_dec_float val((std::numeric_limits<boost::ulong_long_type>::max)());
return val;
}
@@ -374,7 +379,7 @@ public:
}
// Basic operations.
- cpp_dec_float& operator=(const cpp_dec_float& v) BOOST_NOEXCEPT_IF(noexcept(std::declval<array_type&>() = std::declval<const array_type&>()))
+ cpp_dec_float& operator=(const cpp_dec_float& v) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<array_type&>() = std::declval<const array_type&>()))
{
data = v.data;
exp = v.exp;
@@ -397,7 +402,7 @@ public:
return *this;
}
- cpp_dec_float& operator=(long long v)
+ cpp_dec_float& operator=(boost::long_long_type v)
{
if(v < 0)
{
@@ -409,7 +414,7 @@ public:
return *this;
}
- cpp_dec_float& operator=(unsigned long long v)
+ cpp_dec_float& operator=(boost::ulong_long_type v)
{
from_unsigned_long_long(v);
return *this;
@@ -428,22 +433,22 @@ public:
cpp_dec_float& operator*=(const cpp_dec_float& v);
cpp_dec_float& operator/=(const cpp_dec_float& v);
- cpp_dec_float& add_unsigned_long_long(const unsigned long long n)
+ cpp_dec_float& add_unsigned_long_long(const boost::ulong_long_type n)
{
cpp_dec_float t;
t.from_unsigned_long_long(n);
return *this += t;
}
- cpp_dec_float& sub_unsigned_long_long(const unsigned long long n)
+ cpp_dec_float& sub_unsigned_long_long(const boost::ulong_long_type n)
{
cpp_dec_float t;
t.from_unsigned_long_long(n);
return *this -= t;
}
- cpp_dec_float& mul_unsigned_long_long(const unsigned long long n);
- cpp_dec_float& div_unsigned_long_long(const unsigned long long n);
+ cpp_dec_float& mul_unsigned_long_long(const boost::ulong_long_type n);
+ cpp_dec_float& div_unsigned_long_long(const boost::ulong_long_type n);
// Elementary primitives.
cpp_dec_float& calculate_inv ();
@@ -503,8 +508,8 @@ public:
double extract_double() const;
long double extract_long_double() const;
- signed long long extract_signed_long_long() const;
- unsigned long long extract_unsigned_long_long() const;
+ boost::long_long_type extract_signed_long_long() const;
+ boost::ulong_long_type extract_unsigned_long_long() const;
void extract_parts(double& mantissa, ExponentType& exponent) const;
cpp_dec_float extract_integer_part() const;
@@ -522,7 +527,7 @@ public:
prec_elem = (std::min)(cpp_dec_float_elem_number, (std::max)(elems, static_cast<boost::int32_t>(2)));
}
}
- static cpp_dec_float pow2(long long i);
+ static cpp_dec_float pow2(boost::long_long_type i);
ExponentType order()const
{
const bool bo_order_is_zero = ((!(isfinite)()) || (data[0] == static_cast<boost::uint32_t>(0u)));
@@ -590,7 +595,7 @@ private:
static bool data_elem_is_non_nine_predicate(const boost::uint32_t& d) { return (d != static_cast<boost::uint32_t>(cpp_dec_float::cpp_dec_float_elem_mask - 1)); }
static bool char_is_nonzero_predicate(const char& c) { return (c != static_cast<char>('0')); }
- void from_unsigned_long_long(const unsigned long long u);
+ void from_unsigned_long_long(const boost::ulong_long_type u);
int cmp_data(const array_type& vd) const;
@@ -970,9 +975,9 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone
}
template <unsigned Digits10, class ExponentType, class Allocator>
-cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::mul_unsigned_long_long(const unsigned long long n)
+cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::mul_unsigned_long_long(const boost::ulong_long_type n)
{
- // Multiply *this with a constant unsigned long long.
+ // Multiply *this with a constant boost::ulong_long_type.
// Evaluate the sign of the result.
const bool b_neg = neg;
@@ -1003,7 +1008,7 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone
return *this = zero();
}
- if(n >= static_cast<unsigned long long>(cpp_dec_float_elem_mask))
+ if(n >= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask))
{
neg = b_neg;
cpp_dec_float t;
@@ -1011,7 +1016,7 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone
return operator*=(t);
}
- if(n == static_cast<unsigned long long>(1u))
+ if(n == static_cast<boost::ulong_long_type>(1u))
{
neg = b_neg;
return *this;
@@ -1050,9 +1055,9 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone
}
template <unsigned Digits10, class ExponentType, class Allocator>
-cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::div_unsigned_long_long(const unsigned long long n)
+cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::div_unsigned_long_long(const boost::ulong_long_type n)
{
- // Divide *this by a constant unsigned long long.
+ // Divide *this by a constant boost::ulong_long_type.
// Evaluate the sign of the result.
const bool b_neg = neg;
@@ -1074,7 +1079,7 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone
return *this;
}
- if(n == static_cast<unsigned long long>(0u))
+ if(n == static_cast<boost::ulong_long_type>(0u))
{
// Divide by 0.
if(iszero())
@@ -1096,7 +1101,7 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone
return *this;
}
- if(n >= static_cast<unsigned long long>(cpp_dec_float_elem_mask))
+ if(n >= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask))
{
neg = b_neg;
cpp_dec_float t;
@@ -1584,58 +1589,58 @@ long double cpp_dec_float<Digits10, ExponentType, Allocator>::extract_long_doubl
}
template <unsigned Digits10, class ExponentType, class Allocator>
-signed long long cpp_dec_float<Digits10, ExponentType, Allocator>::extract_signed_long_long() const
+boost::long_long_type cpp_dec_float<Digits10, ExponentType, Allocator>::extract_signed_long_long() const
{
// Extracts a signed long long from *this.
- // If (x > maximum of signed long long) or (x < minimum of signed long long),
- // then the maximum or minimum of signed long long is returned accordingly.
+ // If (x > maximum of long long) or (x < minimum of long long),
+ // then the maximum or minimum of long long is returned accordingly.
if(exp < static_cast<ExponentType>(0))
{
- return static_cast<signed long long>(0);
+ return static_cast<boost::long_long_type>(0);
}
const bool b_neg = isneg();
- unsigned long long val;
+ boost::ulong_long_type val;
if((!b_neg) && (compare(long_long_max()) > 0))
{
- return (std::numeric_limits<signed long long>::max)();
+ return (std::numeric_limits<boost::long_long_type>::max)();
}
else if(b_neg && (compare(long_long_min()) < 0))
{
- return (std::numeric_limits<signed long long>::min)();
+ return (std::numeric_limits<boost::long_long_type>::min)();
}
else
{
- // Extract the data into an unsigned long long value.
+ // Extract the data into an boost::ulong_long_type value.
cpp_dec_float<Digits10, ExponentType, Allocator> xn(extract_integer_part());
if(xn.isneg())
xn.negate();
- val = static_cast<unsigned long long>(xn.data[0]);
+ val = static_cast<boost::ulong_long_type>(xn.data[0]);
const boost::int32_t imax = (std::min)(static_cast<boost::int32_t>(static_cast<boost::int32_t>(xn.exp) / cpp_dec_float_elem_digits10), static_cast<boost::int32_t>(cpp_dec_float_elem_number - static_cast<boost::int32_t>(1)));
for(boost::int32_t i = static_cast<boost::int32_t>(1); i <= imax; i++)
{
- val *= static_cast<unsigned long long>(cpp_dec_float_elem_mask);
- val += static_cast<unsigned long long>(xn.data[i]);
+ val *= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask);
+ val += static_cast<boost::ulong_long_type>(xn.data[i]);
}
}
if (!b_neg)
{
- return static_cast<signed long long>(val);
+ return static_cast<boost::long_long_type>(val);
}
else
{
// This strange expression avoids a hardware trap in the corner case
- // that val is the most negative value permitted in long long.
+ // that val is the most negative value permitted in boost::long_long_type.
// See https://svn.boost.org/trac/boost/ticket/9740.
//
- signed long long sval = static_cast<signed long long>(val - 1);
+ boost::long_long_type sval = static_cast<boost::long_long_type>(val - 1);
sval = -sval;
--sval;
return sval;
@@ -1643,43 +1648,43 @@ signed long long cpp_dec_float<Digits10, ExponentType, Allocator>::extract_signe
}
template <unsigned Digits10, class ExponentType, class Allocator>
-unsigned long long cpp_dec_float<Digits10, ExponentType, Allocator>::extract_unsigned_long_long() const
+boost::ulong_long_type cpp_dec_float<Digits10, ExponentType, Allocator>::extract_unsigned_long_long() const
{
- // Extracts an unsigned long long from *this.
- // If x exceeds the maximum of unsigned long long,
- // then the maximum of unsigned long long is returned.
- // If x is negative, then the unsigned long long cast of
- // the signed long long extracted value is returned.
+ // Extracts an boost::ulong_long_type from *this.
+ // If x exceeds the maximum of boost::ulong_long_type,
+ // then the maximum of boost::ulong_long_type is returned.
+ // If x is negative, then the boost::ulong_long_type cast of
+ // the long long extracted value is returned.
if(isneg())
{
- return static_cast<unsigned long long>(extract_signed_long_long());
+ return static_cast<boost::ulong_long_type>(extract_signed_long_long());
}
if(exp < static_cast<ExponentType>(0))
{
- return static_cast<unsigned long long>(0u);
+ return static_cast<boost::ulong_long_type>(0u);
}
const cpp_dec_float<Digits10, ExponentType, Allocator> xn(extract_integer_part());
- unsigned long long val;
+ boost::ulong_long_type val;
if(xn.compare(ulong_long_max()) > 0)
{
- return (std::numeric_limits<unsigned long long>::max)();
+ return (std::numeric_limits<boost::ulong_long_type>::max)();
}
else
{
- // Extract the data into an unsigned long long value.
- val = static_cast<unsigned long long>(xn.data[0]);
+ // Extract the data into an boost::ulong_long_type value.
+ val = static_cast<boost::ulong_long_type>(xn.data[0]);
const boost::int32_t imax = (std::min)(static_cast<boost::int32_t>(static_cast<boost::int32_t>(xn.exp) / cpp_dec_float_elem_digits10), static_cast<boost::int32_t>(cpp_dec_float_elem_number - static_cast<boost::int32_t>(1)));
for(boost::int32_t i = static_cast<boost::int32_t>(1); i <= imax; i++)
{
- val *= static_cast<unsigned long long>(cpp_dec_float_elem_mask);
- val += static_cast<unsigned long long>(xn.data[i]);
+ val *= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask);
+ val += static_cast<boost::ulong_long_type>(xn.data[i]);
}
}
@@ -2209,8 +2214,8 @@ cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float(const double man
template <unsigned Digits10, class ExponentType, class Allocator>
cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator= (long double a)
{
- // Christopher Kormanyos's original code used a cast to long long here, but that fails
- // when long double has more digits than a long long.
+ // Christopher Kormanyos's original code used a cast to boost::long_long_type here, but that fails
+ // when long double has more digits than a boost::long_long_type.
using std::frexp;
using std::ldexp;
using std::floor;
@@ -2259,7 +2264,7 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone
}
template <unsigned Digits10, class ExponentType, class Allocator>
-void cpp_dec_float<Digits10, ExponentType, Allocator>::from_unsigned_long_long(const unsigned long long u)
+void cpp_dec_float<Digits10, ExponentType, Allocator>::from_unsigned_long_long(const boost::ulong_long_type u)
{
std::fill(data.begin(), data.end(), static_cast<boost::uint32_t>(0u));
@@ -2270,14 +2275,14 @@ void cpp_dec_float<Digits10, ExponentType, Allocator>::from_unsigned_long_long(c
std::size_t i =static_cast<std::size_t>(0u);
- unsigned long long uu = u;
+ boost::ulong_long_type uu = u;
- boost::uint32_t temp[(std::numeric_limits<unsigned long long>::digits10 / static_cast<int>(cpp_dec_float_elem_digits10)) + 3] = { static_cast<boost::uint32_t>(0u) };
+ boost::uint32_t temp[(std::numeric_limits<boost::ulong_long_type>::digits10 / static_cast<int>(cpp_dec_float_elem_digits10)) + 3] = { static_cast<boost::uint32_t>(0u) };
- while(uu != static_cast<unsigned long long>(0u))
+ while(uu != static_cast<boost::ulong_long_type>(0u))
{
- temp[i] = static_cast<boost::uint32_t>(uu % static_cast<unsigned long long>(cpp_dec_float_elem_mask));
- uu = static_cast<unsigned long long>(uu / static_cast<unsigned long long>(cpp_dec_float_elem_mask));
+ temp[i] = static_cast<boost::uint32_t>(uu % static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask));
+ uu = static_cast<boost::ulong_long_type>(uu / static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask));
++i;
}
@@ -2351,7 +2356,7 @@ boost::uint32_t cpp_dec_float<Digits10, ExponentType, Allocator>::div_loop_n(boo
}
template <unsigned Digits10, class ExponentType, class Allocator>
-cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(const long long p)
+cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(const boost::long_long_type p)
{
// Create a static const table of p^2 for -128 < p < +128.
// Note: The size of this table must be odd-numbered and
@@ -2488,24 +2493,24 @@ cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, Exponen
cpp_dec_float("0.5"),
one(),
two(),
- cpp_dec_float(static_cast<unsigned long long>(4)),
- cpp_dec_float(static_cast<unsigned long long>(8)),
- cpp_dec_float(static_cast<unsigned long long>(16)),
- cpp_dec_float(static_cast<unsigned long long>(32)),
- cpp_dec_float(static_cast<unsigned long long>(64)),
- cpp_dec_float(static_cast<unsigned long long>(128)),
- cpp_dec_float(static_cast<unsigned long long>(256)),
- cpp_dec_float(static_cast<unsigned long long>(512)),
- cpp_dec_float(static_cast<unsigned long long>(1024)),
- cpp_dec_float(static_cast<unsigned long long>(2048)),
- cpp_dec_float(static_cast<unsigned long long>(4096)),
- cpp_dec_float(static_cast<unsigned long long>(8192)),
- cpp_dec_float(static_cast<unsigned long long>(16384)),
- cpp_dec_float(static_cast<unsigned long long>(32768)),
- cpp_dec_float(static_cast<unsigned long long>(65536)),
- cpp_dec_float(static_cast<unsigned long long>(131072)),
- cpp_dec_float(static_cast<unsigned long long>(262144)),
- cpp_dec_float(static_cast<unsigned long long>(524288)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(4)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(8)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(16)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(32)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(64)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(128)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(256)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(512)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(1024)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(2048)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(4096)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(8192)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(16384)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(32768)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(65536)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(131072)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(262144)),
+ cpp_dec_float(static_cast<boost::ulong_long_type>(524288)),
cpp_dec_float(static_cast<boost::uint64_t>(1uL << 20u)),
cpp_dec_float(static_cast<boost::uint64_t>(1uL << 21u)),
cpp_dec_float(static_cast<boost::uint64_t>(1uL << 22u)),
@@ -2616,16 +2621,16 @@ cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, Exponen
cpp_dec_float("1.701411834604692317316873037158841057280000000000000000000000000000000000000000000000000000000000000e38")
}};
- if((p > static_cast<long long>(-128)) && (p < static_cast<long long>(+128)))
+ if((p > static_cast<boost::long_long_type>(-128)) && (p < static_cast<boost::long_long_type>(+128)))
{
return p2_data[static_cast<std::size_t>(p + ((p2_data.size() - 1u) / 2u))];
}
else
{
// Compute and return 2^p.
- if(p < static_cast<long long>(0))
+ if(p < static_cast<boost::long_long_type>(0))
{
- return pow2(static_cast<long long>(-p)).calculate_inv();
+ return pow2(static_cast<boost::long_long_type>(-p)).calculate_inv();
}
else
{
@@ -2659,28 +2664,28 @@ inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result
}
template <unsigned Digits10, class ExponentType, class Allocator>
-inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const unsigned long long& o)
+inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o)
{
result.add_unsigned_long_long(o);
}
template <unsigned Digits10, class ExponentType, class Allocator>
-inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const unsigned long long& o)
+inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o)
{
result.sub_unsigned_long_long(o);
}
template <unsigned Digits10, class ExponentType, class Allocator>
-inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const unsigned long long& o)
+inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o)
{
result.mul_unsigned_long_long(o);
}
template <unsigned Digits10, class ExponentType, class Allocator>
-inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const unsigned long long& o)
+inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o)
{
result.div_unsigned_long_long(o);
}
template <unsigned Digits10, class ExponentType, class Allocator>
-inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, long long o)
+inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o)
{
if(o < 0)
result.sub_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(o));
@@ -2688,7 +2693,7 @@ inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, l
result.add_unsigned_long_long(o);
}
template <unsigned Digits10, class ExponentType, class Allocator>
-inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, long long o)
+inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o)
{
if(o < 0)
result.add_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(o));
@@ -2696,7 +2701,7 @@ inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& resu
result.sub_unsigned_long_long(o);
}
template <unsigned Digits10, class ExponentType, class Allocator>
-inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, long long o)
+inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o)
{
if(o < 0)
{
@@ -2707,7 +2712,7 @@ inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& resu
result.mul_unsigned_long_long(o);
}
template <unsigned Digits10, class ExponentType, class Allocator>
-inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, long long o)
+inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o)
{
if(o < 0)
{
@@ -2719,12 +2724,12 @@ inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result
}
template <unsigned Digits10, class ExponentType, class Allocator>
-inline void eval_convert_to(unsigned long long* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
+inline void eval_convert_to(boost::ulong_long_type* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
{
*result = val.extract_unsigned_long_long();
}
template <unsigned Digits10, class ExponentType, class Allocator>
-inline void eval_convert_to(long long* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
+inline void eval_convert_to(boost::long_long_type* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
{
*result = val.extract_signed_long_long();
}
@@ -2834,18 +2839,18 @@ inline void eval_scalbn(cpp_dec_float<Digits10, ExponentType, Allocator>& result
template <unsigned Digits10, class ExponentType, class Allocator, class ArgType>
inline void eval_ldexp(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x, ArgType e)
{
- const long long the_exp = static_cast<long long>(e);
+ const boost::long_long_type the_exp = static_cast<boost::long_long_type>(e);
if((the_exp > (std::numeric_limits<ExponentType>::max)()) || (the_exp < (std::numeric_limits<ExponentType>::min)()))
BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Exponent value is out of range.")));
result = x;
- if ((the_exp > static_cast<long long>(-std::numeric_limits<long long>::digits)) && (the_exp < static_cast<long long>(0)))
- result.div_unsigned_long_long(1ULL << static_cast<long long>(-the_exp));
- else if((the_exp < static_cast<long long>( std::numeric_limits<long long>::digits)) && (the_exp > static_cast<long long>(0)))
+ if ((the_exp > static_cast<boost::long_long_type>(-std::numeric_limits<boost::long_long_type>::digits)) && (the_exp < static_cast<boost::long_long_type>(0)))
+ result.div_unsigned_long_long(1ULL << static_cast<boost::long_long_type>(-the_exp));
+ else if((the_exp < static_cast<boost::long_long_type>( std::numeric_limits<boost::long_long_type>::digits)) && (the_exp > static_cast<boost::long_long_type>(0)))
result.mul_unsigned_long_long(1ULL << the_exp);
- else if(the_exp != static_cast<long long>(0))
+ else if(the_exp != static_cast<boost::long_long_type>(0))
result *= cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(e);
}
@@ -3078,4 +3083,8 @@ struct precision< boost::multiprecision::number<boost::multiprecision::cpp_dec_f
}} // namespaces boost::math
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
#endif
diff --git a/boost/multiprecision/cpp_int.hpp b/boost/multiprecision/cpp_int.hpp
index 311f7c16da..d451567bb9 100644
--- a/boost/multiprecision/cpp_int.hpp
+++ b/boost/multiprecision/cpp_int.hpp
@@ -35,7 +35,7 @@ namespace backends{
#ifdef BOOST_MSVC
// warning C4127: conditional expression is constant
#pragma warning(push)
-#pragma warning(disable:4127 4351 4293 4996 4307 4702)
+#pragma warning(disable:4127 4351 4293 4996 4307 4702 6285)
#endif
template <unsigned MinBits = 0, unsigned MaxBits = 0, cpp_integer_type SignType = signed_magnitude, cpp_int_check_type Checked = unchecked, class Allocator = typename mpl::if_c<MinBits && (MinBits == MaxBits), void, std::allocator<limb_type> >::type >
@@ -181,8 +181,8 @@ public:
BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = 1u << (limb_bits - 1));
BOOST_STATIC_CONSTANT(unsigned, internal_limb_count =
MinBits
- ? MinBits / limb_bits + (MinBits % limb_bits ? 1 : 0)
- : sizeof(limb_data) / sizeof(limb_type));
+ ? (MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0))
+ : (sizeof(limb_data) / sizeof(limb_type)));
BOOST_STATIC_CONSTANT(bool, variable = true);
private:
@@ -243,7 +243,7 @@ public:
}
void resize(unsigned new_size, unsigned min_size)
{
- static const unsigned max_limbs = MaxBits / (CHAR_BIT * sizeof(limb_type)) + (MaxBits % (CHAR_BIT * sizeof(limb_type)) ? 1 : 0);
+ static const unsigned max_limbs = MaxBits / (CHAR_BIT * sizeof(limb_type)) + ((MaxBits % (CHAR_BIT * sizeof(limb_type))) ? 1 : 0);
// We never resize beyond MaxSize:
if(new_size > max_limbs)
new_size = max_limbs;
@@ -402,9 +402,9 @@ public:
BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(limb_type) * CHAR_BIT);
BOOST_STATIC_CONSTANT(limb_type, max_limb_value = ~static_cast<limb_type>(0u));
BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = 1u << (limb_bits - 1));
- BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + (MinBits % limb_bits ? 1 : 0));
+ BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0));
BOOST_STATIC_CONSTANT(bool, variable = false);
- BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = MinBits % limb_bits ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0)));
+ BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = (MinBits % limb_bits) ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0)));
BOOST_STATIC_ASSERT_MSG(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs");
private:
@@ -466,12 +466,12 @@ public:
m_sign = false;
}
}
- BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_NOEXCEPT_IF((Checked == unchecked))
+ BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
{
m_limbs = static_cast<boost::uint16_t>((std::min)(new_size, internal_limb_count));
detail::verify_new_size(m_limbs, min_size, checked_type());
}
- BOOST_MP_FORCEINLINE void normalize() BOOST_NOEXCEPT_IF((Checked == unchecked))
+ BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
{
limb_pointer p = limbs();
detail::verify_limb_mask(m_limbs == internal_limb_count, p[internal_limb_count-1], upper_limb_mask, checked_type());
@@ -554,9 +554,9 @@ public:
BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(limb_type) * CHAR_BIT);
BOOST_STATIC_CONSTANT(limb_type, max_limb_value = ~static_cast<limb_type>(0u));
BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = 1u << (limb_bits - 1));
- BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + (MinBits % limb_bits ? 1 : 0));
+ BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0));
BOOST_STATIC_CONSTANT(bool, variable = false);
- BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = MinBits % limb_bits ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0)));
+ BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = (MinBits % limb_bits) ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0)));
BOOST_STATIC_ASSERT_MSG(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs");
private:
@@ -581,12 +581,12 @@ public:
//
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT
: m_wrapper(i), m_limbs(1) {}
- BOOST_MP_FORCEINLINE cpp_int_base(signed_limb_type i)BOOST_NOEXCEPT_IF((Checked == unchecked))
+ BOOST_MP_FORCEINLINE cpp_int_base(signed_limb_type i)BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
: m_wrapper(limb_type(i < 0 ? static_cast<limb_type>(-static_cast<signed_double_limb_type>(i)) : i)), m_limbs(1) { if(i < 0) negate(); }
#ifdef BOOST_LITTLE_ENDIAN
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT
: m_wrapper(i), m_limbs(i > max_limb_value ? 2 : 1) {}
- BOOST_MP_FORCEINLINE cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT_IF((Checked == unchecked))
+ BOOST_MP_FORCEINLINE cpp_int_base(signed_double_limb_type i)BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
: m_wrapper(double_limb_type(i < 0 ? static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) : i)),
m_limbs(i < 0 ? (static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1))
{
@@ -607,13 +607,13 @@ public:
BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return m_wrapper.m_data; }
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const_limb_pointer limbs()const BOOST_NOEXCEPT { return m_wrapper.m_data; }
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool sign()const BOOST_NOEXCEPT { return false; }
- BOOST_MP_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT_IF((Checked == unchecked)) { if(b) negate(); }
- BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_NOEXCEPT_IF((Checked == unchecked))
+ BOOST_MP_FORCEINLINE void sign(bool b) BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { if(b) negate(); }
+ BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
{
m_limbs = (std::min)(new_size, internal_limb_count);
detail::verify_new_size(m_limbs, min_size, checked_type());
}
- BOOST_MP_FORCEINLINE void normalize() BOOST_NOEXCEPT_IF((Checked == unchecked))
+ BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
{
limb_pointer p = limbs();
detail::verify_limb_mask(m_limbs == internal_limb_count, p[internal_limb_count-1], upper_limb_mask, checked_type());
@@ -643,7 +643,7 @@ private:
}
void check_negate(const mpl::int_<unchecked>&){}
public:
- void negate() BOOST_NOEXCEPT_IF((Checked == unchecked))
+ void negate() BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
{
// Not so much a negate as a complement - this gets called when subtraction
// would result in a "negative" number:
@@ -689,7 +689,7 @@ const bool cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, fal
#endif
//
// Traits classes to figure out a native type with N bits, these vary from boost::uint_t<N> only
-// because some platforms have native integer types longer than long long, "really long long" anyone??
+// because some platforms have native integer types longer than boost::long_long_type, "really boost::long_long_type" anyone??
//
template <unsigned N, bool s>
struct trivial_limb_type_imp
@@ -704,7 +704,7 @@ struct trivial_limb_type_imp<N, true>
};
template <unsigned N>
-struct trivial_limb_type : public trivial_limb_type_imp<N, N <= sizeof(long long) * CHAR_BIT> {};
+struct trivial_limb_type : public trivial_limb_type_imp<N, N <= sizeof(boost::long_long_type) * CHAR_BIT> {};
//
// Backend for fixed precision signed-magnitude type which will fit entirely inside a "double_limb_type":
//
@@ -750,7 +750,7 @@ protected:
void check_in_range(T, const mpl::int_<C>&) BOOST_NOEXCEPT {}
template <class T>
- void check_in_range(T val) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type())))
+ void check_in_range(T val) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type())))
{
check_in_range(val, checked_type());
}
@@ -760,17 +760,17 @@ public:
// Direct construction:
//
template <class SI>
- BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
+ BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == unchecked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
: m_data(i < 0 ? static_cast<local_limb_type>(static_cast<typename make_unsigned<SI>::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask) : static_cast<local_limb_type>(i)& limb_mask), m_sign(i < 0) {}
template <class SI>
- BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == checked) >::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
+ BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
: m_data(i < 0 ? (static_cast<local_limb_type>(static_cast<typename make_unsigned<SI>::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask)) : static_cast<local_limb_type>(i)& limb_mask), m_sign(i < 0)
{ check_in_range(i); }
template <class UI>
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == unchecked)>::type const* = 0) BOOST_NOEXCEPT
: m_data(static_cast<local_limb_type>(i) & limb_mask), m_sign(false) {}
template <class UI>
- BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == checked)>::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>())))
+ BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == checked)>::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>())))
: m_data(static_cast<local_limb_type>(i) & limb_mask), m_sign(false) { check_in_range(i); }
template <class F>
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(F i, typename boost::enable_if_c<is_floating_point<F>::value && (Checked == unchecked)>::type const* = 0) BOOST_NOEXCEPT
@@ -810,7 +810,7 @@ public:
{
detail::verify_new_size(2, min_size, checked_type());
}
- BOOST_MP_FORCEINLINE void normalize() BOOST_NOEXCEPT_IF((Checked == unchecked))
+ BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
{
if(!m_data)
m_sign = false; // zero is always unsigned
@@ -893,7 +893,7 @@ protected:
BOOST_MP_FORCEINLINE void check_in_range(T, const mpl::int_<C>&, const boost::integral_constant<bool, B>&) BOOST_NOEXCEPT {}
template <class T>
- BOOST_MP_FORCEINLINE void check_in_range(T val) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type(), is_signed<T>())))
+ BOOST_MP_FORCEINLINE void check_in_range(T val) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type(), is_signed<T>())))
{
check_in_range(val, checked_type(), is_signed<T>());
}
@@ -906,16 +906,16 @@ public:
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT
: m_data(i < 0 ? (1 + ~static_cast<local_limb_type>(-i)) & limb_mask : static_cast<local_limb_type>(i) & limb_mask) {}
template <class SI>
- BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == checked) >::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
+ BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
: m_data(i < 0 ? 1 + ~static_cast<local_limb_type>(-i) : static_cast<local_limb_type>(i)) { check_in_range(i); }
template <class UI>
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT
: m_data(static_cast<local_limb_type>(i) & limb_mask) {}
template <class UI>
- BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == checked) >::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>())))
+ BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>())))
: m_data(static_cast<local_limb_type>(i)) { check_in_range(i); }
template <class F>
- BOOST_MP_FORCEINLINE cpp_int_base(F i, typename boost::enable_if<is_floating_point<F> >::type const* = 0) BOOST_NOEXCEPT_IF((Checked == unchecked))
+ BOOST_MP_FORCEINLINE cpp_int_base(F i, typename boost::enable_if<is_floating_point<F> >::type const* = 0) BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
: m_data(static_cast<local_limb_type>(std::fabs(i)) & limb_mask)
{
check_in_range(i);
@@ -939,7 +939,7 @@ public:
BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return &m_data; }
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const_limb_pointer limbs()const BOOST_NOEXCEPT { return &m_data; }
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool sign()const BOOST_NOEXCEPT { return false; }
- BOOST_MP_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT_IF((Checked == unchecked))
+ BOOST_MP_FORCEINLINE void sign(bool b) BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
{
if(b)
negate();
@@ -948,7 +948,7 @@ public:
{
detail::verify_new_size(2, min_size, checked_type());
}
- BOOST_MP_FORCEINLINE void normalize() BOOST_NOEXCEPT_IF((Checked == unchecked))
+ BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
{
detail::verify_limb_mask(true, m_data, limb_mask, checked_type());
m_data &= limb_mask;
@@ -962,7 +962,7 @@ public:
{
m_data = o.m_data;
}
- BOOST_MP_FORCEINLINE void negate() BOOST_NOEXCEPT_IF((Checked == unchecked))
+ BOOST_MP_FORCEINLINE void negate() BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
{
if(Checked == checked)
{
@@ -1025,13 +1025,13 @@ public:
trivial_tag,
mpl::list<
signed char, short, int, long,
- long long, signed_double_limb_type>,
+ boost::long_long_type, signed_double_limb_type>,
mpl::list<signed_limb_type, signed_double_limb_type>
>::type signed_types;
typedef typename mpl::if_<
trivial_tag,
mpl::list<unsigned char, unsigned short, unsigned,
- unsigned long, unsigned long long, double_limb_type>,
+ unsigned long, boost::ulong_long_type, double_limb_type>,
mpl::list<limb_type, double_limb_type>
>::type unsigned_types;
typedef typename mpl::if_<
@@ -1042,7 +1042,7 @@ public:
typedef mpl::int_<Checked> checked_type;
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend() BOOST_NOEXCEPT{}
- BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(const cpp_int_backend& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value) : base_type(o) {}
+ BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF(boost::is_void<Allocator>::value) : base_type(o) {}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(cpp_int_backend&& o) BOOST_NOEXCEPT
: base_type(static_cast<base_type&&>(o)) {}
@@ -1051,7 +1051,7 @@ public:
// Direct construction from arithmetic type:
//
template <class Arg>
- BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(Arg i, typename boost::enable_if_c<is_allowed_cpp_int_base_conversion<Arg, base_type>::value >::type const* = 0)BOOST_NOEXCEPT_IF(noexcept(base_type(std::declval<Arg>())))
+ BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(Arg i, typename boost::enable_if_c<is_allowed_cpp_int_base_conversion<Arg, base_type>::value >::type const* = 0)BOOST_MP_NOEXCEPT_IF(noexcept(base_type(std::declval<Arg>())))
: base_type(i) {}
private:
@@ -1140,13 +1140,13 @@ public:
: base_type(static_cast<const base_type&>(a), tag){}
#endif
- BOOST_MP_FORCEINLINE cpp_int_backend& operator = (const cpp_int_backend& o) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().assign(std::declval<const cpp_int_backend&>())))
+ BOOST_MP_FORCEINLINE cpp_int_backend& operator = (const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().assign(std::declval<const cpp_int_backend&>())))
{
this->assign(o);
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- BOOST_MP_FORCEINLINE cpp_int_backend& operator = (cpp_int_backend&& o) BOOST_NOEXCEPT_IF(noexcept(std::declval<base_type&>() = std::declval<base_type>()))
+ BOOST_MP_FORCEINLINE cpp_int_backend& operator = (cpp_int_backend&& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<base_type&>() = std::declval<base_type>()))
{
*static_cast<base_type*>(this) = static_cast<base_type&&>(o);
return *this;
@@ -1155,7 +1155,7 @@ public:
private:
template <class A>
typename boost::enable_if<is_unsigned<A> >::type do_assign_arithmetic(A val, const mpl::true_&)
- BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().check_in_range(std::declval<A>())))
+ BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().check_in_range(std::declval<A>())))
{
this->check_in_range(val);
*this->limbs() = static_cast<typename self_type::local_limb_type>(val);
@@ -1163,7 +1163,7 @@ private:
}
template <class A>
typename boost::disable_if_c<is_unsigned<A>::value || !is_integral<A>::value >::type do_assign_arithmetic(A val, const mpl::true_&)
- BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().check_in_range(std::declval<A>())) && noexcept(std::declval<cpp_int_backend>().sign(true)))
+ BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().check_in_range(std::declval<A>())) && noexcept(std::declval<cpp_int_backend>().sign(true)))
{
this->check_in_range(val);
*this->limbs() = (val < 0) ? static_cast<typename self_type::local_limb_type>(boost::multiprecision::detail::unsigned_abs(val)) : static_cast<typename self_type::local_limb_type>(val);
@@ -1184,7 +1184,7 @@ private:
*this->limbs() = i;
this->sign(false);
}
- BOOST_MP_FORCEINLINE void do_assign_arithmetic(signed_limb_type i, const mpl::false_&) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().sign(true)))
+ BOOST_MP_FORCEINLINE void do_assign_arithmetic(signed_limb_type i, const mpl::false_&) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().sign(true)))
{
this->resize(1, 1);
*this->limbs() = static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(i));
@@ -1200,7 +1200,7 @@ private:
this->resize(p[1] ? 2 : 1, p[1] ? 2 : 1);
this->sign(false);
}
- void do_assign_arithmetic(signed_double_limb_type i, const mpl::false_&) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().sign(true)))
+ void do_assign_arithmetic(signed_double_limb_type i, const mpl::false_&) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().sign(true)))
{
BOOST_STATIC_ASSERT(sizeof(i) == 2 * sizeof(limb_type));
BOOST_STATIC_ASSERT(base_type::internal_limb_count >= 2);
@@ -1224,6 +1224,13 @@ private:
using std::ldexp;
using std::floor;
+ if(a < 0)
+ {
+ do_assign_arithmetic(-a, mpl::false_());
+ this->sign(true);
+ return;
+ }
+
if (a == 0) {
*this = static_cast<limb_type>(0u);
}
@@ -1263,7 +1270,7 @@ private:
}
public:
template <class Arithmetic>
- BOOST_MP_FORCEINLINE cpp_int_backend& operator = (Arithmetic val) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().do_assign_arithmetic(std::declval<Arithmetic>(), trivial_tag())))
+ BOOST_MP_FORCEINLINE cpp_int_backend& operator = (Arithmetic val) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().do_assign_arithmetic(std::declval<Arithmetic>(), trivial_tag())))
{
do_assign_arithmetic(val, trivial_tag());
return *this;
@@ -1548,7 +1555,7 @@ private:
limb_type shift = base == 8 ? 3 : 4;
limb_type mask = static_cast<limb_type>((1u << shift) - 1);
cpp_int_backend t(*this);
- result.assign(Bits / shift + (Bits % shift ? 1 : 0), '0');
+ result.assign(Bits / shift + ((Bits % shift) ? 1 : 0), '0');
std::string::difference_type pos = result.size() - 1;
for(unsigned i = 0; i < Bits / shift; ++i)
{
diff --git a/boost/multiprecision/cpp_int/add.hpp b/boost/multiprecision/cpp_int/add.hpp
index f9c9b85ebb..372998d672 100644
--- a/boost/multiprecision/cpp_int/add.hpp
+++ b/boost/multiprecision/cpp_int/add.hpp
@@ -14,7 +14,7 @@ namespace boost{ namespace multiprecision{ namespace backends{
// This is the key addition routine where all the argument types are non-trivial cpp_int's:
//
template <class CppInt1, class CppInt2, class CppInt3>
-inline void add_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BOOST_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value)
+inline void add_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BOOST_MP_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value)
{
using std::swap;
@@ -81,7 +81,7 @@ inline void add_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BO
// As above, but for adding a single limb to a non-trivial cpp_int:
//
template <class CppInt1, class CppInt2>
-inline void add_unsigned(CppInt1& result, const CppInt2& a, const limb_type& o) BOOST_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value)
+inline void add_unsigned(CppInt1& result, const CppInt2& a, const limb_type& o) BOOST_MP_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value)
{
// Addition using modular arithmetic.
// Nothing fancy, just let uintmax_t take the strain:
@@ -119,7 +119,7 @@ inline void add_unsigned(CppInt1& result, const CppInt2& a, const limb_type& o)
// Core subtraction routine for all non-trivial cpp_int's:
//
template <class CppInt1, class CppInt2, class CppInt3>
-inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BOOST_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value)
+inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BOOST_MP_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value)
{
using std::swap;
@@ -203,7 +203,7 @@ inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const CppInt3&
// And again to subtract a single limb:
//
template <class CppInt1, class CppInt2>
-inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const limb_type& b) BOOST_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value)
+inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const limb_type& b) BOOST_MP_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value)
{
// Subtract one limb.
// Nothing fancy, just let uintmax_t take the strain:
@@ -264,7 +264,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
eval_add(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
eval_add(result, result, o);
}
@@ -273,7 +273,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
eval_add(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
- const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(a.sign() != b.sign())
{
@@ -284,7 +284,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
- eval_add(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ eval_add(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(result.sign())
{
@@ -298,7 +298,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi
eval_add(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
- const limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(a.sign())
{
@@ -311,7 +311,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
eval_add(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const signed_limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(o < 0)
eval_subtract(result, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o)));
@@ -323,7 +323,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi
eval_add(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
- const signed_limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(o < 0)
eval_subtract(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o)));
@@ -336,7 +336,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
eval_subtract(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(result.sign())
{
@@ -350,7 +350,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi
eval_subtract(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
- const limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(a.sign())
{
@@ -365,7 +365,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
eval_subtract(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const signed_limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(o)
{
@@ -380,7 +380,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi
eval_subtract(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
- const signed_limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(o)
{
@@ -395,7 +395,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
- eval_increment(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ eval_increment(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
static const limb_type one = 1;
if(!result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value))
@@ -407,7 +407,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
- eval_decrement(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ eval_decrement(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
static const limb_type one = 1;
if(!result.sign() && result.limbs()[0])
@@ -421,7 +421,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
eval_subtract(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
eval_subtract(result, result, o);
}
@@ -430,7 +430,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi
eval_subtract(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
- const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(a.sign() != b.sign())
{
@@ -453,7 +453,7 @@ inline typename enable_if_c<
>::type
eval_add(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(result.sign() != o.sign())
{
@@ -478,7 +478,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<
&& is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
>::type
eval_add(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
result.normalize();
@@ -493,7 +493,7 @@ inline typename enable_if_c<
>::type
eval_subtract(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(result.sign() != o.sign())
{
@@ -518,7 +518,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<
>::type
eval_subtract(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
result.normalize();
diff --git a/boost/multiprecision/cpp_int/bitwise.hpp b/boost/multiprecision/cpp_int/bitwise.hpp
index 98277d69fe..a39e2590cb 100644
--- a/boost/multiprecision/cpp_int/bitwise.hpp
+++ b/boost/multiprecision/cpp_int/bitwise.hpp
@@ -24,11 +24,27 @@ void is_valid_bitwise_op(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& , const mpl::int_<unchecked>&){}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_int_check_type Checked1, class Allocator1>
+void is_valid_bitwise_op(
+ const cpp_int_backend<MinBits1, MaxBits1, signed_magnitude, Checked1, Allocator1>& result, const mpl::int_<checked>&)
+{
+ if(result.sign())
+ BOOST_THROW_EXCEPTION(std::range_error("Bitwise operations on negative values results in undefined behavior."));
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_int_check_type Checked1, class Allocator1>
+void is_valid_bitwise_op(
+ const cpp_int_backend<MinBits1, MaxBits1, unsigned_magnitude, Checked1, Allocator1>&, const mpl::int_<checked>&){}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+void is_valid_bitwise_op(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&, const mpl::int_<unchecked>&){}
+
template <class CppInt1, class CppInt2, class Op>
void bitwise_op(
CppInt1& result,
const CppInt2& o,
- Op op, const mpl::true_&) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<CppInt1>::value))
+ Op op, const mpl::true_&) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<CppInt1>::value))
{
//
// There are 4 cases:
@@ -143,7 +159,6 @@ void bitwise_op(
//
if(static_cast<signed_limb_type>(next_limb) < 0)
{
- result.sign(true);
double_limb_type carry = 1;
for(unsigned i = 0; i < x; ++i)
{
@@ -151,6 +166,13 @@ void bitwise_op(
pr[i] = static_cast<limb_type>(carry);
carry >>= CppInt1::limb_bits;
}
+ if(carry)
+ {
+ result.resize(x + 1, x);
+ if(result.size() > x)
+ result.limbs()[x] = static_cast<limb_type>(carry);
+ }
+ result.sign(true);
}
else
result.sign(false);
@@ -162,7 +184,7 @@ template <class CppInt1, class CppInt2, class Op>
void bitwise_op(
CppInt1& result,
const CppInt2& o,
- Op op, const mpl::false_&) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<CppInt1>::value))
+ Op op, const mpl::false_&) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<CppInt1>::value))
{
//
// Both arguments are unsigned types, very simple case handled as a special case.
@@ -195,7 +217,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
eval_bitwise_and(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
bitwise_op(result, o, bit_and(),
mpl::bool_<std::numeric_limits<number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::is_signed || std::numeric_limits<number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> > >::is_signed>());
@@ -205,7 +227,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
eval_bitwise_or(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
bitwise_op(result, o, bit_or(),
mpl::bool_<std::numeric_limits<number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::is_signed || std::numeric_limits<number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> > >::is_signed>());
@@ -215,7 +237,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
eval_bitwise_xor(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
bitwise_op(result, o, bit_xor(),
mpl::bool_<std::numeric_limits<number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::is_signed || std::numeric_limits<number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> > >::is_signed>());
@@ -255,7 +277,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_
BOOST_MP_FORCEINLINE typename enable_if_c<is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
eval_complement(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
BOOST_STATIC_ASSERT_MSG(((Checked1 != checked) || (Checked2 != checked)), "Attempt to take the complement of a signed type results in undefined behavior.");
// Increment and negate:
@@ -268,7 +290,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_
BOOST_MP_FORCEINLINE typename enable_if_c<is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value >::type
eval_complement(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
unsigned os = o.size();
result.resize(UINT_MAX, os);
@@ -283,8 +305,9 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_
inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
eval_left_shift(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- double_limb_type s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ double_limb_type s) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
+ is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
if(!s)
return;
@@ -359,18 +382,26 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_
inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
eval_right_shift(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- double_limb_type s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ double_limb_type s) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
+ is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
if(!s)
return;
+ bool is_neg = result.sign();
+ if(is_neg)
+ eval_increment(result);
+
limb_type offset = static_cast<limb_type>(s / cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits);
limb_type shift = static_cast<limb_type>(s % cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits);
unsigned ors = result.size();
unsigned rs = ors;
if(offset >= rs)
{
- result = limb_type(0);
+ if(is_neg)
+ result = signed_limb_type(-1);
+ else
+ result = limb_type(0);
return;
}
rs -= offset;
@@ -379,7 +410,10 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
--rs;
if(rs == 0)
{
- result = limb_type(0);
+ if(is_neg)
+ result = signed_limb_type(-1);
+ else
+ result = limb_type(0);
return;
}
unsigned i = 0;
@@ -399,6 +433,8 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
pr[i] = pr[i + offset];
}
result.resize(rs, rs);
+ if(is_neg)
+ eval_decrement(result);
}
//
@@ -406,17 +442,19 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
//
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class T>
BOOST_MP_FORCEINLINE typename enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::type
- eval_left_shift(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, T s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ eval_left_shift(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, T s) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
+ is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
*result.limbs() = detail::checked_left_shift(*result.limbs(), s, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
result.normalize();
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class T>
BOOST_MP_FORCEINLINE typename enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::type
- eval_right_shift(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, T s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ eval_right_shift(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, T s) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
// Nothing to check here... just make sure we don't invoke undefined behavior:
+ is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
*result.limbs() = (static_cast<unsigned>(s) >= sizeof(*result.limbs()) * CHAR_BIT) ? 0 : *result.limbs() >> s;
}
@@ -428,7 +466,7 @@ inline typename enable_if_c<
>::type
eval_bitwise_and(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
@@ -465,7 +503,7 @@ inline typename enable_if_c<
>::type
eval_bitwise_and(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() &= *o.limbs();
}
@@ -478,7 +516,7 @@ inline typename enable_if_c<
>::type
eval_bitwise_or(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
@@ -516,7 +554,7 @@ inline typename enable_if_c<
>::type
eval_bitwise_or(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() |= *o.limbs();
}
@@ -529,7 +567,7 @@ inline typename enable_if_c<
>::type
eval_bitwise_xor(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
@@ -566,7 +604,7 @@ inline typename enable_if_c<
>::type
eval_bitwise_xor(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() ^= *o.limbs();
}
@@ -579,7 +617,7 @@ inline typename enable_if_c<
>::type
eval_complement(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
BOOST_STATIC_ASSERT_MSG(((Checked1 != checked) || (Checked2 != checked)), "Attempt to take the complement of a signed type results in undefined behavior.");
//
@@ -607,7 +645,7 @@ inline typename enable_if_c<
>::type
eval_complement(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() = ~*o.limbs();
result.normalize();
diff --git a/boost/multiprecision/cpp_int/checked.hpp b/boost/multiprecision/cpp_int/checked.hpp
index bf3bc650c0..cafe50ea49 100644
--- a/boost/multiprecision/cpp_int/checked.hpp
+++ b/boost/multiprecision/cpp_int/checked.hpp
@@ -128,7 +128,7 @@ inline A checked_divide(A a, A b, const mpl::int_<unchecked>&)
}
template <class A>
-inline A checked_left_shift(A a, unsigned long long shift, const mpl::int_<checked>&)
+inline A checked_left_shift(A a, boost::ulong_long_type shift, const mpl::int_<checked>&)
{
if(a && shift)
{
@@ -138,7 +138,7 @@ inline A checked_left_shift(A a, unsigned long long shift, const mpl::int_<check
return a << shift;
}
template <class A>
-inline A checked_left_shift(A a, unsigned long long shift, const mpl::int_<unchecked>&)
+inline A checked_left_shift(A a, boost::ulong_long_type shift, const mpl::int_<unchecked>&)
{
return (shift >= sizeof(A) * CHAR_BIT) ? 0 : a << shift;
}
diff --git a/boost/multiprecision/cpp_int/cpp_int_config.hpp b/boost/multiprecision/cpp_int/cpp_int_config.hpp
index 0b8b33d3a7..eb88f3da80 100644
--- a/boost/multiprecision/cpp_int/cpp_int_config.hpp
+++ b/boost/multiprecision/cpp_int/cpp_int_config.hpp
@@ -19,7 +19,7 @@ namespace detail{
//
// These traits calculate the largest type in the list
-// [unsigned] long long, long, int, which has the specified number
+// [unsigned] boost::long_long_type, long, int, which has the specified number
// of bits. Note that intN_t and boost::int_t<N> find the first
// member of the above list, not the last. We want the last in the
// list to ensure that mixed arithmetic operations are as efficient
@@ -29,8 +29,8 @@ template <unsigned N>
struct largest_signed_type
{
typedef typename mpl::if_c<
- 1 + std::numeric_limits<long long>::digits == N,
- long long,
+ 1 + std::numeric_limits<boost::long_long_type>::digits == N,
+ boost::long_long_type,
typename mpl::if_c<
1 + std::numeric_limits<long>::digits == N,
long,
@@ -47,8 +47,8 @@ template <unsigned N>
struct largest_unsigned_type
{
typedef typename mpl::if_c<
- std::numeric_limits<unsigned long long>::digits == N,
- unsigned long long,
+ std::numeric_limits<boost::ulong_long_type>::digits == N,
+ boost::ulong_long_type,
typename mpl::if_c<
std::numeric_limits<unsigned long>::digits == N,
unsigned long,
diff --git a/boost/multiprecision/cpp_int/divide.hpp b/boost/multiprecision/cpp_int/divide.hpp
index b5c9b5e220..c94bc71498 100644
--- a/boost/multiprecision/cpp_int/divide.hpp
+++ b/boost/multiprecision/cpp_int/divide.hpp
@@ -540,7 +540,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi
signed_limb_type b)
{
bool s = a.sign();
- divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>* >(0), a, static_cast<limb_type>(std::abs(b)), result);
+ divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>* >(0), a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(b)), result);
result.sign(s);
}
diff --git a/boost/multiprecision/cpp_int/misc.hpp b/boost/multiprecision/cpp_int/misc.hpp
index 266edac2ed..a124710c28 100644
--- a/boost/multiprecision/cpp_int/misc.hpp
+++ b/boost/multiprecision/cpp_int/misc.hpp
@@ -55,7 +55,7 @@ inline Integer negate_integer(Integer i, const mpl::false_&) BOOST_NOEXCEPT
template <class R, unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
inline typename enable_if_c<is_integral<R>::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, void>::type
- eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& backend) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& backend) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
typedef mpl::int_<Checked1> checked_type;
check_in_range<R>(backend, checked_type());
@@ -76,7 +76,7 @@ inline typename enable_if_c<is_integral<R>::value && !is_trivial_cpp_int<cpp_int
template <class R, unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
inline typename enable_if_c<is_floating_point<R>::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, void>::type
- eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& backend) BOOST_NOEXCEPT_IF(is_arithmetic<R>::value)
+ eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& backend) BOOST_MP_NOEXCEPT_IF(is_arithmetic<R>::value)
{
typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::const_limb_pointer p = backend.limbs();
unsigned shift = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
@@ -104,7 +104,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
- eval_abs(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ eval_abs(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
result = val;
result.sign(false);
@@ -234,7 +234,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& x,
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& y,
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& q,
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
divide_unsigned_helper(&q, x, y, r);
q.sign(x.sign() != y.sign());
@@ -247,7 +247,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& x,
limb_type y,
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& q,
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
divide_unsigned_helper(&q, x, y, r);
q.sign(x.sign());
@@ -259,7 +259,7 @@ inline typename enable_if_c<is_integral<U>::value>::type eval_qr(
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& x,
U y,
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& q,
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
using default_ops::eval_qr;
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(y);
@@ -511,7 +511,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<is_trivial_cpp_int<cpp_int_backend<Min
// This one is only enabled for unchecked cpp_int's, for checked int's we need the checking in the default version:
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && (Checked1 == unchecked)>::type
- eval_lcm(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ eval_lcm(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() = boost::integer::lcm(*a.limbs(), *b.limbs());
result.normalize(); // result may overflow the specified number of bits
diff --git a/boost/multiprecision/cpp_int/multiply.hpp b/boost/multiprecision/cpp_int/multiply.hpp
index fd569faa00..226bc9d192 100644
--- a/boost/multiprecision/cpp_int/multiply.hpp
+++ b/boost/multiprecision/cpp_int/multiply.hpp
@@ -15,7 +15,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
- const limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(!val)
{
@@ -67,7 +67,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
- const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
// Very simple long multiplication, only usable for small numbers of limb_type's
// but that's the typical use case for this type anyway:
@@ -130,10 +130,12 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
for(unsigned j = 0; j < inner_limit; ++j)
{
BOOST_ASSERT(i+j < result.size());
+#if (!defined(__GLIBCXX__) && !defined(__GLIBCPP__)) || !BOOST_WORKAROUND(BOOST_GCC_VERSION, <= 50100)
BOOST_ASSERT(!std::numeric_limits<double_limb_type>::is_specialized
|| ((std::numeric_limits<double_limb_type>::max)() - carry
>
static_cast<double_limb_type>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value) * static_cast<double_limb_type>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value)));
+#endif
carry += static_cast<double_limb_type>(pa[i]) * static_cast<double_limb_type>(pb[j]);
BOOST_ASSERT(!std::numeric_limits<double_limb_type>::is_specialized || ((std::numeric_limits<double_limb_type>::max)() - carry >= pr[i+j]));
carry += pr[i + j];
@@ -157,14 +159,14 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
eval_multiply(result, result, a);
}
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
- eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
eval_multiply(result, result, val);
}
@@ -174,7 +176,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
- const double_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(val <= (std::numeric_limits<limb_type>::max)())
{
@@ -189,7 +191,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
- eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const double_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
eval_multiply(result, result, val);
}
@@ -199,7 +201,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
- const signed_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const signed_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(val > 0)
eval_multiply(result, a, static_cast<limb_type>(val));
@@ -212,7 +214,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
- eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
eval_multiply(result, result, val);
}
@@ -222,7 +224,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
- const signed_double_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const signed_double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
if(val > 0)
{
@@ -244,7 +246,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
- eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_double_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
eval_multiply(result, result, val);
}
@@ -261,7 +263,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<
>::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
result.sign(result.sign() != o.sign());
@@ -275,7 +277,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<
>::type
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
result.normalize();
@@ -291,7 +293,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a,
- const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() = detail::checked_multiply(*a.limbs(), *b.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
result.sign(a.sign() != b.sign());
@@ -306,7 +308,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<
eval_multiply(
cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a,
- const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+ const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
{
*result.limbs() = detail::checked_multiply(*a.limbs(), *b.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
result.normalize();
diff --git a/boost/multiprecision/cpp_int/serialize.hpp b/boost/multiprecision/cpp_int/serialize.hpp
index bdf4758a6e..042a9f89f7 100644
--- a/boost/multiprecision/cpp_int/serialize.hpp
+++ b/boost/multiprecision/cpp_int/serialize.hpp
@@ -49,7 +49,7 @@ void do_serialize(Archive& ar, Int& val, mpl::false_ const&, mpl::false_ const&,
std::size_t limb_count;
std::size_t byte_count;
ar & byte_count;
- limb_count = byte_count / sizeof(limb_type) + (byte_count % sizeof(limb_type) ? 1 : 0);
+ limb_count = byte_count / sizeof(limb_type) + ((byte_count % sizeof(limb_type)) ? 1 : 0);
val.resize(limb_count, limb_count);
limb_type* pl = val.limbs();
for(std::size_t i = 0; i < limb_count; ++i)
diff --git a/boost/multiprecision/detail/bitscan.hpp b/boost/multiprecision/detail/bitscan.hpp
index 40602a939b..ce1cdc8d18 100644
--- a/boost/multiprecision/detail/bitscan.hpp
+++ b/boost/multiprecision/detail/bitscan.hpp
@@ -124,7 +124,7 @@ BOOST_FORCEINLINE unsigned find_lsb(unsigned long mask, mpl::int_<2> const&)
{
return __builtin_ctzl(mask);
}
-BOOST_FORCEINLINE unsigned find_lsb(unsigned long long mask, mpl::int_<3> const&)
+BOOST_FORCEINLINE unsigned find_lsb(boost::ulong_long_type mask, mpl::int_<3> const&)
{
return __builtin_ctzll(mask);
}
@@ -136,9 +136,9 @@ BOOST_FORCEINLINE unsigned find_msb(unsigned long mask, mpl::int_<2> const&)
{
return sizeof(unsigned long) * CHAR_BIT - 1 - __builtin_clzl(mask);
}
-BOOST_FORCEINLINE unsigned find_msb(unsigned long long mask, mpl::int_<3> const&)
+BOOST_FORCEINLINE unsigned find_msb(boost::ulong_long_type mask, mpl::int_<3> const&)
{
- return sizeof(unsigned long long) * CHAR_BIT - 1 - __builtin_clzll(mask);
+ return sizeof(boost::ulong_long_type) * CHAR_BIT - 1 - __builtin_clzll(mask);
}
template <class Unsigned>
@@ -152,7 +152,7 @@ BOOST_FORCEINLINE unsigned find_lsb(Unsigned mask)
sizeof(Unsigned) <= sizeof(unsigned long),
mpl::int_<2>,
typename mpl::if_c<
- sizeof(Unsigned) <= sizeof(unsigned long long),
+ sizeof(Unsigned) <= sizeof(boost::ulong_long_type),
mpl::int_<3>,
mpl::int_<0>
>::type
@@ -171,7 +171,7 @@ BOOST_FORCEINLINE unsigned find_msb(Unsigned mask)
sizeof(Unsigned) <= sizeof(unsigned long),
mpl::int_<2>,
typename mpl::if_c<
- sizeof(Unsigned) <= sizeof(unsigned long long),
+ sizeof(Unsigned) <= sizeof(boost::ulong_long_type),
mpl::int_<3>,
mpl::int_<0>
>::type
diff --git a/boost/multiprecision/detail/default_ops.hpp b/boost/multiprecision/detail/default_ops.hpp
index bf51a58295..01fbe181df 100644
--- a/boost/multiprecision/detail/default_ops.hpp
+++ b/boost/multiprecision/detail/default_ops.hpp
@@ -1219,7 +1219,7 @@ inline typename B::exponent_type eval_ilogb(const B& val)
template <class B>
inline void eval_logb(B& result, const B& val)
{
- typedef typename boost::mpl::if_c<boost::is_same<boost::intmax_t, long>::value, long long, boost::intmax_t>::type max_t;
+ typedef typename boost::mpl::if_c<boost::is_same<boost::intmax_t, long>::value, boost::long_long_type, boost::intmax_t>::type max_t;
result = static_cast<max_t>(eval_ilogb(val));
}
template <class B, class A>
@@ -1436,29 +1436,29 @@ inline long ltrunc(const number<T, ExpressionTemplates>& v)
}
#ifndef BOOST_NO_LONG_LONG
template <class tag, class A1, class A2, class A3, class A4, class Policy>
-inline long long lltrunc(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol)
+inline boost::long_long_type lltrunc(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol)
{
typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
number_type r = trunc(v, pol);
- if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !(boost::math::isfinite)(v))
+ if((r > (std::numeric_limits<boost::long_long_type>::max)()) || r < (std::numeric_limits<boost::long_long_type>::min)() || !(boost::math::isfinite)(v))
return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, number_type(v), 0LL, pol);
- return r.template convert_to<long long>();
+ return r.template convert_to<boost::long_long_type>();
}
template <class tag, class A1, class A2, class A3, class A4>
-inline long long lltrunc(const detail::expression<tag, A1, A2, A3, A4>& v)
+inline boost::long_long_type lltrunc(const detail::expression<tag, A1, A2, A3, A4>& v)
{
return lltrunc(v, boost::math::policies::policy<>());
}
template <class T, expression_template_option ExpressionTemplates, class Policy>
-inline long long lltrunc(const number<T, ExpressionTemplates>& v, const Policy& pol)
+inline boost::long_long_type lltrunc(const number<T, ExpressionTemplates>& v, const Policy& pol)
{
number<T, ExpressionTemplates> r = trunc(v, pol);
- if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !(boost::math::isfinite)(v))
+ if((r > (std::numeric_limits<boost::long_long_type>::max)()) || r < (std::numeric_limits<boost::long_long_type>::min)() || !(boost::math::isfinite)(v))
return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, v, 0LL, pol);
- return r.template convert_to<long long>();
+ return r.template convert_to<boost::long_long_type>();
}
template <class T, expression_template_option ExpressionTemplates>
-inline long long lltrunc(const number<T, ExpressionTemplates>& v)
+inline boost::long_long_type lltrunc(const number<T, ExpressionTemplates>& v)
{
return lltrunc(v, boost::math::policies::policy<>());
}
@@ -1534,29 +1534,29 @@ inline long lround(const number<T, ExpressionTemplates>& v)
}
#ifndef BOOST_NO_LONG_LONG
template <class tag, class A1, class A2, class A3, class A4, class Policy>
-inline long long llround(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol)
+inline boost::long_long_type llround(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol)
{
typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
number_type r = round(v, pol);
- if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !(boost::math::isfinite)(v))
+ if((r > (std::numeric_limits<boost::long_long_type>::max)()) || r < (std::numeric_limits<boost::long_long_type>::min)() || !(boost::math::isfinite)(v))
return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, number_type(v), 0LL, pol);
- return r.template convert_to<long long>();
+ return r.template convert_to<boost::long_long_type>();
}
template <class tag, class A1, class A2, class A3, class A4>
-inline long long llround(const detail::expression<tag, A1, A2, A3, A4>& v)
+inline boost::long_long_type llround(const detail::expression<tag, A1, A2, A3, A4>& v)
{
return llround(v, boost::math::policies::policy<>());
}
template <class T, expression_template_option ExpressionTemplates, class Policy>
-inline long long llround(const number<T, ExpressionTemplates>& v, const Policy& pol)
+inline boost::long_long_type llround(const number<T, ExpressionTemplates>& v, const Policy& pol)
{
number<T, ExpressionTemplates> r = round(v, pol);
- if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !(boost::math::isfinite)(v))
+ if((r > (std::numeric_limits<boost::long_long_type>::max)()) || r < (std::numeric_limits<boost::long_long_type>::min)() || !(boost::math::isfinite)(v))
return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, v, 0LL, pol);
- return r.template convert_to<long long>();
+ return r.template convert_to<boost::long_long_type>();
}
template <class T, expression_template_option ExpressionTemplates>
-inline long long llround(const number<T, ExpressionTemplates>& v)
+inline boost::long_long_type llround(const number<T, ExpressionTemplates>& v)
{
return llround(v, boost::math::policies::policy<>());
}
@@ -1612,7 +1612,7 @@ frexp(const detail::expression<tag, A1, A2, A3, A4>& v, long* pint)
return BOOST_MP_MOVE(frexp(static_cast<number_type>(v), pint));
}
template <class T, expression_template_option ExpressionTemplates>
-inline typename enable_if_c<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, long long* pint)
+inline typename enable_if_c<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, boost::long_long_type* pint)
{
using default_ops::eval_frexp;
number<T, ExpressionTemplates> result;
@@ -1621,7 +1621,7 @@ inline typename enable_if_c<number_category<T>::value == number_kind_floating_po
}
template <class tag, class A1, class A2, class A3, class A4>
inline typename enable_if_c<number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_floating_point, typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type
-frexp(const detail::expression<tag, A1, A2, A3, A4>& v, long long* pint)
+frexp(const detail::expression<tag, A1, A2, A3, A4>& v, boost::long_long_type* pint)
{
typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
return BOOST_MP_MOVE(frexp(static_cast<number_type>(v), pint));
@@ -2104,8 +2104,8 @@ HETERO_BINARY_OP_FUNCTOR_B(ldexp, int, number_kind_floating_point)
//HETERO_BINARY_OP_FUNCTOR_B(frexp, int*, number_kind_floating_point)
HETERO_BINARY_OP_FUNCTOR_B(ldexp, long, number_kind_floating_point)
//HETERO_BINARY_OP_FUNCTOR_B(frexp, long*, number_kind_floating_point)
-HETERO_BINARY_OP_FUNCTOR_B(ldexp, long long, number_kind_floating_point)
-//HETERO_BINARY_OP_FUNCTOR_B(frexp, long long*, number_kind_floating_point)
+HETERO_BINARY_OP_FUNCTOR_B(ldexp, boost::long_long_type, number_kind_floating_point)
+//HETERO_BINARY_OP_FUNCTOR_B(frexp, boost::long_long_type*, number_kind_floating_point)
BINARY_OP_FUNCTOR(pow, number_kind_floating_point)
BINARY_OP_FUNCTOR(fmod, number_kind_floating_point)
BINARY_OP_FUNCTOR(atan2, number_kind_floating_point)
@@ -2114,7 +2114,7 @@ UNARY_OP_FUNCTOR(logb, number_kind_floating_point)
HETERO_BINARY_OP_FUNCTOR(scalbn, short, number_kind_floating_point)
HETERO_BINARY_OP_FUNCTOR_B(scalbn, int, number_kind_floating_point)
HETERO_BINARY_OP_FUNCTOR_B(scalbn, long, number_kind_floating_point)
-HETERO_BINARY_OP_FUNCTOR_B(scalbn, long long, number_kind_floating_point)
+HETERO_BINARY_OP_FUNCTOR_B(scalbn, boost::long_long_type, number_kind_floating_point)
//
// Integer functions:
diff --git a/boost/multiprecision/detail/functions/pow.hpp b/boost/multiprecision/detail/functions/pow.hpp
index 5b54a1a9a8..b58d6b07be 100644
--- a/boost/multiprecision/detail/functions/pow.hpp
+++ b/boost/multiprecision/detail/functions/pow.hpp
@@ -12,6 +12,11 @@
// This file has no include guards or namespaces - it's expanded inline inside default_ops.hpp
//
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:6326) // comparison of two constants
+#endif
+
namespace detail{
template<typename T, typename U>
@@ -160,7 +165,7 @@ void hyp1F0(T& H1F0, const T& a, const T& x)
si_type n;
T term, part;
- static const unsigned series_limit =
+ static const si_type series_limit =
boost::multiprecision::detail::digits2<number<T, et_on> >::value < 100
? 100 : boost::multiprecision::detail::digits2<number<T, et_on> >::value;
// Series expansion of hyperg_1f0(a; ; x).
@@ -692,3 +697,6 @@ inline void eval_tanh(T& result, const T& x)
eval_divide(result, c);
}
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
diff --git a/boost/multiprecision/detail/functions/trig.hpp b/boost/multiprecision/detail/functions/trig.hpp
index baa42be38c..5d4e2639c2 100644
--- a/boost/multiprecision/detail/functions/trig.hpp
+++ b/boost/multiprecision/detail/functions/trig.hpp
@@ -12,6 +12,11 @@
// This file has no include guards or namespaces - it's expanded inline inside default_ops.hpp
//
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:6326) // comparison of two constants
+#endif
+
template <class T>
void hyp0F1(T& result, const T& b, const T& x)
{
@@ -494,12 +499,12 @@ void eval_asin(T& result, const T& x)
// Newton-Raphson iteration
while(current_digits < target_precision)
{
- T s, c;
- eval_sin(s, result);
- eval_cos(c, result);
- eval_subtract(s, xx);
- eval_divide(s, c);
- eval_subtract(result, s);
+ T sine, cosine;
+ eval_sin(sine, result);
+ eval_cos(cosine, result);
+ eval_subtract(sine, xx);
+ eval_divide(sine, cosine);
+ eval_subtract(result, sine);
current_digits *= 2;
/*
@@ -770,3 +775,6 @@ inline typename enable_if<is_arithmetic<A>, void>::type eval_atan2(T& result, co
eval_atan2(result, c, a);
}
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
diff --git a/boost/multiprecision/detail/generic_interconvert.hpp b/boost/multiprecision/detail/generic_interconvert.hpp
index 690723be8b..d1fa028d30 100644
--- a/boost/multiprecision/detail/generic_interconvert.hpp
+++ b/boost/multiprecision/detail/generic_interconvert.hpp
@@ -10,7 +10,7 @@
#ifdef BOOST_MSVC
#pragma warning(push)
-#pragma warning(disable:4127)
+#pragma warning(disable:4127 6326)
#endif
namespace boost{ namespace multiprecision{ namespace detail{
@@ -314,7 +314,7 @@ typename enable_if_c<is_number<To>::value || is_floating_point<To>::value>::type
if(shift > 0)
num <<= shift;
else if(shift < 0)
- denom <<= std::abs(shift);
+ denom <<= boost::multiprecision::detail::unsigned_abs(shift);
Integer q, r;
divide_qr(num, denom, q, r);
int q_bits = msb(q);
@@ -392,7 +392,7 @@ template <class To, class From>
void generic_interconvert_float2rational(To& to, const From& from, const mpl::int_<2>& /*radix*/)
{
typedef typename mpl::front<typename To::unsigned_types>::type ui_type;
- static const int shift = std::numeric_limits<long long>::digits;
+ static const int shift = std::numeric_limits<boost::long_long_type>::digits;
typename From::exponent_type e;
typename component_type<number<To> >::type num, denom;
number<From> val(from);
@@ -401,7 +401,7 @@ void generic_interconvert_float2rational(To& to, const From& from, const mpl::in
{
val = ldexp(val, shift);
e -= shift;
- long long ll = boost::math::lltrunc(val);
+ boost::long_long_type ll = boost::math::lltrunc(val);
val -= ll;
num <<= shift;
num += ll;
@@ -430,7 +430,7 @@ void generic_interconvert_float2rational(To& to, const From& from, const mpl::in
val = scalbn(val, -e);
while(val)
{
- long long ll = boost::math::lltrunc(val);
+ boost::long_long_type ll = boost::math::lltrunc(val);
val -= ll;
val = scalbn(val, 1);
num *= Radix;
diff --git a/boost/multiprecision/detail/number_base.hpp b/boost/multiprecision/detail/number_base.hpp
index 09c86e6ce0..d725779091 100644
--- a/boost/multiprecision/detail/number_base.hpp
+++ b/boost/multiprecision/detail/number_base.hpp
@@ -25,7 +25,19 @@
# define BOOST_MP_FORCEINLINE inline
#endif
-namespace boost{ namespace multiprecision{
+#if defined(BOOST_GCC) && (BOOST_GCC <= 40700)
+# define BOOST_MP_NOEXCEPT_IF(x)
+#else
+# define BOOST_MP_NOEXCEPT_IF(x) BOOST_NOEXCEPT_IF(x)
+#endif
+
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable:6326)
+#endif
+
+namespace boost{
+ namespace multiprecision{
enum expression_template_option
{
@@ -72,13 +84,13 @@ struct is_compatible_arithmetic_type
namespace detail{
//
-// Workaround for missing abs(long long) and abs(__int128) on some compilers:
+// Workaround for missing abs(boost::long_long_type) and abs(__int128) on some compilers:
//
template <class T>
BOOST_CONSTEXPR typename enable_if_c<(is_signed<T>::value || is_floating_point<T>::value), T>::type abs(T t) BOOST_NOEXCEPT
{
// This strange expression avoids a hardware trap in the corner case
- // that val is the most negative value permitted in long long.
+ // that val is the most negative value permitted in boost::long_long_type.
// See https://svn.boost.org/trac/boost/ticket/9740.
return t < 0 ? T(1u) + T(-(t + 1)) : t;
}
@@ -94,7 +106,7 @@ template <class T>
BOOST_CONSTEXPR typename enable_if_c<(is_signed<T>::value || is_floating_point<T>::value), typename make_unsigned<T>::type>::type unsigned_abs(T t) BOOST_NOEXCEPT
{
// This strange expression avoids a hardware trap in the corner case
- // that val is the most negative value permitted in long long.
+ // that val is the most negative value permitted in boost::long_long_type.
// See https://svn.boost.org/trac/boost/ticket/9740.
return t < 0 ? static_cast<typename make_unsigned<T>::type>(1u) + static_cast<typename make_unsigned<T>::type>(-(t + 1)) : static_cast<typename make_unsigned<T>::type>(t);
}
@@ -814,6 +826,10 @@ namespace constants{
}}
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+
#endif // BOOST_MATH_BIG_NUM_BASE_HPP
diff --git a/boost/multiprecision/detail/number_compare.hpp b/boost/multiprecision/detail/number_compare.hpp
index d1606ad73d..e9e510d302 100644
--- a/boost/multiprecision/detail/number_compare.hpp
+++ b/boost/multiprecision/detail/number_compare.hpp
@@ -6,6 +6,8 @@
#ifndef BOOST_MP_COMPARE_HPP
#define BOOST_MP_COMPARE_HPP
+#include <boost/multiprecision/traits/is_backend.hpp>
+
//
// Comparison operators for number.
//
@@ -14,61 +16,82 @@ namespace boost{ namespace multiprecision{
namespace default_ops{
+//
+// The dispatching mechanism used here to deal with differently typed arguments
+// could be better replaced with enable_if overloads, but that breaks MSVC-12
+// under strange and hard to reproduce circumstances.
+//
template <class B>
inline bool eval_eq(const B& a, const B& b)
{
return a.compare(b) == 0;
}
-//
-// For the default version which compares to some arbitrary type convertible to
-// our number type, we don't know what value the ExpressionTemplates parameter to
-// class number should be. We generally prefer ExpressionTemplates to be enabled
-// in case type A is itself an expression template, but we need to test both options
-// with is_convertible in case A has an implicit conversion operator to number<B,something>.
-// This is the case with many uBlas types for example.
-//
-template <class B, class A>
-inline bool eval_eq(const B& a, const A& b)
-{
- typedef typename mpl::if_c<
- is_convertible<A, number<B, et_on> >::value,
- number<B, et_on>,
- number<B, et_off> >::type mp_type;
- mp_type t(b);
+template <class T, class U>
+inline bool eval_eq_imp(const T& a, const U& b, const mpl::true_&)
+{
+ typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b);
return eval_eq(a, t.backend());
}
+template <class T, class U>
+inline bool eval_eq_imp(const T& a, const U& b, const mpl::false_&)
+{
+ typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a);
+ return eval_eq(t.backend(), b);
+}
+template <class T, class U>
+inline bool eval_eq(const T& a, const U& b)
+{
+ typedef mpl::bool_<boost::multiprecision::detail::is_first_backend<T, U>::value> tag_type;
+ return eval_eq_imp(a, b, tag_type());
+}
template <class B>
inline bool eval_lt(const B& a, const B& b)
{
return a.compare(b) < 0;
}
-template <class B, class A>
-inline bool eval_lt(const B& a, const A& b)
+template <class T, class U>
+inline bool eval_lt_imp(const T& a, const U& b, const mpl::true_&)
{
- typedef typename mpl::if_c<
- is_convertible<A, number<B, et_on> >::value,
- number<B, et_on>,
- number<B, et_off> >::type mp_type;
- mp_type t(b);
+ typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b);
return eval_lt(a, t.backend());
}
+template <class T, class U>
+inline bool eval_lt_imp(const T& a, const U& b, const mpl::false_&)
+{
+ typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a);
+ return eval_lt(t.backend(), b);
+}
+template <class T, class U>
+inline bool eval_lt(const T& a, const U& b)
+{
+ typedef mpl::bool_<boost::multiprecision::detail::is_first_backend<T, U>::value> tag_type;
+ return eval_lt_imp(a, b, tag_type());
+}
template <class B>
inline bool eval_gt(const B& a, const B& b)
{
return a.compare(b) > 0;
}
-template <class B, class A>
-inline bool eval_gt(const B& a, const A& b)
+template <class T, class U>
+inline bool eval_gt_imp(const T& a, const U& b, const mpl::true_&)
{
- typedef typename mpl::if_c<
- is_convertible<A, number<B, et_on> >::value,
- number<B, et_on>,
- number<B, et_off> >::type mp_type;
- mp_type t(b);
+ typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b);
return eval_gt(a, t.backend());
}
+template <class T, class U>
+inline bool eval_gt_imp(const T& a, const U& b, const mpl::false_&)
+{
+ typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a);
+ return eval_gt(t.backend(), b);
+}
+template <class T, class U>
+inline bool eval_gt(const T& a, const U& b)
+{
+ typedef mpl::bool_<boost::multiprecision::detail::is_first_backend<T, U>::value> tag_type;
+ return eval_gt_imp(a, b, tag_type());
+}
} // namespace default_ops
@@ -91,12 +114,42 @@ template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, ex
struct is_valid_mixed_compare<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >
: public mpl::bool_<is_convertible<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::value> {};
+template <class Backend, expression_template_option ExpressionTemplates>
+inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Backend>::value != number_kind_floating_point, bool>::type is_unordered_value(const number<Backend, ExpressionTemplates>&)
+{
+ return false;
+}
+template <class Backend, expression_template_option ExpressionTemplates>
+inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Backend>::value == number_kind_floating_point, bool>::type is_unordered_value(const number<Backend, ExpressionTemplates>& a)
+{
+ using default_ops::eval_fpclassify;
+ return eval_fpclassify(a.backend()) == FP_NAN;
+}
+
+template <class Arithmetic>
+inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Arithmetic>::value != number_kind_floating_point, bool>::type is_unordered_value(const Arithmetic&)
+{
+ return false;
+}
+template <class Arithmetic>
+inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Arithmetic>::value == number_kind_floating_point, bool>::type is_unordered_value(const Arithmetic& a)
+{
+ return (boost::math::isnan)(a);
+}
+
+template <class T, class U>
+inline BOOST_CONSTEXPR bool is_unordered_comparison(const T& a, const U& b)
+{
+ return is_unordered_value(a) || is_unordered_value(b);
+}
+
}
template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
inline bool operator == (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
{
using default_ops::eval_eq;
+ if(detail::is_unordered_comparison(a, b)) return false;
return eval_eq(a.backend(), b.backend());
}
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
@@ -104,6 +157,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
operator == (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
{
using default_ops::eval_eq;
+ if(detail::is_unordered_comparison(a, b)) return false;
return eval_eq(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
}
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
@@ -111,6 +165,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
operator == (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
{
using default_ops::eval_eq;
+ if(detail::is_unordered_comparison(a, b)) return false;
return eval_eq(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
}
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
@@ -120,6 +175,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
using default_ops::eval_eq;
result_type t(b);
+ if(detail::is_unordered_comparison(a, t)) return false;
return eval_eq(t.backend(), result_type::canonical_value(a));
}
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
@@ -129,6 +185,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
using default_ops::eval_eq;
result_type t(a);
+ if(detail::is_unordered_comparison(t, b)) return false;
return eval_eq(t.backend(), result_type::canonical_value(b));
}
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
@@ -138,6 +195,7 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A
using default_ops::eval_eq;
typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
+ if(detail::is_unordered_comparison(t, t2)) return false;
return eval_eq(t.backend(), t2.backend());
}
@@ -145,6 +203,7 @@ template <class Backend, expression_template_option ExpressionTemplates, class B
inline bool operator != (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
{
using default_ops::eval_eq;
+ if(detail::is_unordered_comparison(a, b)) return true;
return !eval_eq(a.backend(), b.backend());
}
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
@@ -152,6 +211,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
operator != (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
{
using default_ops::eval_eq;
+ if(detail::is_unordered_comparison(a, b)) return true;
return !eval_eq(a.backend(), number<Backend, et_on>::canonical_value(b));
}
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
@@ -159,6 +219,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
operator != (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
{
using default_ops::eval_eq;
+ if(detail::is_unordered_comparison(a, b)) return true;
return !eval_eq(b.backend(), number<Backend, et_on>::canonical_value(a));
}
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
@@ -168,6 +229,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
using default_ops::eval_eq;
result_type t(b);
+ if(detail::is_unordered_comparison(a, t)) return true;
return !eval_eq(t.backend(), result_type::canonical_value(a));
}
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
@@ -177,6 +239,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
using default_ops::eval_eq;
result_type t(a);
+ if(detail::is_unordered_comparison(t, b)) return true;
return !eval_eq(t.backend(), result_type::canonical_value(b));
}
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
@@ -186,6 +249,7 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A
using default_ops::eval_eq;
typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
+ if(detail::is_unordered_comparison(t, t2)) return true;
return !eval_eq(t.backend(), t2.backend());
}
@@ -193,6 +257,7 @@ template <class Backend, expression_template_option ExpressionTemplates, class B
inline bool operator < (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
{
using default_ops::eval_lt;
+ if(detail::is_unordered_comparison(a, b)) return false;
return eval_lt(a.backend(), b.backend());
}
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
@@ -200,6 +265,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
operator < (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
{
using default_ops::eval_lt;
+ if(detail::is_unordered_comparison(a, b)) return false;
return eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
}
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
@@ -207,6 +273,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
operator < (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
{
using default_ops::eval_gt;
+ if(detail::is_unordered_comparison(a, b)) return false;
return eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
}
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
@@ -216,6 +283,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
using default_ops::eval_gt;
result_type t(b);
+ if(detail::is_unordered_comparison(a, t)) return false;
return eval_gt(t.backend(), result_type::canonical_value(a));
}
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
@@ -225,6 +293,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
using default_ops::eval_lt;
result_type t(a);
+ if(detail::is_unordered_comparison(t, b)) return false;
return eval_lt(t.backend(), result_type::canonical_value(b));
}
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
@@ -234,6 +303,7 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A
using default_ops::eval_lt;
typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
+ if(detail::is_unordered_comparison(t, t2)) return false;
return eval_lt(t.backend(), t2.backend());
}
@@ -241,6 +311,7 @@ template <class Backend, expression_template_option ExpressionTemplates, class B
inline bool operator > (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
{
using default_ops::eval_gt;
+ if(detail::is_unordered_comparison(a, b)) return false;
return eval_gt(a.backend(), b.backend());
}
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
@@ -248,6 +319,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
operator > (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
{
using default_ops::eval_gt;
+ if(detail::is_unordered_comparison(a, b)) return false;
return eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
}
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
@@ -255,6 +327,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
operator > (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
{
using default_ops::eval_lt;
+ if(detail::is_unordered_comparison(a, b)) return false;
return eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
}
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
@@ -264,7 +337,8 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
using default_ops::eval_lt;
result_type t(b);
- return eval_lt(t.backend(), result_type::canonical_value(a));
+ if(detail::is_unordered_comparison(a, t)) return false;
+ return a > t;
}
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
@@ -273,7 +347,8 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
using default_ops::eval_gt;
result_type t(a);
- return eval_gt(t.backend(), result_type::canonical_value(b));
+ if(detail::is_unordered_comparison(t, b)) return false;
+ return t > b;
}
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
@@ -282,13 +357,15 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A
using default_ops::eval_gt;
typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
- return eval_gt(t.backend(), t2.backend());
+ if(detail::is_unordered_comparison(t, t2)) return false;
+ return t > t2;
}
template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
inline bool operator <= (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
{
using default_ops::eval_gt;
+ if(detail::is_unordered_comparison(a, b)) return false;
return !eval_gt(a.backend(), b.backend());
}
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
@@ -296,6 +373,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
operator <= (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
{
using default_ops::eval_gt;
+ if(detail::is_unordered_comparison(a, b)) return false;
return !eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
}
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
@@ -303,6 +381,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
operator <= (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
{
using default_ops::eval_lt;
+ if(detail::is_unordered_comparison(a, b)) return false;
return !eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
}
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
@@ -311,7 +390,10 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
{
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
using default_ops::eval_lt;
+ if(detail::is_unordered_value(a) || detail::is_unordered_value(b))
+ return false;
result_type t(b);
+ if(detail::is_unordered_comparison(a, t)) return false;
return !eval_lt(t.backend(), result_type::canonical_value(a));
}
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
@@ -321,6 +403,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
using default_ops::eval_gt;
result_type t(a);
+ if(detail::is_unordered_comparison(t, b)) return false;
return !eval_gt(t.backend(), result_type::canonical_value(b));
}
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
@@ -330,6 +413,7 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A
using default_ops::eval_gt;
typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
+ if(detail::is_unordered_comparison(t, t2)) return false;
return !eval_gt(t.backend(), t2.backend());
}
@@ -337,6 +421,7 @@ template <class Backend, expression_template_option ExpressionTemplates, class B
inline bool operator >= (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
{
using default_ops::eval_lt;
+ if(detail::is_unordered_comparison(a, b)) return false;
return !eval_lt(a.backend(), b.backend());
}
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
@@ -344,6 +429,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
operator >= (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
{
using default_ops::eval_lt;
+ if(detail::is_unordered_comparison(a, b)) return false;
return !eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
}
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
@@ -351,6 +437,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
operator >= (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
{
using default_ops::eval_gt;
+ if(detail::is_unordered_comparison(a, b)) return false;
return !eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
}
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
@@ -360,6 +447,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
using default_ops::eval_gt;
result_type t(b);
+ if(detail::is_unordered_comparison(a, t)) return false;
return !eval_gt(t.backend(), result_type::canonical_value(a));
}
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
@@ -369,6 +457,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
using default_ops::eval_lt;
result_type t(a);
+ if(detail::is_unordered_comparison(t, b)) return false;
return !eval_lt(t.backend(), result_type::canonical_value(b));
}
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
@@ -378,6 +467,7 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A
using default_ops::eval_lt;
typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a);
typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
+ if(detail::is_unordered_comparison(t, t2)) return false;
return !eval_lt(t.backend(), t2.backend());
}
diff --git a/boost/multiprecision/float128.hpp b/boost/multiprecision/float128.hpp
index 6e2958e07f..cd70fa009b 100644
--- a/boost/multiprecision/float128.hpp
+++ b/boost/multiprecision/float128.hpp
@@ -127,9 +127,9 @@ namespace backends{
struct float128_backend
{
- typedef mpl::list<signed char, short, int, long, long long> signed_types;
+ typedef mpl::list<signed char, short, int, long, boost::long_long_type> signed_types;
typedef mpl::list<unsigned char, unsigned short,
- unsigned int, unsigned long, unsigned long long> unsigned_types;
+ unsigned int, unsigned long, boost::ulong_long_type> unsigned_types;
typedef mpl::list<float, double, long double> float_types;
typedef int exponent_type;
@@ -534,7 +534,7 @@ public:
static number_type (max)() BOOST_NOEXCEPT { return 1.18973149535723176508575932662800702e4932Q; }
static number_type lowest() BOOST_NOEXCEPT { return -(max)(); }
BOOST_STATIC_CONSTEXPR int digits = 113;
- BOOST_STATIC_CONSTEXPR int digits10 = 34;
+ BOOST_STATIC_CONSTEXPR int digits10 = 33;
BOOST_STATIC_CONSTEXPR int max_digits10 = 36;
BOOST_STATIC_CONSTEXPR bool is_signed = true;
BOOST_STATIC_CONSTEXPR bool is_integer = false;
@@ -564,57 +564,57 @@ public:
};
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_specialized;
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_specialized;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits;
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits10;
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits10;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_digits10;
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_digits10;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_signed;
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_signed;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_integer;
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_integer;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_exact;
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_exact;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::radix;
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::radix;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent;
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent;
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent10;
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent10;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent10;
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent10;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_infinity;
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_infinity;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_quiet_NaN;
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_quiet_NaN;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_signaling_NaN;
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_signaling_NaN;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm_loss;
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm_loss;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_iec559;
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_iec559;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_bounded;
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_bounded;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_modulo;
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_modulo;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::traps;
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::traps;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::tinyness_before;
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::tinyness_before;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::round_style;
+BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::round_style;
template <boost::multiprecision::expression_template_option ExpressionTemplates>
-const float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm;
+BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm;
} // namespace std
diff --git a/boost/multiprecision/gmp.hpp b/boost/multiprecision/gmp.hpp
index 3b020d07c5..6351f7ea48 100644
--- a/boost/multiprecision/gmp.hpp
+++ b/boost/multiprecision/gmp.hpp
@@ -59,10 +59,15 @@ namespace detail{
template <unsigned digits10>
struct gmp_float_imp
{
- typedef mpl::list<long, long long> signed_types;
- typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
- typedef mpl::list<double, long double> float_types;
- typedef long exponent_type;
+#ifdef BOOST_HAS_LONG_LONG
+ typedef mpl::list<long, boost::long_long_type> signed_types;
+ typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
+#else
+ typedef mpl::list<long> signed_types;
+ typedef mpl::list<unsigned long> unsigned_types;
+#endif
+ typedef mpl::list<double, long double> float_types;
+ typedef long exponent_type;
gmp_float_imp() BOOST_NOEXCEPT {}
@@ -100,37 +105,48 @@ struct gmp_float_imp
return *this;
}
#endif
- gmp_float_imp& operator = (unsigned long long i)
+
+#ifdef BOOST_HAS_LONG_LONG
+#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
+ gmp_float_imp& operator = (boost::ulong_long_type i)
+ {
+ *this = static_cast<unsigned long>(i);
+ return *this;
+ }
+#else
+ gmp_float_imp& operator = (boost::ulong_long_type i)
{
if(m_data[0]._mp_d == 0)
mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
- unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
+ boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
unsigned shift = 0;
mpf_t t;
mpf_init2(t, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
mpf_set_ui(m_data, 0);
while(i)
{
- mpf_set_ui(t, static_cast<unsigned>(i & mask));
+ mpf_set_ui(t, static_cast<unsigned long>(i & mask));
if(shift)
mpf_mul_2exp(t, t, shift);
mpf_add(m_data, m_data, t);
- shift += std::numeric_limits<unsigned>::digits;
- i >>= std::numeric_limits<unsigned>::digits;
+ shift += std::numeric_limits<unsigned long>::digits;
+ i >>= std::numeric_limits<unsigned long>::digits;
}
mpf_clear(t);
return *this;
}
- gmp_float_imp& operator = (long long i)
+#endif
+ gmp_float_imp& operator = (boost::long_long_type i)
{
if(m_data[0]._mp_d == 0)
mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
bool neg = i < 0;
- *this = static_cast<unsigned long long>(boost::multiprecision::detail::unsigned_abs(i));
+ *this = static_cast<boost::ulong_long_type>(boost::multiprecision::detail::unsigned_abs(i));
if(neg)
mpf_neg(m_data, m_data);
return *this;
}
+#endif
gmp_float_imp& operator = (unsigned long i)
{
if(m_data[0]._mp_d == 0)
@@ -627,7 +643,7 @@ inline void eval_add(gmp_float<digits10>& result, long i)
if(i > 0)
mpf_add_ui(result.data(), result.data(), i);
else
- mpf_sub_ui(result.data(), result.data(), std::abs(i));
+ mpf_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
}
template <unsigned digits10>
inline void eval_subtract(gmp_float<digits10>& result, long i)
@@ -635,12 +651,12 @@ inline void eval_subtract(gmp_float<digits10>& result, long i)
if(i > 0)
mpf_sub_ui(result.data(), result.data(), i);
else
- mpf_add_ui(result.data(), result.data(), std::abs(i));
+ mpf_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
}
template <unsigned digits10>
inline void eval_multiply(gmp_float<digits10>& result, long i)
{
- mpf_mul_ui(result.data(), result.data(), std::abs(i));
+ mpf_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
if(i < 0)
mpf_neg(result.data(), result.data());
}
@@ -649,7 +665,7 @@ inline void eval_divide(gmp_float<digits10>& result, long i)
{
if(i == 0)
BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
- mpf_div_ui(result.data(), result.data(), std::abs(i));
+ mpf_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
if(i < 0)
mpf_neg(result.data(), result.data());
}
@@ -843,13 +859,13 @@ inline void eval_convert_to(double* result, const gmp_float<digits10>& val) BOOS
}
#ifdef BOOST_HAS_LONG_LONG
template <unsigned digits10>
-inline void eval_convert_to(long long* result, const gmp_float<digits10>& val)
+inline void eval_convert_to(boost::long_long_type* result, const gmp_float<digits10>& val)
{
gmp_float<digits10> t(val);
if(eval_get_sign(t) < 0)
t.negate();
- long digits = std::numeric_limits<long long>::digits - std::numeric_limits<long>::digits;
+ long digits = std::numeric_limits<boost::long_long_type>::digits - std::numeric_limits<long>::digits;
if(digits > 0)
mpf_div_2exp(t.data(), t.data(), digits);
@@ -857,9 +873,9 @@ inline void eval_convert_to(long long* result, const gmp_float<digits10>& val)
if(!mpf_fits_slong_p(t.data()))
{
if(eval_get_sign(val) < 0)
- *result = (std::numeric_limits<long long>::min)();
+ *result = (std::numeric_limits<boost::long_long_type>::min)();
else
- *result = (std::numeric_limits<long long>::max)();
+ *result = (std::numeric_limits<boost::long_long_type>::max)();
return;
};
@@ -878,18 +894,18 @@ inline void eval_convert_to(long long* result, const gmp_float<digits10>& val)
*result = -*result;
}
template <unsigned digits10>
-inline void eval_convert_to(unsigned long long* result, const gmp_float<digits10>& val)
+inline void eval_convert_to(boost::ulong_long_type* result, const gmp_float<digits10>& val)
{
gmp_float<digits10> t(val);
- long digits = std::numeric_limits<long long>::digits - std::numeric_limits<long>::digits;
+ long digits = std::numeric_limits<boost::long_long_type>::digits - std::numeric_limits<long>::digits;
if(digits > 0)
mpf_div_2exp(t.data(), t.data(), digits);
if(!mpf_fits_ulong_p(t.data()))
{
- *result = (std::numeric_limits<long long>::max)();
+ *result = (std::numeric_limits<boost::long_long_type>::max)();
return;
}
@@ -969,8 +985,13 @@ inline void eval_frexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& v
struct gmp_int
{
- typedef mpl::list<long, long long> signed_types;
- typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
+#ifdef BOOST_HAS_LONG_LONG
+ typedef mpl::list<long, boost::long_long_type> signed_types;
+ typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
+#else
+ typedef mpl::list<long> signed_types;
+ typedef mpl::list<unsigned long> unsigned_types;
+#endif
typedef mpl::list<double, long double> float_types;
gmp_int()
@@ -1026,28 +1047,37 @@ struct gmp_int
return *this;
}
#endif
- gmp_int& operator = (unsigned long long i)
+#ifdef BOOST_HAS_LONG_LONG
+#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
+ gmp_int& operator = (boost::ulong_long_type i)
+ {
+ *this = static_cast<unsigned long>(i);
+ return *this;
+ }
+#else
+ gmp_int& operator = (boost::ulong_long_type i)
{
if(m_data[0]._mp_d == 0)
mpz_init(this->m_data);
- unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
+ boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
unsigned shift = 0;
mpz_t t;
mpz_set_ui(m_data, 0);
mpz_init_set_ui(t, 0);
while(i)
{
- mpz_set_ui(t, static_cast<unsigned>(i & mask));
+ mpz_set_ui(t, static_cast<unsigned long>(i & mask));
if(shift)
mpz_mul_2exp(t, t, shift);
mpz_add(m_data, m_data, t);
- shift += std::numeric_limits<unsigned>::digits;
- i >>= std::numeric_limits<unsigned>::digits;
+ shift += std::numeric_limits<unsigned long>::digits;
+ i >>= std::numeric_limits<unsigned long>::digits;
}
mpz_clear(t);
return *this;
}
- gmp_int& operator = (long long i)
+#endif
+ gmp_int& operator = (boost::long_long_type i)
{
if(m_data[0]._mp_d == 0)
mpz_init(this->m_data);
@@ -1057,6 +1087,7 @@ struct gmp_int
mpz_neg(m_data, m_data);
return *this;
}
+#endif
gmp_int& operator = (unsigned long i)
{
if(m_data[0]._mp_d == 0)
@@ -1379,19 +1410,19 @@ inline void eval_subtract(gmp_int& t, long i)
}
inline void eval_multiply(gmp_int& t, long i)
{
- mpz_mul_ui(t.data(), t.data(), std::abs(i));
+ mpz_mul_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
if(i < 0)
mpz_neg(t.data(), t.data());
}
inline void eval_modulus(gmp_int& t, long i)
{
- mpz_tdiv_r_ui(t.data(), t.data(), std::abs(i));
+ mpz_tdiv_r_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
}
inline void eval_divide(gmp_int& t, long i)
{
if(i == 0)
BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
- mpz_tdiv_q_ui(t.data(), t.data(), std::abs(i));
+ mpz_tdiv_q_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
if(i < 0)
mpz_neg(t.data(), t.data());
}
@@ -1491,19 +1522,19 @@ inline void eval_subtract(gmp_int& t, const gmp_int& p, long i)
}
inline void eval_multiply(gmp_int& t, const gmp_int& p, long i)
{
- mpz_mul_ui(t.data(), p.data(), std::abs(i));
+ mpz_mul_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
if(i < 0)
mpz_neg(t.data(), t.data());
}
inline void eval_modulus(gmp_int& t, const gmp_int& p, long i)
{
- mpz_tdiv_r_ui(t.data(), p.data(), std::abs(i));
+ mpz_tdiv_r_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
}
inline void eval_divide(gmp_int& t, const gmp_int& p, long i)
{
if(i == 0)
BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
- mpz_tdiv_q_ui(t.data(), p.data(), std::abs(i));
+ mpz_tdiv_q_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
if(i < 0)
mpz_neg(t.data(), t.data());
}
@@ -1582,12 +1613,12 @@ inline typename enable_if_c<(is_unsigned<I>::value && (sizeof(I) <= sizeof(unsig
template <class I>
inline typename enable_if_c<(is_signed<I>::value && (sizeof(I) <= sizeof(long)))>::type eval_gcd(gmp_int& result, const gmp_int& a, const I b)
{
- mpz_gcd_ui(result.data(), a.data(), std::abs(b));
+ mpz_gcd_ui(result.data(), a.data(), boost::multiprecision::detail::unsigned_abs(b));
}
template <class I>
inline typename enable_if_c<is_signed<I>::value && ((sizeof(I) <= sizeof(long)))>::type eval_lcm(gmp_int& result, const gmp_int& a, const I b)
{
- mpz_lcm_ui(result.data(), a.data(), std::abs(b));
+ mpz_lcm_ui(result.data(), a.data(), boost::multiprecision::detail::unsigned_abs(b));
}
inline void eval_integer_sqrt(gmp_int& s, gmp_int& r, const gmp_int& x)
@@ -1664,8 +1695,7 @@ inline typename enable_if<is_unsigned<Integer>, Integer>::type eval_integer_modu
template <class Integer>
inline typename enable_if<is_signed<Integer>, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val)
{
- typedef typename make_unsigned<Integer>::type unsigned_type;
- return eval_integer_modulus(x, static_cast<unsigned_type>(std::abs(val)));
+ return eval_integer_modulus(x, boost::multiprecision::detail::unsigned_abs(val));
}
inline void eval_powm(gmp_int& result, const gmp_int& base, const gmp_int& p, const gmp_int& m)
{
@@ -1706,9 +1736,14 @@ void eval_add(gmp_rational& t, const gmp_rational& o);
struct gmp_rational
{
- typedef mpl::list<long, long long> signed_types;
- typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
- typedef mpl::list<double, long double> float_types;
+#ifdef BOOST_HAS_LONG_LONG
+ typedef mpl::list<long, boost::long_long_type> signed_types;
+ typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
+#else
+ typedef mpl::list<long> signed_types;
+ typedef mpl::list<unsigned long> unsigned_types;
+#endif
+ typedef mpl::list<double, long double> float_types;
gmp_rational()
{
@@ -1757,28 +1792,24 @@ struct gmp_rational
return *this;
}
#endif
- gmp_rational& operator = (unsigned long long i)
+#ifdef BOOST_HAS_LONG_LONG
+#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
+ gmp_rational& operator = (boost::ulong_long_type i)
+ {
+ *this = static_cast<unsigned long>(i);
+ return *this;
+ }
+#else
+ gmp_rational& operator = (boost::ulong_long_type i)
{
if(m_data[0]._mp_den._mp_d == 0)
mpq_init(m_data);
- unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
- unsigned shift = 0;
- mpq_t t;
- mpq_set_ui(m_data, 0, 1);
- mpq_init(t);
- while(i)
- {
- mpq_set_ui(t, static_cast<unsigned>(i & mask), 1);
- if(shift)
- mpq_mul_2exp(t, t, shift);
- mpq_add(m_data, m_data, t);
- shift += std::numeric_limits<unsigned>::digits;
- i >>= std::numeric_limits<unsigned>::digits;
- }
- mpq_clear(t);
+ gmp_int zi;
+ zi = i;
+ mpq_set_z(m_data, zi.data());
return *this;
}
- gmp_rational& operator = (long long i)
+ gmp_rational& operator = (boost::long_long_type i)
{
if(m_data[0]._mp_den._mp_d == 0)
mpq_init(m_data);
@@ -1788,6 +1819,8 @@ struct gmp_rational
mpq_neg(m_data, m_data);
return *this;
}
+#endif
+#endif
gmp_rational& operator = (unsigned long i)
{
if(m_data[0]._mp_den._mp_d == 0)
diff --git a/boost/multiprecision/integer.hpp b/boost/multiprecision/integer.hpp
index 4432f1e971..e4c8bf8b6c 100644
--- a/boost/multiprecision/integer.hpp
+++ b/boost/multiprecision/integer.hpp
@@ -48,17 +48,17 @@ namespace detail{
//
// Figure out the kind of integer that has twice as many bits as some builtin
// integer type I. Use a native type if we can (including types which may not
-// be recognised by boost::int_t because they're larger than long long),
+// be recognised by boost::int_t because they're larger than boost::long_long_type),
// otherwise synthesize a cpp_int to do the job.
//
template <class I>
struct double_integer
{
static const unsigned int_t_digits =
- 2 * sizeof(I) <= sizeof(long long) ? std::numeric_limits<I>::digits * 2 : 1;
+ 2 * sizeof(I) <= sizeof(boost::long_long_type) ? std::numeric_limits<I>::digits * 2 : 1;
typedef typename mpl::if_c<
- 2 * sizeof(I) <= sizeof(long long),
+ 2 * sizeof(I) <= sizeof(boost::long_long_type),
typename mpl::if_c<
is_signed<I>::value,
typename boost::int_t<int_t_digits>::least,
diff --git a/boost/multiprecision/mpfi.hpp b/boost/multiprecision/mpfi.hpp
index 81503f7108..8d13981ceb 100644
--- a/boost/multiprecision/mpfi.hpp
+++ b/boost/multiprecision/mpfi.hpp
@@ -55,8 +55,13 @@ struct mpfi_float_imp;
template <unsigned digits10>
struct mpfi_float_imp
{
- typedef mpl::list<long, long long> signed_types;
- typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
+#ifdef BOOST_HAS_LONG_LONG
+ typedef mpl::list<long, boost::long_long_type> signed_types;
+ typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
+#else
+ typedef mpl::list<long> signed_types;
+ typedef mpl::list<unsigned long> unsigned_types;
+#endif
typedef mpl::list<double, long double> float_types;
typedef long exponent_type;
@@ -97,8 +102,9 @@ struct mpfi_float_imp
return *this;
}
#endif
+#ifdef BOOST_HAS_LONG_LONG
#ifdef _MPFR_H_HAVE_INTMAX_T
- mpfi_float_imp& operator = (unsigned long long i)
+ mpfi_float_imp& operator = (boost::ulong_long_type i)
{
if(m_data[0].left._mpfr_d == 0)
mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
@@ -106,7 +112,7 @@ struct mpfi_float_imp
mpfr_set_uj(right_data(), i, GMP_RNDU);
return *this;
}
- mpfi_float_imp& operator = (long long i)
+ mpfi_float_imp& operator = (boost::long_long_type i)
{
if(m_data[0].left._mpfr_d == 0)
mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
@@ -115,28 +121,28 @@ struct mpfi_float_imp
return *this;
}
#else
- mpfi_float_imp& operator = (unsigned long long i)
+ mpfi_float_imp& operator = (boost::ulong_long_type i)
{
if(m_data[0].left._mpfr_d == 0)
mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
- unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
+ boost::ulong_long_type mask = (((1uLL << (std::numeric_limits<unsigned long>::digits - 1) - 1) << 1) | 1u);
unsigned shift = 0;
mpfi_t t;
- mpfi_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<unsigned long long>::digits), static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10))));
+ mpfi_init2(t, (std::max)(static_cast<unsigned long>(std::numeric_limits<boost::ulong_long_type>::digits), static_cast<unsigned long>(multiprecision::detail::digits10_2_2(digits10))));
mpfi_set_ui(m_data, 0);
while(i)
{
- mpfi_set_ui(t, static_cast<unsigned>(i & mask));
+ mpfi_set_ui(t, static_cast<unsigned long>(i & mask));
if(shift)
mpfi_mul_2exp(t, t, shift);
mpfi_add(m_data, m_data, t);
- shift += std::numeric_limits<unsigned>::digits;
- i >>= std::numeric_limits<unsigned>::digits;
+ shift += std::numeric_limits<unsigned long>::digits;
+ i >>= std::numeric_limits<unsigned long>::digits;
}
mpfi_clear(t);
return *this;
}
- mpfi_float_imp& operator = (long long i)
+ mpfi_float_imp& operator = (boost::long_long_type i)
{
if(m_data[0].left._mpfr_d == 0)
mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
@@ -147,6 +153,7 @@ struct mpfi_float_imp
return *this;
}
#endif
+#endif
mpfi_float_imp& operator = (unsigned long i)
{
if(m_data[0].left._mpfr_d == 0)
@@ -731,14 +738,14 @@ inline void eval_convert_to(long* result, const mpfi_float_backend<digits10>& va
}
#ifdef _MPFR_H_HAVE_INTMAX_T
template <unsigned digits10>
-inline void eval_convert_to(unsigned long long* result, const mpfi_float_backend<digits10>& val)
+inline void eval_convert_to(boost::ulong_long_type* result, const mpfi_float_backend<digits10>& val)
{
mpfr_float_backend<digits10> t;
mpfi_mid(t.data(), val.data());
eval_convert_to(result, t);
}
template <unsigned digits10>
-inline void eval_convert_to(long long* result, const mpfi_float_backend<digits10>& val)
+inline void eval_convert_to(boost::long_long_type* result, const mpfi_float_backend<digits10>& val)
{
mpfr_float_backend<digits10> t;
mpfi_mid(t.data(), val.data());
diff --git a/boost/multiprecision/mpfr.hpp b/boost/multiprecision/mpfr.hpp
index 36298c143e..dcf0044cdd 100644
--- a/boost/multiprecision/mpfr.hpp
+++ b/boost/multiprecision/mpfr.hpp
@@ -63,8 +63,13 @@ struct mpfr_float_imp;
template <unsigned digits10>
struct mpfr_float_imp<digits10, allocate_dynamic>
{
- typedef mpl::list<long, long long> signed_types;
- typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
+#ifdef BOOST_HAS_LONG_LONG
+ typedef mpl::list<long, boost::long_long_type> signed_types;
+ typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
+#else
+ typedef mpl::list<long> signed_types;
+ typedef mpl::list<unsigned long> unsigned_types;
+#endif
typedef mpl::list<double, long double> float_types;
typedef long exponent_type;
@@ -105,15 +110,16 @@ struct mpfr_float_imp<digits10, allocate_dynamic>
return *this;
}
#endif
+#ifdef BOOST_HAS_LONG_LONG
#ifdef _MPFR_H_HAVE_INTMAX_T
- mpfr_float_imp& operator = (unsigned long long i)
+ mpfr_float_imp& operator = (boost::ulong_long_type i)
{
if(m_data[0]._mpfr_d == 0)
mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
mpfr_set_uj(m_data, i, GMP_RNDN);
return *this;
}
- mpfr_float_imp& operator = (long long i)
+ mpfr_float_imp& operator = (boost::long_long_type i)
{
if(m_data[0]._mpfr_d == 0)
mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
@@ -121,28 +127,28 @@ struct mpfr_float_imp<digits10, allocate_dynamic>
return *this;
}
#else
- mpfr_float_imp& operator = (unsigned long long i)
+ mpfr_float_imp& operator = (boost::ulong_long_type i)
{
if(m_data[0]._mpfr_d == 0)
mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
- unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
+ boost::ulong_long_type mask = (((1uLL << (std::numeric_limits<unsigned long>::digits - 1) - 1) << 1) | 1uLL);
unsigned shift = 0;
mpfr_t t;
- mpfr_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<unsigned long long>::digits), static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10))));
+ mpfr_init2(t, (std::max)(static_cast<unsigned long>(std::numeric_limits<boost::ulong_long_type>::digits), static_cast<unsigned long>(multiprecision::detail::digits10_2_2(digits10))));
mpfr_set_ui(m_data, 0, GMP_RNDN);
while(i)
{
- mpfr_set_ui(t, static_cast<unsigned>(i & mask), GMP_RNDN);
+ mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
if(shift)
mpfr_mul_2exp(t, t, shift, GMP_RNDN);
mpfr_add(m_data, m_data, t, GMP_RNDN);
- shift += std::numeric_limits<unsigned>::digits;
- i >>= std::numeric_limits<unsigned>::digits;
+ shift += std::numeric_limits<unsigned long>::digits;
+ i >>= std::numeric_limits<unsigned long>::digits;
}
mpfr_clear(t);
return *this;
}
- mpfr_float_imp& operator = (long long i)
+ mpfr_float_imp& operator = (boost::long_long_type i)
{
if(m_data[0]._mpfr_d == 0)
mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
@@ -153,6 +159,7 @@ struct mpfr_float_imp<digits10, allocate_dynamic>
return *this;
}
#endif
+#endif
mpfr_float_imp& operator = (unsigned long i)
{
if(m_data[0]._mpfr_d == 0)
@@ -363,8 +370,13 @@ protected:
template <unsigned digits10>
struct mpfr_float_imp<digits10, allocate_stack>
{
- typedef mpl::list<long, long long> signed_types;
- typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
+#ifdef BOOST_HAS_LONG_LONG
+ typedef mpl::list<long, boost::long_long_type> signed_types;
+ typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
+#else
+ typedef mpl::list<long> signed_types;
+ typedef mpl::list<unsigned long> unsigned_types;
+#endif
typedef mpl::list<double, long double> float_types;
typedef long exponent_type;
@@ -392,21 +404,22 @@ struct mpfr_float_imp<digits10, allocate_stack>
mpfr_set(m_data, o.m_data, GMP_RNDN);
return *this;
}
+#ifdef BOOST_HAS_LONG_LONG
#ifdef _MPFR_H_HAVE_INTMAX_T
- mpfr_float_imp& operator = (unsigned long long i)
+ mpfr_float_imp& operator = (boost::ulong_long_type i)
{
mpfr_set_uj(m_data, i, GMP_RNDN);
return *this;
}
- mpfr_float_imp& operator = (long long i)
+ mpfr_float_imp& operator = (boost::long_long_type i)
{
mpfr_set_sj(m_data, i, GMP_RNDN);
return *this;
}
#else
- mpfr_float_imp& operator = (unsigned long long i)
+ mpfr_float_imp& operator = (boost::ulong_long_type i)
{
- unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
+ boost::ulong_long_type mask = (((1uLL << (std::numeric_limits<unsigned long>::digits - 1) - 1) << 1) | 1uL);
unsigned shift = 0;
mpfr_t t;
mp_limb_t t_limbs[limb_count];
@@ -415,16 +428,16 @@ struct mpfr_float_imp<digits10, allocate_stack>
mpfr_set_ui(m_data, 0, GMP_RNDN);
while(i)
{
- mpfr_set_ui(t, static_cast<unsigned>(i & mask), GMP_RNDN);
+ mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
if(shift)
mpfr_mul_2exp(t, t, shift, GMP_RNDN);
mpfr_add(m_data, m_data, t, GMP_RNDN);
- shift += std::numeric_limits<unsigned>::digits;
- i >>= std::numeric_limits<unsigned>::digits;
+ shift += std::numeric_limits<unsigned long>::digits;
+ i >>= std::numeric_limits<unsigned long>::digits;
}
return *this;
}
- mpfr_float_imp& operator = (long long i)
+ mpfr_float_imp& operator = (boost::long_long_type i)
{
bool neg = i < 0;
*this = boost::multiprecision::detail::unsigned_abs(i);
@@ -433,6 +446,7 @@ struct mpfr_float_imp<digits10, allocate_stack>
return *this;
}
#endif
+#endif
mpfr_float_imp& operator = (unsigned long i)
{
mpfr_set_ui(m_data, i, GMP_RNDN);
@@ -817,11 +831,14 @@ struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0
mpfr_float_backend& operator=(const mpfr_float_backend& o)
{
- if(this->m_data[0]._mpfr_d == 0)
- mpfr_init2(this->m_data, mpfr_get_prec(o.data()));
- else
- mpfr_set_prec(this->m_data, mpfr_get_prec(o.data()));
- mpfr_set(this->m_data, o.data(), GMP_RNDN);
+ if(this != &o)
+ {
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, mpfr_get_prec(o.data()));
+ else
+ mpfr_set_prec(this->m_data, mpfr_get_prec(o.data()));
+ mpfr_set(this->m_data, o.data(), GMP_RNDN);
+ }
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
@@ -1192,7 +1209,7 @@ inline void eval_convert_to(long* result, const mpfr_float_backend<digits10, All
}
#ifdef _MPFR_H_HAVE_INTMAX_T
template <unsigned digits10, mpfr_allocation_type AllocationType>
-inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
+inline void eval_convert_to(boost::ulong_long_type* result, const mpfr_float_backend<digits10, AllocationType>& val)
{
if(mpfr_nan_p(val.data()))
{
@@ -1201,7 +1218,7 @@ inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend
*result = mpfr_get_uj(val.data(), GMP_RNDZ);
}
template <unsigned digits10, mpfr_allocation_type AllocationType>
-inline void eval_convert_to(long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
+inline void eval_convert_to(boost::long_long_type* result, const mpfr_float_backend<digits10, AllocationType>& val)
{
if(mpfr_nan_p(val.data()))
{
diff --git a/boost/multiprecision/number.hpp b/boost/multiprecision/number.hpp
index c977958ea5..92242847de 100644
--- a/boost/multiprecision/number.hpp
+++ b/boost/multiprecision/number.hpp
@@ -31,7 +31,7 @@ namespace boost{ namespace multiprecision{
// warning C4127: conditional expression is constant
// warning C4714: function marked as __forceinline not inlined
#pragma warning(push)
-#pragma warning(disable:4127 4714)
+#pragma warning(disable:4127 4714 6326)
#endif
template <class Backend, expression_template_option ExpressionTemplates>
@@ -40,8 +40,8 @@ class number
typedef number<Backend, ExpressionTemplates> self_type;
public:
typedef Backend backend_type;
- BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number() BOOST_NOEXCEPT_IF(noexcept(Backend())) {}
- BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number& e) BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>()))) : m_backend(e.m_backend){}
+ BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number() BOOST_MP_NOEXCEPT_IF(noexcept(Backend())) {}
+ BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number& e) BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>()))) : m_backend(e.m_backend){}
template <class V>
BOOST_MP_FORCEINLINE number(const V& v, typename boost::enable_if_c<
(boost::is_arithmetic<V>::value || is_same<std::string, V>::value || is_convertible<V, const char*>::value)
@@ -57,11 +57,11 @@ public:
&& !detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value
>::type* = 0)
#ifndef BOOST_INTEL
- BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<typename detail::canonical<V, Backend>::type const&>())))
+ BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<typename detail::canonical<V, Backend>::type const&>())))
#endif
: m_backend(canonical_value(v)) {}
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number& e, unsigned digits10)
- BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>(), std::declval<unsigned>())))
+ BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>(), std::declval<unsigned>())))
: m_backend(e.m_backend, digits10){}
template <class V>
explicit BOOST_MP_FORCEINLINE number(const V& v, typename boost::enable_if_c<
@@ -69,7 +69,7 @@ public:
&& !detail::is_explicitly_convertible<typename detail::canonical<V, Backend>::type, Backend>::value
&& detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value
>::type* = 0)
- BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<typename detail::canonical<V, Backend>::type const&>()))
+ BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<typename detail::canonical<V, Backend>::type const&>()))
{
m_backend = canonical_value(v);
}
@@ -79,7 +79,7 @@ public:
&& (detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value
|| !is_convertible<typename detail::canonical<V, Backend>::type, Backend>::value)
>::type* = 0)
- BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<typename detail::canonical<V, Backend>::type const&>())))
+ BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<typename detail::canonical<V, Backend>::type const&>())))
: m_backend(canonical_value(v)) {}
/*
//
@@ -95,12 +95,12 @@ public:
*/
template<expression_template_option ET>
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number<Backend, ET>& val)
- BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>()))) : m_backend(val.backend()) {}
+ BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>()))) : m_backend(val.backend()) {}
template <class Other, expression_template_option ET>
BOOST_MP_FORCEINLINE number(const number<Other, ET>& val,
typename boost::enable_if_c<(boost::is_convertible<Other, Backend>::value && !detail::is_restricted_conversion<Other, Backend>::value)>::type* = 0)
- BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<Other const&>())))
+ BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Other const&>())))
: m_backend(val.backend()) {}
template <class Other, expression_template_option ET>
@@ -117,7 +117,7 @@ public:
explicit BOOST_MP_FORCEINLINE number(const number<Other, ET>& val, typename boost::enable_if_c<
(detail::is_explicitly_convertible<Other, Backend>::value
&& (detail::is_restricted_conversion<Other, Backend>::value || !boost::is_convertible<Other, Backend>::value))
- >::type* = 0) BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<Other const&>())))
+ >::type* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Other const&>())))
: m_backend(val.backend()) {}
template <class V>
@@ -149,7 +149,7 @@ public:
}
BOOST_MP_FORCEINLINE number& operator=(const number& e)
- BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<Backend const&>()))
+ BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<Backend const&>()))
{
m_backend = e.m_backend;
return *this;
@@ -158,14 +158,14 @@ public:
template <class V>
BOOST_MP_FORCEINLINE typename boost::enable_if<is_convertible<V, self_type>, number<Backend, ExpressionTemplates>& >::type
operator=(const V& v)
- BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<const typename detail::canonical<V, Backend>::type&>()))
+ BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<const typename detail::canonical<V, Backend>::type&>()))
{
m_backend = canonical_value(v);
return *this;
}
template <class V>
BOOST_MP_FORCEINLINE number<Backend, ExpressionTemplates>& assign(const V& v)
- BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<const typename detail::canonical<V, Backend>::type&>()))
+ BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<const typename detail::canonical<V, Backend>::type&>()))
{
m_backend = canonical_value(v);
return *this;
@@ -196,9 +196,9 @@ public:
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(number&& r)
- BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend>())))
+ BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend>())))
: m_backend(static_cast<Backend&&>(r.m_backend)){}
- BOOST_MP_FORCEINLINE number& operator=(number&& r) BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<Backend>()))
+ BOOST_MP_FORCEINLINE number& operator=(number&& r) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<Backend>()))
{
m_backend = static_cast<Backend&&>(r.m_backend);
return *this;
@@ -547,7 +547,7 @@ public:
//
// swap:
//
- BOOST_MP_FORCEINLINE void swap(self_type& other) BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend>().swap(std::declval<Backend&>())))
+ BOOST_MP_FORCEINLINE void swap(self_type& other) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend>().swap(std::declval<Backend&>())))
{
m_backend.swap(other.backend());
}
@@ -664,7 +664,7 @@ public:
// Comparison:
//
BOOST_MP_FORCEINLINE int compare(const number<Backend, ExpressionTemplates>& o)const
- BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend>().compare(std::declval<Backend>())))
+ BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend>().compare(std::declval<Backend>())))
{
return m_backend.compare(o.m_backend);
}
@@ -1726,7 +1726,7 @@ inline std::istream& operator >> (std::istream& is, number<Backend, ExpressionTe
template <class Backend, expression_template_option ExpressionTemplates>
BOOST_MP_FORCEINLINE void swap(number<Backend, ExpressionTemplates>& a, number<Backend, ExpressionTemplates>& b)
- BOOST_NOEXCEPT_IF(noexcept(std::declval<number<Backend, ExpressionTemplates>&>() = std::declval<number<Backend, ExpressionTemplates>&>()))
+ BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<number<Backend, ExpressionTemplates>&>() = std::declval<number<Backend, ExpressionTemplates>&>()))
{
a.swap(b);
}
diff --git a/boost/multiprecision/rational_adaptor.hpp b/boost/multiprecision/rational_adaptor.hpp
index 3e294aabb2..e3cec0e482 100644
--- a/boost/multiprecision/rational_adaptor.hpp
+++ b/boost/multiprecision/rational_adaptor.hpp
@@ -34,12 +34,12 @@ struct rational_adaptor
typedef typename IntBackend::unsigned_types unsigned_types;
typedef typename IntBackend::float_types float_types;
- rational_adaptor() BOOST_NOEXCEPT_IF(noexcept(rational_type())) {}
- rational_adaptor(const rational_adaptor& o) BOOST_NOEXCEPT_IF(noexcept(std::declval<rational_type&>() = std::declval<const rational_type&>()))
+ rational_adaptor() BOOST_MP_NOEXCEPT_IF(noexcept(rational_type())) {}
+ rational_adaptor(const rational_adaptor& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<rational_type&>() = std::declval<const rational_type&>()))
{
m_value = o.m_value;
}
- rational_adaptor(const IntBackend& o) BOOST_NOEXCEPT_IF(noexcept(rational_type(std::declval<const IntBackend&>()))) : m_value(o) {}
+ rational_adaptor(const IntBackend& o) BOOST_MP_NOEXCEPT_IF(noexcept(rational_type(std::declval<const IntBackend&>()))) : m_value(o) {}
template <class U>
rational_adaptor(const U& u, typename enable_if_c<is_convertible<U, IntBackend>::value>::type* = 0)
@@ -57,9 +57,9 @@ struct rational_adaptor
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- rational_adaptor(rational_adaptor&& o) BOOST_NOEXCEPT_IF(noexcept(rational_type(std::declval<rational_type>()))) : m_value(static_cast<rational_type&&>(o.m_value)) {}
- rational_adaptor(IntBackend&& o) BOOST_NOEXCEPT_IF(noexcept(rational_type(std::declval<IntBackend>()))) : m_value(static_cast<IntBackend&&>(o)) {}
- rational_adaptor& operator = (rational_adaptor&& o) BOOST_NOEXCEPT_IF(noexcept(std::declval<rational_type&>() = std::declval<rational_type>()))
+ rational_adaptor(rational_adaptor&& o) BOOST_MP_NOEXCEPT_IF(noexcept(rational_type(std::declval<rational_type>()))) : m_value(static_cast<rational_type&&>(o.m_value)) {}
+ rational_adaptor(IntBackend&& o) BOOST_MP_NOEXCEPT_IF(noexcept(rational_type(std::declval<IntBackend>()))) : m_value(static_cast<IntBackend&&>(o)) {}
+ rational_adaptor& operator = (rational_adaptor&& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<rational_type&>() = std::declval<rational_type>()))
{
m_value = static_cast<rational_type&&>(o.m_value);
return *this;
@@ -134,7 +134,7 @@ struct rational_adaptor
v2 = 1;
if(*s)
{
- BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Could parse the string \"") + p + std::string("\" as a valid rational number.")));
+ BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Could not parse the string \"") + p + std::string("\" as a valid rational number.")));
}
data().assign(v1, v2);
return *this;
diff --git a/boost/multiprecision/tommath.hpp b/boost/multiprecision/tommath.hpp
index 8abee83c4a..9c373443c6 100644
--- a/boost/multiprecision/tommath.hpp
+++ b/boost/multiprecision/tommath.hpp
@@ -38,8 +38,8 @@ void eval_add(tommath_int& t, const tommath_int& o);
struct tommath_int
{
- typedef mpl::list<boost::int32_t, long long> signed_types;
- typedef mpl::list<boost::uint32_t, unsigned long long> unsigned_types;
+ typedef mpl::list<boost::int32_t, boost::long_long_type> signed_types;
+ typedef mpl::list<boost::uint32_t, boost::ulong_long_type> unsigned_types;
typedef mpl::list<long double> float_types;
tommath_int()
@@ -70,11 +70,11 @@ struct tommath_int
detail::check_tommath_result(mp_copy(const_cast< ::mp_int*>(&o.m_data), &m_data));
return *this;
}
- tommath_int& operator = (unsigned long long i)
+ tommath_int& operator = (boost::ulong_long_type i)
{
if(m_data.dp == 0)
detail::check_tommath_result(mp_init(&m_data));
- unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
+ boost::ulong_long_type mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
unsigned shift = 0;
::mp_int t;
detail::check_tommath_result(mp_init(&t));
@@ -91,7 +91,7 @@ struct tommath_int
mp_clear(&t);
return *this;
}
- tommath_int& operator = (long long i)
+ tommath_int& operator = (boost::long_long_type i)
{
if(m_data.dp == 0)
detail::check_tommath_result(mp_init(&m_data));
@@ -118,7 +118,7 @@ struct tommath_int
if(m_data.dp == 0)
detail::check_tommath_result(mp_init(&m_data));
bool neg = i < 0;
- *this = static_cast<boost::uint32_t>(std::abs(i));
+ *this = boost::multiprecision::detail::unsigned_abs(i);
if(neg)
detail::check_tommath_result(mp_neg(&m_data, &m_data));
return *this;
@@ -222,7 +222,7 @@ struct tommath_int
unsigned shift = radix == 8 ? 3 : 4;
unsigned block_count = DIGIT_BIT / shift;
unsigned block_shift = shift * block_count;
- unsigned long long val, block;
+ boost::ulong_long_type val, block;
while(*s)
{
block = 0;
@@ -536,7 +536,7 @@ inline void eval_complement(tommath_int& result, const tommath_int& u)
// Create a mask providing the extra bits we need and add to result:
tommath_int mask;
- mask = static_cast<long long>((1u << padding) - 1);
+ mask = static_cast<boost::long_long_type>((1u << padding) - 1);
eval_left_shift(mask, shift);
add(result, mask);
}
@@ -640,8 +640,7 @@ inline typename enable_if<is_unsigned<Integer>, Integer>::type eval_integer_modu
template <class Integer>
inline typename enable_if<is_signed<Integer>, Integer>::type eval_integer_modulus(const tommath_int& x, Integer val)
{
- typedef typename make_unsigned<Integer>::type unsigned_type;
- return eval_integer_modulus(x, static_cast<unsigned_type>(std::abs(val)));
+ return eval_integer_modulus(x, boost::multiprecision::detail::unsigned_abs(val));
}
} // namespace backends
diff --git a/boost/multiprecision/traits/is_backend.hpp b/boost/multiprecision/traits/is_backend.hpp
new file mode 100644
index 0000000000..9b23c86665
--- /dev/null
+++ b/boost/multiprecision/traits/is_backend.hpp
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2015 John Maddock. Distributed under the 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_MP_IS_BACKEND_HPP
+#define BOOST_MP_IS_BACKEND_HPP
+
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/type_traits/conditional.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/multiprecision/detail/number_base.hpp>
+
+namespace boost{ namespace multiprecision{ namespace detail{
+
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(signed_types);
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(unsigned_types);
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(float_types);
+
+ template <class T>
+ struct is_backend
+ {
+ static const bool value = has_signed_types<T>::value && has_unsigned_types<T>::value && has_float_types<T>::value;
+ };
+
+ template <class Backend>
+ struct other_backend
+ {
+ typedef typename boost::conditional<
+ boost::is_same<number<Backend>, number<Backend, et_on> >::value,
+ number<Backend, et_off>, number<Backend, et_on> >::type type;
+ };
+
+ template <class B, class V>
+ struct number_from_backend
+ {
+ typedef typename boost::conditional <
+ boost::is_convertible<V, number<B> >::value,
+ number<B>,
+ typename other_backend<B>::type > ::type type;
+ };
+
+ template <bool b, class T, class U>
+ struct is_first_backend_imp{ static const bool value = false; };
+ template <class T, class U>
+ struct is_first_backend_imp<true, T, U>{ static const bool value = is_convertible<U, number<T, et_on> >::value || is_convertible<U, number<T, et_off> >::value; };
+
+ template <class T, class U>
+ struct is_first_backend : is_first_backend_imp<is_backend<T>::value, T, U> {};
+
+ template <bool b, class T, class U>
+ struct is_second_backend_imp{ static const bool value = false; };
+ template <class T, class U>
+ struct is_second_backend_imp<true, T, U>{ static const bool value = (is_convertible<T, number<U, et_on> >::value || is_convertible<T, number<U, et_off> >::value) && !is_first_backend<T, U>::value; };
+
+ template <class T, class U>
+ struct is_second_backend : is_second_backend_imp<is_backend<U>::value, T, U> {};
+
+}
+}
+}
+
+#endif // BOOST_MP_IS_BACKEND_HPP
diff --git a/boost/numeric/odeint/external/openmp/openmp_range_algebra.hpp b/boost/numeric/odeint/external/openmp/openmp_range_algebra.hpp
index f5668e4d0b..295db647d4 100644
--- a/boost/numeric/odeint/external/openmp/openmp_range_algebra.hpp
+++ b/boost/numeric/odeint/external/openmp/openmp_range_algebra.hpp
@@ -259,7 +259,7 @@ BOOST_ODEINT_GEN_FOR_EACH(BOOST_ODEINT_GEN_BODY)
typedef typename norm_result_type< S >::type result_type;
result_type init = static_cast< result_type >( 0 );
const size_t len = boost::size(s);
- typename boost::range_iterator<S>::type beg = boost::begin(s);
+ typename boost::range_iterator<const S>::type beg = boost::begin(s);
# pragma omp parallel for reduction(max: init) schedule(dynamic)
for( size_t i = 0 ; i < len ; ++i )
init = max( init , abs( beg[i] ) );
diff --git a/boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp b/boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp
index 15338ecd32..743e57709c 100644
--- a/boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp
+++ b/boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp
@@ -98,7 +98,7 @@ size_t integrate_adaptive(
}
size_t trials = 0;
- controlled_step_result res = success;
+ controlled_step_result res;
do
{
res = st.try_step( system , start_state , start_time , dt );
diff --git a/boost/numeric/odeint/integrate/detail/integrate_times.hpp b/boost/numeric/odeint/integrate/detail/integrate_times.hpp
index ac9b75d8bc..d5446ba590 100644
--- a/boost/numeric/odeint/integrate/detail/integrate_times.hpp
+++ b/boost/numeric/odeint/integrate/detail/integrate_times.hpp
@@ -130,7 +130,9 @@ size_t integrate_times(
if( start_time == end_time )
return 0;
- Time last_time_point = static_cast<time_type>(*(end_time-1));
+ TimeIterator last_time_iterator = end_time;
+ --last_time_iterator;
+ Time last_time_point = static_cast<time_type>(*last_time_iterator);
st.initialize( start_state , *start_time , dt );
obs( start_state , *start_time++ );
diff --git a/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp b/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp
index 0036d1d2a6..3018524ec9 100644
--- a/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp
+++ b/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp
@@ -109,7 +109,7 @@ public:
m_table( m_k_max ) ,
m_mp_states( m_k_max+1 ) ,
m_derivs( m_k_max+1 ) ,
- m_diffs( 2*m_k_max+1 ) ,
+ m_diffs( 2*m_k_max+2 ) ,
STEPFAC1( 0.65 ) , STEPFAC2( 0.94 ) , STEPFAC3( 0.02 ) , STEPFAC4( 4.0 ) , KFAC1( 0.8 ) , KFAC2( 0.9 )
{
BOOST_USING_STD_MIN();
@@ -139,7 +139,7 @@ public:
*/
}
int num = 1;
- for( int i = 2*(m_k_max) ; i >=0 ; i-- )
+ for( int i = 2*(m_k_max)+1 ; i >=0 ; i-- )
{
m_diffs[i].resize( num );
num += (i+1)%2;
@@ -587,7 +587,7 @@ private:
for( size_t i = 0 ; i < m_k_max+1 ; ++i )
for( size_t j = 0 ; j < m_derivs[i].size() ; ++j )
resized |= adjust_size_by_resizeability( m_derivs[i][j] , x , typename is_resizeable<deriv_type>::type() );
- for( size_t i = 0 ; i < 2*m_k_max+1 ; ++i )
+ for( size_t i = 0 ; i < 2*m_k_max+2 ; ++i )
for( size_t j = 0 ; j < m_diffs[i].size() ; ++j )
resized |= adjust_size_by_resizeability( m_diffs[i][j] , x , typename is_resizeable<deriv_type>::type() );
diff --git a/boost/numeric/odeint/util/detail/less_with_sign.hpp b/boost/numeric/odeint/util/detail/less_with_sign.hpp
index 8a7fda2789..d90e12f7b4 100644
--- a/boost/numeric/odeint/util/detail/less_with_sign.hpp
+++ b/boost/numeric/odeint/util/detail/less_with_sign.hpp
@@ -47,9 +47,9 @@ template< typename T >
bool less_eq_with_sign( T t1 , T t2 , T dt )
{
if( get_unit_value(dt) > 0 )
- return t1-t2 < std::numeric_limits<T>::epsilon();
+ return t1-t2 <= std::numeric_limits<T>::epsilon();
else
- return t2-t1 < std::numeric_limits<T>::epsilon();
+ return t2-t1 <= std::numeric_limits<T>::epsilon();
}
template< typename T >
diff --git a/boost/numeric/ublas/storage.hpp b/boost/numeric/ublas/storage.hpp
index 8821309dd5..bd648925a9 100644
--- a/boost/numeric/ublas/storage.hpp
+++ b/boost/numeric/ublas/storage.hpp
@@ -777,8 +777,8 @@ namespace boost { namespace numeric { namespace ublas {
BOOST_UBLAS_INLINE
shallow_array_adaptor (size_type size, pointer data):
size_ (size), own_ (false), data_ (data, leaker<value_type> ()) {}
- BOOST_UBLAS_INLINE
template <size_t N>
+ BOOST_UBLAS_INLINE
shallow_array_adaptor (T (&data)[N]):
size_ (N), own_ (false), data_ (data, leaker<value_type> ()) {}
@@ -833,13 +833,13 @@ namespace boost { namespace numeric { namespace ublas {
void resize (size_type size, pointer data, value_type init) {
resize_internal (size, data, init, true);
}
- BOOST_UBLAS_INLINE
template <size_t N>
+ BOOST_UBLAS_INLINE
void resize (T (&data)[N]) {
resize_internal (N, data, value_type (), false);
}
- BOOST_UBLAS_INLINE
template <size_t N>
+ BOOST_UBLAS_INLINE
void resize (T (&data)[N], value_type init) {
resize_internal (N, data, init, true);
}
diff --git a/boost/optional/optional.hpp b/boost/optional/optional.hpp
index afcb8079e2..9def94ede8 100644
--- a/boost/optional/optional.hpp
+++ b/boost/optional/optional.hpp
@@ -18,12 +18,14 @@
#define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
#include <new>
-#include <algorithm>
#include <iosfwd>
#include <boost/config.hpp>
#include <boost/assert.hpp>
+#include <boost/core/addressof.hpp>
+#include <boost/core/enable_if.hpp>
#include <boost/core/explicit_operator_bool.hpp>
+#include <boost/core/swap.hpp>
#include <boost/optional/bad_optional_access.hpp>
#include <boost/static_assert.hpp>
#include <boost/throw_exception.hpp>
@@ -47,13 +49,7 @@
#include <boost/detail/reference_content.hpp>
#include <boost/move/utility.hpp>
#include <boost/none.hpp>
-#include <boost/utility/addressof.hpp>
#include <boost/utility/compare_pointees.hpp>
-#include <boost/utility/enable_if.hpp>
-#include <boost/utility/in_place_factory.hpp>
-#include <boost/utility/swap.hpp>
-
-
#include <boost/optional/optional_fwd.hpp>
@@ -506,6 +502,13 @@ class optional_base : public optional_tag
::new (m_storage.address()) internal_type( boost::forward<Arg>(arg) );
m_initialized = true ;
}
+
+ void emplace_assign ()
+ {
+ destroy();
+ ::new (m_storage.address()) internal_type();
+ m_initialized = true ;
+ }
#else
template<class Arg>
void emplace_assign ( const Arg& arg )
@@ -515,13 +518,20 @@ class optional_base : public optional_tag
m_initialized = true ;
}
- template<class Arg>
+ template<class Arg>
void emplace_assign ( Arg& arg )
{
destroy();
::new (m_storage.address()) internal_type( arg );
m_initialized = true ;
}
+
+ void emplace_assign ()
+ {
+ destroy();
+ ::new (m_storage.address()) internal_type();
+ m_initialized = true ;
+ }
#endif
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
@@ -976,6 +986,11 @@ class optional : public optional_detail::optional_base<T>
{
this->emplace_assign( boost::forward<Arg>(arg) );
}
+
+ void emplace ()
+ {
+ this->emplace_assign();
+ }
#else
template<class Arg>
void emplace ( const Arg& arg )
@@ -988,6 +1003,11 @@ class optional : public optional_detail::optional_base<T>
{
this->emplace_assign( arg );
}
+
+ void emplace ()
+ {
+ this->emplace_assign();
+ }
#endif
void swap( optional & arg )
@@ -1251,9 +1271,10 @@ get_pointer ( optional<T>& opt )
// The following declaration prevents a bug where operator safe-bool is used upon streaming optional object if you forget the IO header.
template<class CharType, class CharTrait>
std::basic_ostream<CharType, CharTrait>&
-operator<<(std::basic_ostream<CharType, CharTrait>& out, optional_detail::optional_tag const& v)
+operator<<(std::basic_ostream<CharType, CharTrait>& os, optional_detail::optional_tag const&)
{
- BOOST_STATIC_ASSERT_MSG(sizeof(CharType) == 0, "If you want to output boost::optional, include header <boost/optional/optional_io.hpp>");
+ BOOST_STATIC_ASSERT_MSG(sizeof(CharType) == 0, "If you want to output boost::optional, include header <boost/optional/optional_io.hpp>");
+ return os;
}
// optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics (compare values).
@@ -1448,9 +1469,9 @@ struct swap_selector<true>
return;
if( !hasX )
- x = boost::in_place();
+ x.emplace();
else if ( !hasY )
- y = boost::in_place();
+ y.emplace();
// Boost.Utility.Swap will take care of ADL and workarounds for broken compilers
boost::swap(x.get(),y.get());
@@ -1523,9 +1544,18 @@ struct swap_selector<false>
} // namespace optional_detail
+#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_CONFIG_RESTORE_OBSOLETE_SWAP_IMPLEMENTATION)
+
+template<class T>
+struct optional_swap_should_use_default_constructor : boost::false_type {} ;
+
+#else
+
template<class T>
struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor<T> {} ;
+#endif //BOOST_NO_CXX11_RVALUE_REFERENCES
+
template<class T> inline void swap ( optional<T>& x, optional<T>& y )
//BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y)))
{
diff --git a/boost/parameter/aux_/arg_list.hpp b/boost/parameter/aux_/arg_list.hpp
index ed3929d5bf..71e4da271e 100644
--- a/boost/parameter/aux_/arg_list.hpp
+++ b/boost/parameter/aux_/arg_list.hpp
@@ -78,15 +78,11 @@ struct empty_arg_list
};
};
-#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
// Terminator for has_key, indicating that the keyword is unique
template <class KW>
static no_tag has_key(KW*);
-#endif
-#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
- || (BOOST_WORKAROUND(__GNUC__, < 3)) \
- || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// The overload set technique doesn't work with these older
// compilers, so they need some explicit handholding.
@@ -150,11 +146,6 @@ struct empty_arg_list
typedef arg_list_tag tag; // For dispatching to sequence intrinsics
};
-#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
-template<class KW>
-no_tag operator*(empty_arg_list, KW*);
-#endif
-
// Forward declaration for arg_list::operator,
template <class KW, class T>
struct tagged_argument;
@@ -227,25 +218,17 @@ struct arg_list : Next
};
};
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && !BOOST_WORKAROUND(__GNUC__, == 2)
-# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
- friend yes_tag operator*(arg_list, key_type*);
-# define BOOST_PARAMETER_CALL_HAS_KEY(next, key) (*(next*)0 * (key*)0)
-# else
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// Overload for key_type, so the assert below will fire if the
// same keyword is used again
static yes_tag has_key(key_type*);
using Next::has_key;
-# define BOOST_PARAMETER_CALL_HAS_KEY(next, key) next::has_key((key*)0)
-# endif
-
BOOST_MPL_ASSERT_MSG(
- sizeof(BOOST_PARAMETER_CALL_HAS_KEY(Next,key_type)) == sizeof(no_tag)
+ sizeof(Next::has_key((key_type*)0)) == sizeof(no_tag)
, duplicate_keyword, (key_type)
);
-# undef BOOST_PARAMETER_CALL_HAS_KEY
#endif
//
// Begin implementation of indexing operators for looking up
@@ -266,9 +249,7 @@ struct arg_list : Next
return arg.value ? arg.value.get() : arg.value.construct(d.value);
}
-#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
- || BOOST_WORKAROUND(__GNUC__, < 3) \
- || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// These older compilers don't support the overload set creation
// idiom well, so we need to do all the return type calculation
// for the compiler and dispatch through an outer function template
@@ -407,10 +388,6 @@ struct arg_list : Next
typedef arg_list_tag tag; // For dispatching to sequence intrinsics
};
-#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // ETI workaround
-template <> struct arg_list<int,int> {};
-#endif
-
// MPL sequence support
template <class ArgumentPack>
struct arg_list_iterator
diff --git a/boost/parameter/aux_/cast.hpp b/boost/parameter/aux_/cast.hpp
index b94c764e03..bd3de2bef5 100644
--- a/boost/parameter/aux_/cast.hpp
+++ b/boost/parameter/aux_/cast.hpp
@@ -7,8 +7,7 @@
# include <boost/detail/workaround.hpp>
-# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
- && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/remove_const.hpp>
# endif
@@ -17,8 +16,7 @@ namespace boost { namespace parameter { namespace aux {
struct use_default_tag {};
-# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
- || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# define BOOST_PARAMETER_FUNCTION_CAST(value, predicate) value
diff --git a/boost/parameter/aux_/parenthesized_type.hpp b/boost/parameter/aux_/parenthesized_type.hpp
index c6ddd77f31..69e7a237d4 100755..100644
--- a/boost/parameter/aux_/parenthesized_type.hpp
+++ b/boost/parameter/aux_/parenthesized_type.hpp
@@ -18,96 +18,12 @@ namespace boost { namespace parameter { namespace aux {
template <class UnaryFunctionPointer>
struct unaryfunptr_arg_type;
-# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
-
template <class Arg>
struct unaryfunptr_arg_type<void(*)(Arg)>
{
typedef Arg type;
};
-# else
-
-// Use the "native typeof" bugfeatures of older versions of MSVC to
-// accomplish what we'd normally do with partial specialization. This
-// capability was discovered by Igor Chesnokov.
-
-# if BOOST_WORKAROUND(BOOST_MSVC, != 1300)
-
-// This version applies to VC6.5 and VC7.1 (except that we can just
-// use partial specialization for the latter in this case).
-
-// This gets used as a base class.
-template<typename Address>
-struct msvc_type_memory
-{
- // A nullary metafunction that will yield the Value type "stored"
- // at this Address.
- struct storage;
-};
-
-template<typename Value, typename Address>
-struct msvc_store_type : msvc_type_memory<Address>
-{
- // VC++ somehow lets us define the base's nested storage
- // metafunction here, where we have the Value type we'd like to
- // "store" in it. Later we can come back to the base class and
- // extract the "stored type."
- typedef msvc_type_memory<Address> location;
- struct location::storage
- {
- typedef Value type;
- };
-};
-
-# else
-
-// This slightly more complicated version of the same thing is
-// required for msvc-7.0
-template<typename Address>
-struct msvc_type_memory
-{
- template<bool>
- struct storage_impl;
-
- typedef storage_impl<true> storage;
-};
-
-template<typename Value, typename Address>
-struct msvc_store_type : msvc_type_memory<Address>
-{
- // Rather than supplying a definition for the base class' nested
- // class, we specialize the base class' nested template
- template<>
- struct storage_impl<true>
- {
- typedef Value type;
- };
-};
-
-# endif
-
-// Function template argument deduction does many of the same things
-// as type matching during partial specialization, so we call a
-// function template to "store" T into the type memory addressed by
-// void(*)(T).
-template <class T>
-msvc_store_type<T,void(*)(T)>
-msvc_store_argument_type(void(*)(T));
-
-template <class FunctionPointer>
-struct unaryfunptr_arg_type
-{
- // We don't want the function to be evaluated, just instantiated,
- // so protect it inside of sizeof.
- enum { dummy = sizeof(msvc_store_argument_type((FunctionPointer)0)) };
-
- // Now pull the type out of the instantiated base class
- typedef typename msvc_type_memory<FunctionPointer>::storage::type type;
-};
-
-# endif
-
template <>
struct unaryfunptr_arg_type<void(*)(void)>
{
diff --git a/boost/parameter/aux_/set.hpp b/boost/parameter/aux_/set.hpp
index 1c4ccf5d94..7ab93dc7bb 100644
--- a/boost/parameter/aux_/set.hpp
+++ b/boost/parameter/aux_/set.hpp
@@ -7,8 +7,7 @@
# include <boost/detail/workaround.hpp>
-# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \
- && !BOOST_WORKAROUND(__GNUC__, < 3)
+# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# include <boost/mpl/insert.hpp>
# include <boost/mpl/set/set0.hpp>
# include <boost/mpl/has_key.hpp>
diff --git a/boost/parameter/aux_/tagged_argument.hpp b/boost/parameter/aux_/tagged_argument.hpp
index 6248be2d4a..79d273e418 100644
--- a/boost/parameter/aux_/tagged_argument.hpp
+++ b/boost/parameter/aux_/tagged_argument.hpp
@@ -120,13 +120,13 @@ struct tagged_argument : tagged_argument_base
}
# else
template <class Default>
- reference operator[](default_<key_type,Default> const& x) const
+ reference operator[](default_<key_type,Default> const& ) const
{
return value;
}
template <class F>
- reference operator[](lazy_default<key_type,F> const& x) const
+ reference operator[](lazy_default<key_type,F> const& ) const
{
return value;
}
diff --git a/boost/parameter/aux_/unwrap_cv_reference.hpp b/boost/parameter/aux_/unwrap_cv_reference.hpp
index e7aa0c1d3a..b6c263f232 100755..100644
--- a/boost/parameter/aux_/unwrap_cv_reference.hpp
+++ b/boost/parameter/aux_/unwrap_cv_reference.hpp
@@ -44,12 +44,6 @@ struct is_cv_reference_wrapper
value> type;
};
-#if BOOST_WORKAROUND(MSVC, == 1200)
-template <>
-struct is_cv_reference_wrapper<int>
- : mpl::false_ {};
-#endif
-
// Needed for unwrap_cv_reference below. T might be const, so
// eval_if might fail because of deriving from T const on EDG.
template <class T>
diff --git a/boost/parameter/binding.hpp b/boost/parameter/binding.hpp
index 632f0fdb9d..778a7b7bac 100755..100644
--- a/boost/parameter/binding.hpp
+++ b/boost/parameter/binding.hpp
@@ -11,18 +11,13 @@
# include <boost/parameter/aux_/void.hpp>
# include <boost/type_traits/is_same.hpp>
-# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-# include <boost/mpl/eval_if.hpp>
-# endif
-
namespace boost { namespace parameter {
// A metafunction that, given an argument pack, returns the type of
// the parameter identified by the given keyword. If no such
// parameter has been specified, returns Default
-# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
- || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class Parameters, class Keyword, class Default>
struct binding0
{
@@ -40,14 +35,9 @@ struct binding0
# endif
template <class Parameters, class Keyword, class Default = void_>
-# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
struct binding
-# else
-struct binding_eti
-# endif
{
-# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
- || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
typedef typename mpl::eval_if<
mpl::is_placeholder<Parameters>
, mpl::identity<int>
@@ -66,24 +56,8 @@ struct binding_eti
));
# endif
-# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
- BOOST_MPL_AUX_LAMBDA_SUPPORT(3,binding,(Parameters,Keyword,Default))
-# endif
-};
-
-# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-template <class Parameters, class Keyword, class Default = void_>
-struct binding
-{
- typedef typename mpl::eval_if<
- is_same<Parameters, int>
- , mpl::identity<int>
- , binding_eti<Parameters, Keyword, Default>
- >::type type;
-
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,binding,(Parameters,Keyword,Default))
};
-# endif
// A metafunction that, given an argument pack, returns the type of
// the parameter identified by the given keyword. If no such
diff --git a/boost/parameter/keyword.hpp b/boost/parameter/keyword.hpp
index cfb4bfdc53..925c772085 100755..100644
--- a/boost/parameter/keyword.hpp
+++ b/boost/parameter/keyword.hpp
@@ -52,7 +52,6 @@ struct keyword
return aux::lazy_default<Tag, Default>(default_);
}
-#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) // avoid partial ordering bugs
template <class T>
typename aux::tag<Tag, T const>::type const
operator=(T const& x) const
@@ -60,15 +59,10 @@ struct keyword
typedef typename aux::tag<Tag, T const>::type result;
return result(x);
}
-#endif
-#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) // avoid partial ordering bugs
template <class Default>
aux::default_<Tag, const Default>
operator|(const Default& default_) const
-#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
- volatile
-#endif
{
return aux::default_<Tag, const Default>(default_);
}
@@ -76,13 +70,9 @@ struct keyword
template <class Default>
aux::lazy_default<Tag, Default>
operator||(Default const& default_) const
-#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
- volatile
-#endif
{
return aux::lazy_default<Tag, Default>(default_);
}
-#endif
public: // Insurance against ODR violations
@@ -109,24 +99,6 @@ keyword<Tag> const keyword<Tag>::instance = {};
// reference in an anonymous namespace to a singleton instance of that
// type.
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-
-# define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \
- namespace tag_namespace \
- { \
- struct name \
- { \
- static char const* keyword_name() \
- { \
- return #name; \
- } \
- }; \
- } \
- static ::boost::parameter::keyword<tag_namespace::name> const& name \
- = ::boost::parameter::keyword<tag_namespace::name>::instance;
-
-#else
-
#define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \
namespace tag_namespace \
{ \
@@ -144,8 +116,6 @@ keyword<Tag> const keyword<Tag>::instance = {};
= ::boost::parameter::keyword<tag_namespace::name>::instance;\
}
-#endif
-
}} // namespace boost::parameter
#endif // KEYWORD_050328_HPP
diff --git a/boost/parameter/name.hpp b/boost/parameter/name.hpp
index 7352616e7a..f439df416b 100644
--- a/boost/parameter/name.hpp
+++ b/boost/parameter/name.hpp
@@ -16,7 +16,6 @@
# include <boost/mpl/placeholders.hpp>
# if !defined(BOOST_NO_SFINAE) \
- && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
# include <boost/utility/enable_if.hpp>
@@ -75,19 +74,6 @@ struct lambda<
# define BOOST_PARAMETER_IS_BINARY(x) BOOST_PP_IS_BINARY(x)
# endif
-# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-# define BOOST_PARAMETER_NAME_OBJECT(tag, name) \
- static ::boost::parameter::keyword<tag> const& name \
- = ::boost::parameter::keyword<tag>::instance;
-# else
-# define BOOST_PARAMETER_NAME_OBJECT(tag, name) \
- namespace \
- { \
- ::boost::parameter::keyword<tag> const& name \
- = ::boost::parameter::keyword<tag>::instance; \
- }
-# endif
-
# define BOOST_PARAMETER_BASIC_NAME(tag_namespace, tag, name) \
namespace tag_namespace \
{ \
@@ -107,7 +93,11 @@ struct lambda<
> _1; \
}; \
} \
- BOOST_PARAMETER_NAME_OBJECT(tag_namespace::tag, name)
+ namespace \
+ { \
+ ::boost::parameter::keyword<tag_namespace::tag> const& name \
+ = ::boost::parameter::keyword<tag_namespace::tag>::instance; \
+ }
# define BOOST_PARAMETER_COMPLEX_NAME_TUPLE1(tag,namespace) \
(tag, namespace), ~
diff --git a/boost/parameter/preprocessor.hpp b/boost/parameter/preprocessor.hpp
index f1bda87cdd..8ea370cb4b 100644
--- a/boost/parameter/preprocessor.hpp
+++ b/boost/parameter/preprocessor.hpp
@@ -37,10 +37,6 @@
# include <boost/mpl/always.hpp>
# include <boost/mpl/apply_wrap.hpp>
-# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
-# include <boost/type.hpp>
-# endif
-
namespace boost { namespace parameter { namespace aux {
# if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
@@ -102,41 +98,6 @@ struct match
{};
# endif
-# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
-
-// Function template argument deduction does many of the same things
-// as type matching during partial specialization, so we call a
-// function template to "store" T into the type memory addressed by
-// void(*)(T).
-template <class T>
-msvc_store_type<T,void*(*)(void**(T))>
-msvc_store_predicate_type(void*(*)(void**(T)));
-
-template <class T>
-msvc_store_type<boost::is_convertible<mpl::_,T>,void*(*)(void*(T))>
-msvc_store_predicate_type(void*(*)(void*(T)));
-
-template <class FunctionType>
-struct unwrap_predicate
-{
- static FunctionType f;
-
- // We don't want the function to be evaluated, just instantiated,
- // so protect it inside of sizeof.
- enum { dummy = sizeof(msvc_store_predicate_type(f)) };
-
- // Now pull the type out of the instantiated base class
- typedef typename msvc_type_memory<FunctionType>::storage::type type;
-};
-
-template <>
-struct unwrap_predicate<void*(*)(void**)>
-{
- typedef mpl::always<mpl::true_> type;
-};
-
-# endif
-
# undef false_
template <
@@ -158,7 +119,6 @@ struct argument_pack
typedef typename mpl::first<result>::type type;
};
-# if 1 //BOOST_WORKAROUND(BOOST_MSVC, < 1300)
// Works around VC6 problem where it won't accept rvalues.
template <class T>
T& as_lvalue(T& value, long)
@@ -171,11 +131,9 @@ T const& as_lvalue(T const& value, int)
{
return value;
}
-# endif
-# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
- || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class Predicate, class T, class Args>
struct apply_predicate
@@ -502,13 +460,7 @@ struct funptr_predicate<void**>
# define BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_deduced_required(tag) \
required<boost::parameter::deduced<tag>
-# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
-
-# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
-# define BOOST_PARAMETER_PREDICATE_TYPE(p) void*(*) (void* p)
-# else
-# define BOOST_PARAMETER_PREDICATE_TYPE(p) void p
-# endif
+# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# define BOOST_PARAMETER_FUNCTION_PARAMETERS_M(r,tag_namespace,i,elem) \
BOOST_PP_COMMA_IF(i) \
@@ -521,24 +473,9 @@ struct funptr_predicate<void**>
) \
) \
, typename boost::parameter::aux::unwrap_predicate< \
- BOOST_PARAMETER_PREDICATE_TYPE(BOOST_PARAMETER_FN_ARG_PRED(elem)) \
+ void BOOST_PARAMETER_FN_ARG_PRED(elem) \
>::type \
>
-# elif BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-# define BOOST_PARAMETER_FUNCTION_PARAMETERS_M(r,tag_namespace,i,elem) \
- BOOST_PP_COMMA_IF(i) \
- boost::parameter::BOOST_PP_CAT( \
- BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_ \
- , BOOST_PARAMETER_FN_ARG_QUALIFIER(elem) \
- )( \
- tag_namespace::BOOST_PARAMETER_FUNCTION_KEYWORD( \
- BOOST_PARAMETER_FN_ARG_KEYWORD(elem) \
- ) \
- ) \
- , boost::parameter::aux::funptr_predicate< \
- void* BOOST_PARAMETER_FN_ARG_PRED(elem) \
- > \
- >
# elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# define BOOST_PARAMETER_FUNCTION_PARAMETERS_M(r,tag_namespace,i,elem) \
BOOST_PP_COMMA_IF(i) \
@@ -583,21 +520,6 @@ struct funptr_predicate<void**>
typedef typename BOOST_PARAMETER_PARENTHESIZED_TYPE(result) type; \
};
-# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
-
-# define BOOST_PARAMETER_FUNCTION_RESULT(result, name, args) \
- BOOST_PARAMETER_FUNCTION_RESULT_(result, name, args) \
- template <> \
- struct BOOST_PARAMETER_FUNCTION_RESULT_NAME(name)<int> \
- { typedef int type; };
-
-# else
-
-# define BOOST_PARAMETER_FUNCTION_RESULT(result, name, args) \
- BOOST_PARAMETER_FUNCTION_RESULT_(result, name, args)
-
-# endif
-
// Defines implementation function
# define BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name) \
template <class Args> \
@@ -896,7 +818,7 @@ struct funptr_predicate<void**>
BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) \
ResultType BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \
ResultType(*)() \
- , Args const& args \
+ , Args const& \
, int \
BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG \
@@ -915,7 +837,7 @@ struct funptr_predicate<void**>
// Defines the result metafunction and the parameters specialization.
# define BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_namespace, args) \
- BOOST_PARAMETER_FUNCTION_RESULT(result, name, args) \
+ BOOST_PARAMETER_FUNCTION_RESULT_(result, name, args) \
\
BOOST_PARAMETER_FUNCTION_PARAMETERS(tag_namespace, name, args) \
BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(name); \
@@ -1021,18 +943,6 @@ struct funptr_predicate<void**>
BOOST_PP_COMMA_IF(i) elem& BOOST_PP_CAT(a, i)
/**/
-# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
-
-// Older MSVC can't do what's necessary to handle commas in base names; just
-// use a typedef instead if you have a base name that contains commas.
-# define BOOST_PARAMETER_PARENTHESIZED_BASE(x) BOOST_PP_SEQ_HEAD(x)
-
-# else
-
-# define BOOST_PARAMETER_PARENTHESIZED_BASE(x) BOOST_PARAMETER_PARENTHESIZED_TYPE(x)
-
-# endif
-
# define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR00(z, n, r, data, elem) \
BOOST_PP_IF( \
n \
@@ -1057,7 +967,7 @@ struct funptr_predicate<void**>
, n \
) \
) \
- : BOOST_PARAMETER_PARENTHESIZED_BASE(BOOST_PP_TUPLE_ELEM(6,3,data)) ( \
+ : BOOST_PARAMETER_PARENTHESIZED_TYPE(BOOST_PP_TUPLE_ELEM(6,3,data)) ( \
BOOST_PP_CAT(constructor_parameters, __LINE__)()( \
BOOST_PP_ENUM_PARAMS_Z(z, n, a) \
) \
@@ -1148,18 +1058,7 @@ struct funptr_predicate<void**>
, (const ParameterArgumentType ## i)(ParameterArgumentType ## i) \
, (const ParameterArgumentType ## i) \
))
-// MSVC6.5 lets us bind rvalues to T&.
-# elif BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-# define BOOST_PARAMETER_FUNCTION_FWD_COMBINATION(r, _, i, elem) \
- (BOOST_PP_IF( \
- BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER( \
- BOOST_PARAMETER_FN_ARG_NAME(elem) \
- ) \
- , (ParameterArgumentType ## i) \
- , (const ParameterArgumentType ## i) \
- ))
// No partial ordering. This feature doesn't work.
-// This is exactly the same as for VC6.5, but we might change it later.
# else
# define BOOST_PARAMETER_FUNCTION_FWD_COMBINATION(r, _, i, elem) \
(BOOST_PP_IF( \
diff --git a/boost/parameter/value_type.hpp b/boost/parameter/value_type.hpp
index 7415a5cd2a..a323dcf37c 100755..100644
--- a/boost/parameter/value_type.hpp
+++ b/boost/parameter/value_type.hpp
@@ -12,18 +12,13 @@
# include <boost/parameter/aux_/void.hpp>
# include <boost/type_traits/is_same.hpp>
-# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-# include <boost/mpl/eval_if.hpp>
-# endif
-
namespace boost { namespace parameter {
// A metafunction that, given an argument pack, returns the type of
// the parameter identified by the given keyword. If no such
// parameter has been specified, returns Default
-# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
- || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class Parameters, class Keyword, class Default>
struct value_type0
{
@@ -41,14 +36,9 @@ struct value_type0
# endif
template <class Parameters, class Keyword, class Default = void_>
-# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
struct value_type
-# else
-struct value_type_eti
-# endif
{
-# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
- || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
typedef typename mpl::eval_if<
mpl::is_placeholder<Parameters>
, mpl::identity<int>
@@ -67,24 +57,8 @@ struct value_type_eti
));
# endif
-# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
- BOOST_MPL_AUX_LAMBDA_SUPPORT(3,value_type,(Parameters,Keyword,Default))
-# endif
-};
-
-# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-template <class Parameters, class Keyword, class Default = void_>
-struct value_type
-{
- typedef typename mpl::eval_if<
- is_same<Parameters, int>
- , mpl::identity<int>
- , value_type_eti<Parameters, Keyword, Default>
- >::type type;
-
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,value_type,(Parameters,Keyword,Default))
};
-# endif
// A metafunction that, given an argument pack, returns the type of
// the parameter identified by the given keyword. If no such
diff --git a/boost/phoenix/scope/let.hpp b/boost/phoenix/scope/let.hpp
index 8581112db7..14c6a157c9 100644
--- a/boost/phoenix/scope/let.hpp
+++ b/boost/phoenix/scope/let.hpp
@@ -119,7 +119,7 @@ namespace boost { namespace phoenix
locals_type locals = initialize_locals(proto::value(vars_), ctx);
- typedef typename result<let_eval(Vars const&, Map const&, Expr const &, Context const &)>::type result_type;
+ //typedef typename result<let_eval(Vars const&, Map const&, Expr const &, Context const &)>::type result_type;
scoped_environment<
env_type
@@ -136,7 +136,7 @@ namespace boost { namespace phoenix
//strm << vsize << std::endl;
//int size = strm.str().length();
//BOOST_ASSERT(size >= 0);
- result_type r = eval(expr, phoenix::context(env, phoenix::actions(ctx)));
+ return eval(expr, phoenix::context(env, phoenix::actions(ctx)));
// typedef is_value<result_type> is_val;
//if(is_val::value) This seems always to be true
//{
@@ -144,7 +144,7 @@ namespace boost { namespace phoenix
// }
//if (is_val(r) ) std::cout << "let returns val" << std::endl;
//std::cout << "result is " << r << std::endl;
- return r;
+ //return r;
}
};
diff --git a/boost/polygon/detail/voronoi_ctypes.hpp b/boost/polygon/detail/voronoi_ctypes.hpp
index d8580dda4e..a2ea9ffd63 100644
--- a/boost/polygon/detail/voronoi_ctypes.hpp
+++ b/boost/polygon/detail/voronoi_ctypes.hpp
@@ -470,7 +470,7 @@ class extended_int {
ret_val.first *= static_cast<fpt64>(0x100000000LL);
ret_val.first += static_cast<fpt64>(this->chunks_[sz - i]);
}
- ret_val.second = (sz - 3) << 5;
+ ret_val.second = static_cast<int>((sz - 3) << 5);
}
}
if (this->count_ < 0)
@@ -490,7 +490,7 @@ class extended_int {
add(c2, sz2, c1, sz1);
return;
}
- this->count_ = sz1;
+ this->count_ = static_cast<int32>(sz1);
uint64 temp = 0;
for (std::size_t i = 0; i < sz2; ++i) {
temp += static_cast<uint64>(c1[i]) + static_cast<uint64>(c2[i]);
@@ -534,7 +534,7 @@ class extended_int {
}
sz2 = sz1;
}
- this->count_ = sz1-1;
+ this->count_ = static_cast<int32>(sz1-1);
bool flag = false;
for (std::size_t i = 0; i < sz2; ++i) {
this->chunks_[i] = c1[i] - c2[i] - (flag?1:0);
diff --git a/boost/polygon/voronoi_diagram.hpp b/boost/polygon/voronoi_diagram.hpp
index 7df26ec4e1..33803f4eba 100644
--- a/boost/polygon/voronoi_diagram.hpp
+++ b/boost/polygon/voronoi_diagram.hpp
@@ -347,8 +347,8 @@ class voronoi_diagram {
const detail::site_event<CT>& site1,
const detail::site_event<CT>& site2) {
// Get sites' indexes.
- int site_index1 = site1.sorted_index();
- int site_index2 = site2.sorted_index();
+ std::size_t site_index1 = site1.sorted_index();
+ std::size_t site_index2 = site2.sorted_index();
bool is_linear = is_linear_edge(site1, site2);
bool is_primary = is_primary_edge(site1, site2);
diff --git a/boost/predef.h b/boost/predef.h
index 753cd61e8b..36d731fa41 100644
--- a/boost/predef.h
+++ b/boost/predef.h
@@ -1,12 +1,14 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
+#if !defined(BOOST_PREDEF_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
#ifndef BOOST_PREDEF_H
#define BOOST_PREDEF_H
+#endif
#include <boost/predef/language.h>
#include <boost/predef/architecture.h>
@@ -16,4 +18,6 @@ http://www.boost.org/LICENSE_1_0.txt)
#include <boost/predef/other.h>
#include <boost/predef/platform.h>
+#include <boost/predef/version.h>
+
#endif
diff --git a/boost/predef/architecture.h b/boost/predef/architecture.h
index b32701ecea..c433d437bd 100644
--- a/boost/predef/architecture.h
+++ b/boost/predef/architecture.h
@@ -1,12 +1,14 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
+#if !defined(BOOST_PREDEF_ARCHITECTURE_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
#ifndef BOOST_PREDEF_ARCHITECTURE_H
#define BOOST_PREDEF_ARCHITECTURE_H
+#endif
#include <boost/predef/architecture/alpha.h>
#include <boost/predef/architecture/arm.h>
diff --git a/boost/predef/architecture/alpha.h b/boost/predef/architecture/alpha.h
index 6365ec45e4..5bcade18b1 100644
--- a/boost/predef/architecture/alpha.h
+++ b/boost/predef/architecture/alpha.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -53,8 +53,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ARCH_ALPHA_NAME "DEC Alpha"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_ALPHA,BOOST_ARCH_ALPHA_NAME)
-
-
-#endif
diff --git a/boost/predef/architecture/arm.h b/boost/predef/architecture/arm.h
index 4974895b2c..b200c62777 100644
--- a/boost/predef/architecture/arm.h
+++ b/boost/predef/architecture/arm.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Copyright Franz Detro 2014
Copyright (c) Microsoft Corporation 2014
Distributed under the Boost Software License, Version 1.0.
@@ -64,8 +64,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ARCH_ARM_NAME "ARM"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_ARM,BOOST_ARCH_ARM_NAME)
-
-
-#endif
diff --git a/boost/predef/architecture/blackfin.h b/boost/predef/architecture/blackfin.h
index ae3407e935..84c58a25e9 100644
--- a/boost/predef/architecture/blackfin.h
+++ b/boost/predef/architecture/blackfin.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2013
+Copyright Rene Rivera 2013-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -40,8 +40,7 @@ Blackfin Processors from Analog Devices.
#define BOOST_ARCH_BLACKFIN_NAME "Blackfin"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_BLACKFIN,BOOST_ARCH_BLACKFIN_NAME)
-
-
-#endif
diff --git a/boost/predef/architecture/convex.h b/boost/predef/architecture/convex.h
index 3b425a04cf..ac783a9cc1 100644
--- a/boost/predef/architecture/convex.h
+++ b/boost/predef/architecture/convex.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2011-2013
+Copyright Rene Rivera 2011-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -59,9 +59,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ARCH_CONVEX_NAME "Convex Computer"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_CONVEX,BOOST_ARCH_CONVEX_NAME)
-
-
-
-#endif
diff --git a/boost/predef/architecture/ia64.h b/boost/predef/architecture/ia64.h
index 4b5a10331f..9b1972bd39 100644
--- a/boost/predef/architecture/ia64.h
+++ b/boost/predef/architecture/ia64.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -43,7 +43,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ARCH_IA64_NAME "Intel Itanium 64"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_IA64,BOOST_ARCH_IA64_NAME)
-
-#endif
diff --git a/boost/predef/architecture/m68k.h b/boost/predef/architecture/m68k.h
index 09c3cd3a02..63ed5f8479 100644
--- a/boost/predef/architecture/m68k.h
+++ b/boost/predef/architecture/m68k.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -76,8 +76,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ARCH_M68K_NAME "Motorola 68k"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_M68K,BOOST_ARCH_M68K_NAME)
-
-
-#endif
diff --git a/boost/predef/architecture/mips.h b/boost/predef/architecture/mips.h
index ae88428c28..0189d7dbd6 100644
--- a/boost/predef/architecture/mips.h
+++ b/boost/predef/architecture/mips.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -67,8 +67,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ARCH_MIPS_NAME "MIPS"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_MIPS,BOOST_ARCH_MIPS_NAME)
-
-
-#endif
diff --git a/boost/predef/architecture/parisc.h b/boost/predef/architecture/parisc.h
index e843dd2106..7c7625f912 100644
--- a/boost/predef/architecture/parisc.h
+++ b/boost/predef/architecture/parisc.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -58,8 +58,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ARCH_PARISC_NAME "HP/PA RISC"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PARISC,BOOST_ARCH_PARISC_NAME)
-
-
-#endif
diff --git a/boost/predef/architecture/ppc.h b/boost/predef/architecture/ppc.h
index cc743e74f6..e8c57c91f2 100644
--- a/boost/predef/architecture/ppc.h
+++ b/boost/predef/architecture/ppc.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -66,8 +66,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ARCH_PPC_NAME "PowerPC"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PPC,BOOST_ARCH_PPC_NAME)
-
-
-#endif
diff --git a/boost/predef/architecture/pyramid.h b/boost/predef/architecture/pyramid.h
index 26d5293e68..4f13253807 100644
--- a/boost/predef/architecture/pyramid.h
+++ b/boost/predef/architecture/pyramid.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2011-2013
+Copyright Rene Rivera 2011-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -36,8 +36,7 @@ Pyramid 9810 architecture.
#define BOOST_ARCH_PYRAMID_NAME "Pyramid 9810"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PYRAMID,BOOST_ARCH_PYRAMID_NAME)
-
-
-#endif
diff --git a/boost/predef/architecture/rs6k.h b/boost/predef/architecture/rs6k.h
index 20dd64bac1..8a6e9b6b53 100644
--- a/boost/predef/architecture/rs6k.h
+++ b/boost/predef/architecture/rs6k.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -42,9 +42,6 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ARCH_RS6000_NAME "RS/6000"
-#include <boost/predef/detail/test.h>
-BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_RS6000,BOOST_ARCH_RS6000_NAME)
-
#define BOOST_ARCH_PWR BOOST_ARCH_RS6000
#if BOOST_ARCH_PWR
@@ -54,3 +51,6 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_RS6000,BOOST_ARCH_RS6000_NAME)
#define BOOST_ARCH_PWR_NAME BOOST_ARCH_RS6000_NAME
#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_RS6000,BOOST_ARCH_RS6000_NAME)
diff --git a/boost/predef/architecture/sparc.h b/boost/predef/architecture/sparc.h
index 9c91cdacad..a89a5100b8 100644
--- a/boost/predef/architecture/sparc.h
+++ b/boost/predef/architecture/sparc.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -48,8 +48,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ARCH_SPARC_NAME "SPARC"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SPARC,BOOST_ARCH_SPARC_NAME)
-
-
-#endif
diff --git a/boost/predef/architecture/superh.h b/boost/predef/architecture/superh.h
index ef88242d1a..da0529e5e0 100644
--- a/boost/predef/architecture/superh.h
+++ b/boost/predef/architecture/superh.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -61,8 +61,7 @@ If available versions \[1-5\] are specifically detected.
#define BOOST_ARCH_SH_NAME "SuperH"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SH,BOOST_ARCH_SH_NAME)
-
-
-#endif
diff --git a/boost/predef/architecture/sys370.h b/boost/predef/architecture/sys370.h
index 507ee8637e..cfd85dc803 100644
--- a/boost/predef/architecture/sys370.h
+++ b/boost/predef/architecture/sys370.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -37,8 +37,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ARCH_SYS370_NAME "System/370"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SYS370,BOOST_ARCH_SYS370_NAME)
-
-
-#endif
diff --git a/boost/predef/architecture/sys390.h b/boost/predef/architecture/sys390.h
index 070117a70d..47aff6acd6 100644
--- a/boost/predef/architecture/sys390.h
+++ b/boost/predef/architecture/sys390.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -37,8 +37,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ARCH_SYS390_NAME "System/390"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SYS390,BOOST_ARCH_SYS390_NAME)
-
-
-#endif
diff --git a/boost/predef/architecture/x86.h b/boost/predef/architecture/x86.h
index fa9a025c4c..0ef3ef45ef 100644
--- a/boost/predef/architecture/x86.h
+++ b/boost/predef/architecture/x86.h
@@ -1,16 +1,16 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
-#ifndef BOOST_PREDEF_ARCHITECTURE_X86_H
-#define BOOST_PREDEF_ARCHITECTURE_X86_H
-
#include <boost/predef/architecture/x86/32.h>
#include <boost/predef/architecture/x86/64.h>
+#ifndef BOOST_PREDEF_ARCHITECTURE_X86_H
+#define BOOST_PREDEF_ARCHITECTURE_X86_H
+
/*`
[heading `BOOST_ARCH_X86`]
@@ -32,7 +32,7 @@ a category to indicate that either `BOOST_ARCH_X86_32` or
#define BOOST_ARCH_X86_NAME "Intel x86"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86,BOOST_ARCH_X86_NAME)
-
-#endif
diff --git a/boost/predef/architecture/x86/32.h b/boost/predef/architecture/x86/32.h
index b796f841c4..17fbff554a 100644
--- a/boost/predef/architecture/x86/32.h
+++ b/boost/predef/architecture/x86/32.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -79,9 +79,9 @@ If available versions \[3-6\] are specifically detected.
#define BOOST_ARCH_X86_32_NAME "Intel x86-32"
-#include <boost/predef/detail/test.h>
-BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86_32,BOOST_ARCH_X86_32_NAME)
-
#include <boost/predef/architecture/x86.h>
#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86_32,BOOST_ARCH_X86_32_NAME)
diff --git a/boost/predef/architecture/x86/64.h b/boost/predef/architecture/x86/64.h
index a035c88b15..f761c92596 100644
--- a/boost/predef/architecture/x86/64.h
+++ b/boost/predef/architecture/x86/64.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -42,9 +42,9 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ARCH_X86_64_NAME "Intel x86-64"
-#include <boost/predef/detail/test.h>
-BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86_64,BOOST_ARCH_X86_64_NAME)
-
#include <boost/predef/architecture/x86.h>
#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86_64,BOOST_ARCH_X86_64_NAME)
diff --git a/boost/predef/architecture/z.h b/boost/predef/architecture/z.h
index 768f342772..3d218aa264 100644
--- a/boost/predef/architecture/z.h
+++ b/boost/predef/architecture/z.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -36,8 +36,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ARCH_Z_NAME "z/Architecture"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_Z,BOOST_ARCH_Z_NAME)
-
-
-#endif
diff --git a/boost/predef/compiler.h b/boost/predef/compiler.h
index 12c4dfcb88..61a4c527ab 100644
--- a/boost/predef/compiler.h
+++ b/boost/predef/compiler.h
@@ -1,12 +1,14 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
+#if !defined(BOOST_PREDEF_COMPILER_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
#ifndef BOOST_PREDEF_COMPILER_H
#define BOOST_PREDEF_COMPILER_H
+#endif
#include <boost/predef/compiler/borland.h>
#include <boost/predef/compiler/clang.h>
diff --git a/boost/predef/compiler/borland.h b/boost/predef/compiler/borland.h
index 01b5de7c6e..3677cca7fd 100644
--- a/boost/predef/compiler/borland.h
+++ b/boost/predef/compiler/borland.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -52,6 +52,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_BORLAND_NAME "Borland C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_BORLAND,BOOST_COMP_BORLAND_NAME)
@@ -59,6 +61,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_BORLAND,BOOST_COMP_BORLAND_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_BORLAND_EMULATED,BOOST_COMP_BORLAND_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/clang.h b/boost/predef/compiler/clang.h
index 87dd033c57..56678fe6a5 100644
--- a/boost/predef/compiler/clang.h
+++ b/boost/predef/compiler/clang.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -45,6 +45,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_CLANG_NAME "Clang"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_CLANG,BOOST_COMP_CLANG_NAME)
@@ -52,6 +54,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_CLANG,BOOST_COMP_CLANG_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_CLANG_EMULATED,BOOST_COMP_CLANG_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/comeau.h b/boost/predef/compiler/comeau.h
index 386218404d..15a4564896 100644
--- a/boost/predef/compiler/comeau.h
+++ b/boost/predef/compiler/comeau.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -29,7 +29,7 @@ Version number available as major, minor, and patch.
*/
#if defined(__COMO__)
-# if !defined(BOOST_COMP_COMO_DETECTION) && defined(__CONO_VERSION__)
+# if !defined(BOOST_COMP_COMO_DETECTION) && defined(__COMO_VERSION__)
# define BOOST_COMP_COMO_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__COMO_VERSION__)
# endif
# if !defined(BOOST_COMP_COMO_DETECTION)
@@ -50,6 +50,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_COMO_NAME "Comeau C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_COMO,BOOST_COMP_COMO_NAME)
@@ -57,6 +59,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_COMO,BOOST_COMP_COMO_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_COMO_EMULATED,BOOST_COMP_COMO_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/compaq.h b/boost/predef/compiler/compaq.h
index a922d170f8..96a79e6756 100644
--- a/boost/predef/compiler/compaq.h
+++ b/boost/predef/compiler/compaq.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -55,6 +55,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_DEC_NAME "Compaq C/C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DEC,BOOST_COMP_DEC_NAME)
@@ -62,6 +64,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DEC,BOOST_COMP_DEC_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DEC_EMULATED,BOOST_COMP_DEC_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/diab.h b/boost/predef/compiler/diab.h
index 2cba03b972..f5a37de7d3 100644
--- a/boost/predef/compiler/diab.h
+++ b/boost/predef/compiler/diab.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -45,6 +45,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_DIAB_NAME "Diab C/C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DIAB,BOOST_COMP_DIAB_NAME)
@@ -52,6 +54,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DIAB,BOOST_COMP_DIAB_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DIAB_EMULATED,BOOST_COMP_DIAB_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/digitalmars.h b/boost/predef/compiler/digitalmars.h
index 2306a7e3a7..9bd58502e0 100644
--- a/boost/predef/compiler/digitalmars.h
+++ b/boost/predef/compiler/digitalmars.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -45,6 +45,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_DMC_NAME "Digital Mars"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DMC,BOOST_COMP_DMC_NAME)
@@ -52,6 +54,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DMC,BOOST_COMP_DMC_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DMC_EMULATED,BOOST_COMP_DMC_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/dignus.h b/boost/predef/compiler/dignus.h
index 33c3560f97..c65d3dc764 100644
--- a/boost/predef/compiler/dignus.h
+++ b/boost/predef/compiler/dignus.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -45,6 +45,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_SYSC_NAME "Dignus Systems/C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SYSC,BOOST_COMP_SYSC_NAME)
@@ -52,6 +54,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SYSC,BOOST_COMP_SYSC_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SYSC_EMULATED,BOOST_COMP_SYSC_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/edg.h b/boost/predef/compiler/edg.h
index d53a5ffba6..2ffb9b0a6d 100644
--- a/boost/predef/compiler/edg.h
+++ b/boost/predef/compiler/edg.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -45,6 +45,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_EDG_NAME "EDG C++ Frontend"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_EDG,BOOST_COMP_EDG_NAME)
@@ -52,6 +54,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_EDG,BOOST_COMP_EDG_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_EDG_EMULATED,BOOST_COMP_EDG_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/ekopath.h b/boost/predef/compiler/ekopath.h
index 4d7dabea7c..e5cde36752 100644
--- a/boost/predef/compiler/ekopath.h
+++ b/boost/predef/compiler/ekopath.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -46,6 +46,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_PATH_NAME "EKOpath"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PATH,BOOST_COMP_PATH_NAME)
@@ -53,6 +55,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PATH,BOOST_COMP_PATH_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PATH_EMULATED,BOOST_COMP_PATH_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/gcc.h b/boost/predef/compiler/gcc.h
index 5b226bdfab..c2d7fff178 100644
--- a/boost/predef/compiler/gcc.h
+++ b/boost/predef/compiler/gcc.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -57,6 +57,8 @@ Version number available as major, minor, and patch (if available).
#define BOOST_COMP_GNUC_NAME "Gnu GCC C/C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GNUC,BOOST_COMP_GNUC_NAME)
@@ -64,6 +66,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GNUC,BOOST_COMP_GNUC_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GNUC_EMULATED,BOOST_COMP_GNUC_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/gcc_xml.h b/boost/predef/compiler/gcc_xml.h
index ef55f5d431..acae600c81 100644
--- a/boost/predef/compiler/gcc_xml.h
+++ b/boost/predef/compiler/gcc_xml.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -42,6 +42,8 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_COMP_GCCXML_NAME "GCC XML"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GCCXML,BOOST_COMP_GCCXML_NAME)
@@ -49,5 +51,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GCCXML,BOOST_COMP_GCCXML_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GCCXML_EMULATED,BOOST_COMP_GCCXML_NAME)
#endif
-
-#endif
diff --git a/boost/predef/compiler/greenhills.h b/boost/predef/compiler/greenhills.h
index 462f57b611..23b8f017d8 100644
--- a/boost/predef/compiler/greenhills.h
+++ b/boost/predef/compiler/greenhills.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -55,6 +55,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_GHS_NAME "Green Hills C/C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GHS,BOOST_COMP_GHS_NAME)
@@ -62,6 +64,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GHS,BOOST_COMP_GHS_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GHS_EMULATED,BOOST_COMP_GHS_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/hp_acc.h b/boost/predef/compiler/hp_acc.h
index 8cb7022d3b..7b3ffe9068 100644
--- a/boost/predef/compiler/hp_acc.h
+++ b/boost/predef/compiler/hp_acc.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -50,6 +50,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_HPACC_NAME "HP aC++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HPACC,BOOST_COMP_HPACC_NAME)
@@ -57,6 +59,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HPACC,BOOST_COMP_HPACC_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HPACC_EMULATED,BOOST_COMP_HPACC_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/iar.h b/boost/predef/compiler/iar.h
index dd6bc0e095..237f492e29 100644
--- a/boost/predef/compiler/iar.h
+++ b/boost/predef/compiler/iar.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -45,6 +45,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_IAR_NAME "IAR C/C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IAR,BOOST_COMP_IAR_NAME)
@@ -52,6 +54,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IAR,BOOST_COMP_IAR_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IAR_EMULATED,BOOST_COMP_IAR_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/ibm.h b/boost/predef/compiler/ibm.h
index 1edc93c364..6931ebd884 100644
--- a/boost/predef/compiler/ibm.h
+++ b/boost/predef/compiler/ibm.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -61,6 +61,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_IBM_NAME "IBM XL C/C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IBM,BOOST_COMP_IBM_NAME)
@@ -68,6 +70,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IBM,BOOST_COMP_IBM_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IBM_EMULATED,BOOST_COMP_IBM_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/intel.h b/boost/predef/compiler/intel.h
index 60220c7bfe..65bde6778a 100644
--- a/boost/predef/compiler/intel.h
+++ b/boost/predef/compiler/intel.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -54,6 +54,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_INTEL_NAME "Intel C/C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_INTEL,BOOST_COMP_INTEL_NAME)
@@ -61,6 +63,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_INTEL,BOOST_COMP_INTEL_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_INTEL_EMULATED,BOOST_COMP_INTEL_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/kai.h b/boost/predef/compiler/kai.h
index 4aadbe329d..68ce84e146 100644
--- a/boost/predef/compiler/kai.h
+++ b/boost/predef/compiler/kai.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -45,6 +45,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_KCC_NAME "Kai C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_KCC,BOOST_COMP_KCC_NAME)
@@ -52,6 +54,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_KCC,BOOST_COMP_KCC_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_KCC_EMULATED,BOOST_COMP_KCC_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/llvm.h b/boost/predef/compiler/llvm.h
index c7e634c312..de654eb8ce 100644
--- a/boost/predef/compiler/llvm.h
+++ b/boost/predef/compiler/llvm.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -46,6 +46,8 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_COMP_LLVM_NAME "LLVM"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_LLVM,BOOST_COMP_LLVM_NAME)
@@ -53,6 +55,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_LLVM,BOOST_COMP_LLVM_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_LLVM_EMULATED,BOOST_COMP_LLVM_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/metaware.h b/boost/predef/compiler/metaware.h
index 5e13de854a..1a32039cef 100644
--- a/boost/predef/compiler/metaware.h
+++ b/boost/predef/compiler/metaware.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -42,6 +42,8 @@ MetaWare High C/C++ compiler.
#define BOOST_COMP_HIGHC_NAME "MetaWare High C/C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HIGHC,BOOST_COMP_HIGHC_NAME)
@@ -49,6 +51,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HIGHC,BOOST_COMP_HIGHC_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HIGHC_EMULATED,BOOST_COMP_HIGHC_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/metrowerks.h b/boost/predef/compiler/metrowerks.h
index 409282b339..f2d739b958 100644
--- a/boost/predef/compiler/metrowerks.h
+++ b/boost/predef/compiler/metrowerks.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -66,6 +66,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_MWERKS_NAME "Metrowerks CodeWarrior"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MWERKS,BOOST_COMP_MWERKS_NAME)
@@ -73,6 +75,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MWERKS,BOOST_COMP_MWERKS_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MWERKS_EMULATED,BOOST_COMP_MWERKS_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/microtec.h b/boost/predef/compiler/microtec.h
index 6bd627905b..066a6d2ad9 100644
--- a/boost/predef/compiler/microtec.h
+++ b/boost/predef/compiler/microtec.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -42,6 +42,8 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_COMP_MRI_NAME "Microtec C/C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MRI,BOOST_COMP_MRI_NAME)
@@ -49,6 +51,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MRI,BOOST_COMP_MRI_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MRI_EMULATED,BOOST_COMP_MRI_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/mpw.h b/boost/predef/compiler/mpw.h
index 3a48f6f74a..118330646e 100644
--- a/boost/predef/compiler/mpw.h
+++ b/boost/predef/compiler/mpw.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -52,6 +52,8 @@ Version number available as major, and minor.
#define BOOST_COMP_MPW_NAME "MPW C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MPW,BOOST_COMP_MPW_NAME)
@@ -59,6 +61,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MPW,BOOST_COMP_MPW_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MPW_EMULATED,BOOST_COMP_MPW_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/palm.h b/boost/predef/compiler/palm.h
index eb1da971cf..707925a651 100644
--- a/boost/predef/compiler/palm.h
+++ b/boost/predef/compiler/palm.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -45,6 +45,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_PALM_NAME "Palm C/C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PALM,BOOST_COMP_PALM_NAME)
@@ -52,6 +54,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PALM,BOOST_COMP_PALM_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PALM_EMULATED,BOOST_COMP_PALM_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/pgi.h b/boost/predef/compiler/pgi.h
index 563335ff3c..e016aeb080 100644
--- a/boost/predef/compiler/pgi.h
+++ b/boost/predef/compiler/pgi.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -49,6 +49,8 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_COMP_PGI_NAME "Portland Group C/C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PGI,BOOST_COMP_PGI_NAME)
@@ -56,6 +58,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PGI,BOOST_COMP_PGI_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PGI_EMULATED,BOOST_COMP_PGI_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/sgi_mipspro.h b/boost/predef/compiler/sgi_mipspro.h
index c212b19f4f..00739f0c3c 100644
--- a/boost/predef/compiler/sgi_mipspro.h
+++ b/boost/predef/compiler/sgi_mipspro.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -55,6 +55,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_SGI_NAME "SGI MIPSpro"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SGI,BOOST_COMP_SGI_NAME)
@@ -62,6 +64,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SGI,BOOST_COMP_SGI_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SGI_EMULATED,BOOST_COMP_SGI_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/sunpro.h b/boost/predef/compiler/sunpro.h
index bd3da279dd..92c3926013 100644
--- a/boost/predef/compiler/sunpro.h
+++ b/boost/predef/compiler/sunpro.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -14,7 +14,7 @@ http://www.boost.org/LICENSE_1_0.txt)
/*`
[heading `BOOST_COMP_SUNPRO`]
-[@http://en.wikipedia.org/wiki/Sun_Studio_%28software%29 Sun Studio] compiler.
+[@http://en.wikipedia.org/wiki/Oracle_Solaris_Studio Oracle Solaris Studio] compiler.
Version number available as major, minor, and patch.
[table
@@ -25,6 +25,8 @@ Version number available as major, minor, and patch.
[[`__SUNPRO_CC`] [V.R.P]]
[[`__SUNPRO_C`] [V.R.P]]
+ [[`__SUNPRO_CC`] [VV.RR.P]]
+ [[`__SUNPRO_C`] [VV.RR.P]]
]
*/
@@ -32,10 +34,18 @@ Version number available as major, minor, and patch.
#if defined(__SUNPRO_CC) || defined(__SUNPRO_C)
# if !defined(BOOST_COMP_SUNPRO_DETECTION) && defined(__SUNPRO_CC)
-# define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__SUNPRO_CC)
+# if (__SUNPRO_CC < 0x5100)
+# define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__SUNPRO_CC)
+# else
+# define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VVRRP(__SUNPRO_CC)
+# endif
# endif
# if !defined(BOOST_COMP_SUNPRO_DETECTION) && defined(__SUNPRO_C)
-# define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__SUNPRO_C)
+# if (__SUNPRO_C < 0x5100)
+# define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__SUNPRO_C)
+# else
+# define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VVRRP(__SUNPRO_C)
+# endif
# endif
# if !defined(BOOST_COMP_SUNPRO_DETECTION)
# define BOOST_COMP_SUNPRO_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
@@ -53,7 +63,9 @@ Version number available as major, minor, and patch.
# include <boost/predef/detail/comp_detected.h>
#endif
-#define BOOST_COMP_SUNPRO_NAME "Sun Studio"
+#define BOOST_COMP_SUNPRO_NAME "Oracle Solaris Studio"
+
+#endif
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SUNPRO,BOOST_COMP_SUNPRO_NAME)
@@ -62,6 +74,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SUNPRO,BOOST_COMP_SUNPRO_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SUNPRO_EMULATED,BOOST_COMP_SUNPRO_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/tendra.h b/boost/predef/compiler/tendra.h
index 194f0af83a..c2bc5e4ef5 100644
--- a/boost/predef/compiler/tendra.h
+++ b/boost/predef/compiler/tendra.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -42,6 +42,8 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_COMP_TENDRA_NAME "TenDRA C/C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_TENDRA,BOOST_COMP_TENDRA_NAME)
@@ -49,6 +51,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_TENDRA,BOOST_COMP_TENDRA_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_TENDRA_EMULATED,BOOST_COMP_TENDRA_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/visualc.h b/boost/predef/compiler/visualc.h
index 959d38f267..9481d9d9fd 100644
--- a/boost/predef/compiler/visualc.h
+++ b/boost/predef/compiler/visualc.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -80,6 +80,8 @@ Version number available as major, minor, and patch.
#define BOOST_COMP_MSVC_NAME "Microsoft Visual C/C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MSVC,BOOST_COMP_MSVC_NAME)
@@ -87,6 +89,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MSVC,BOOST_COMP_MSVC_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MSVC_EMULATED,BOOST_COMP_MSVC_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/compiler/watcom.h b/boost/predef/compiler/watcom.h
index 832d10c54a..b0e7776d06 100644
--- a/boost/predef/compiler/watcom.h
+++ b/boost/predef/compiler/watcom.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2014
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -45,6 +45,8 @@ Version number available as major, and minor.
#define BOOST_COMP_WATCOM_NAME "Watcom C++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_WATCOM,BOOST_COMP_WATCOM_NAME)
@@ -52,6 +54,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_WATCOM,BOOST_COMP_WATCOM_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_WATCOM_EMULATED,BOOST_COMP_WATCOM_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/detail/test_def.h b/boost/predef/detail/test_def.h
new file mode 100644
index 0000000000..c2f195bfd6
--- /dev/null
+++ b/boost/predef/detail/test_def.h
@@ -0,0 +1,71 @@
+/*
+Copyright Rene Rivera 2011-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+#include <boost/predef.h>
+
+#define BOOST_PREDEF_INTERNAL_GENERATE_TESTS
+
+void * add_predef_entry(const char * name, const char * description, unsigned value);
+#undef BOOST_PREDEF_DECLARE_TEST
+#define BOOST_PREDEF_DECLARE_TEST(x,s) void predef_entry_##x() { add_predef_entry(#x, s, x); }
+#include <boost/predef.h>
+
+#undef BOOST_PREDEF_DECLARE_TEST
+#define BOOST_PREDEF_DECLARE_TEST(x,s) predef_entry_##x();
+void create_predef_entries()
+{
+#include <boost/predef.h>
+}
+
+#ifdef __cplusplus
+#include <cstring>
+#include <cstdio>
+#include <cstdlib>
+using namespace std;
+#else
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+typedef struct predef_info
+{
+ const char * name;
+ const char * description;
+ unsigned value;
+} predef_info;
+
+#ifdef __cplusplus
+using namespace std;
+#endif
+
+unsigned generated_predef_info_count = 0;
+predef_info* generated_predef_info = 0;
+void * add_predef_entry(const char * name, const char * description, unsigned value)
+{
+ if (0 == generated_predef_info_count)
+ {
+ generated_predef_info_count = 1;
+ generated_predef_info = (predef_info*)malloc(sizeof(predef_info));
+ }
+ else
+ {
+ generated_predef_info_count += 1;
+ generated_predef_info = (predef_info*)realloc(generated_predef_info,
+ generated_predef_info_count*sizeof(predef_info));
+ }
+ generated_predef_info[generated_predef_info_count-1].name = name;
+ generated_predef_info[generated_predef_info_count-1].description = description;
+ generated_predef_info[generated_predef_info_count-1].value = value;
+ return 0;
+}
+
+int predef_info_compare(const void * a, const void * b)
+{
+ const predef_info * i = (const predef_info *)a;
+ const predef_info * j = (const predef_info *)b;
+ return strcmp(i->name,j->name);
+}
diff --git a/boost/predef/language.h b/boost/predef/language.h
index c9251c52ae..0a317d5ece 100644
--- a/boost/predef/language.h
+++ b/boost/predef/language.h
@@ -1,12 +1,14 @@
/*
-Copyright Rene Rivera 2011-2012
+Copyright Rene Rivera 2011-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
+#if !defined(BOOST_PREDEF_LANGUAGE_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
#ifndef BOOST_PREDEF_LANGUAGE_H
#define BOOST_PREDEF_LANGUAGE_H
+#endif
#include <boost/predef/language/stdc.h>
#include <boost/predef/language/stdcpp.h>
diff --git a/boost/predef/language/objc.h b/boost/predef/language/objc.h
index 27a32b6372..24e3ad3c5c 100644
--- a/boost/predef/language/objc.h
+++ b/boost/predef/language/objc.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2011-2013
+Copyright Rene Rivera 2011-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -36,8 +36,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_LANG_OBJC_NAME "Objective-C"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_OBJC,BOOST_LANG_OBJC_NAME)
-
-
-#endif
diff --git a/boost/predef/language/stdc.h b/boost/predef/language/stdc.h
index 59a4e0bb47..db25c12dc0 100644
--- a/boost/predef/language/stdc.h
+++ b/boost/predef/language/stdc.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2011-2012
+Copyright Rene Rivera 2011-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -47,8 +47,7 @@ If available, the year of the standard is detected as YYYY.MM.1 from the Epoc da
#define BOOST_LANG_STDC_NAME "Standard C"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDC,BOOST_LANG_STDC_NAME)
-
-
-#endif
diff --git a/boost/predef/language/stdcpp.h b/boost/predef/language/stdcpp.h
index 693c67b02a..34dc8c7deb 100644
--- a/boost/predef/language/stdcpp.h
+++ b/boost/predef/language/stdcpp.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2011-2013
+Copyright Rene Rivera 2011-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -52,10 +52,6 @@ Specifically the defined versions are:
#define BOOST_LANG_STDCPP_NAME "Standard C++"
-#include <boost/predef/detail/test.h>
-BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDCPP,BOOST_LANG_STDCPP_NAME)
-
-
/*`
[heading `BOOST_LANG_STDCPPCLI`]
@@ -88,10 +84,6 @@ If available, the year of the standard is detected as YYYY.MM.1 from the Epoc da
#define BOOST_LANG_STDCPPCLI_NAME "Standard C++/CLI"
-#include <boost/predef/detail/test.h>
-BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDCPPCLI,BOOST_LANG_STDCPPCLI_NAME)
-
-
/*`
[heading `BOOST_LANG_STDECPP`]
@@ -117,8 +109,13 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDCPPCLI,BOOST_LANG_STDCPPCLI_NAME)
#define BOOST_LANG_STDECPP_NAME "Standard Embedded C++"
+#endif
+
#include <boost/predef/detail/test.h>
-BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDECPP,BOOST_LANG_STDECPP_NAME)
+BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDCPP,BOOST_LANG_STDCPP_NAME)
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDCPPCLI,BOOST_LANG_STDCPPCLI_NAME)
-#endif
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDECPP,BOOST_LANG_STDECPP_NAME)
diff --git a/boost/predef/library.h b/boost/predef/library.h
index a474323f3e..40518a90d8 100644
--- a/boost/predef/library.h
+++ b/boost/predef/library.h
@@ -1,12 +1,14 @@
/*
-Copyright Rene Rivera 2008-2012
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
+#if !defined(BOOST_PREDEF_LIBRARY_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
#ifndef BOOST_PREDEF_LIBRARY_H
#define BOOST_PREDEF_LIBRARY_H
+#endif
#include <boost/predef/library/c.h>
#include <boost/predef/library/std.h>
diff --git a/boost/predef/library/c.h b/boost/predef/library/c.h
index 733e6a7c87..fa8841e827 100644
--- a/boost/predef/library/c.h
+++ b/boost/predef/library/c.h
@@ -1,12 +1,14 @@
/*
-Copyright Rene Rivera 2008-2012
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
+#if !defined(BOOST_PREDEF_LIBRARY_C_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
#ifndef BOOST_PREDEF_LIBRARY_C_H
#define BOOST_PREDEF_LIBRARY_C_H
+#endif
#include <boost/predef/library/c/_prefix.h>
diff --git a/boost/predef/library/c/gnu.h b/boost/predef/library/c/gnu.h
index 8ed9f76a3d..9e4ca89d64 100644
--- a/boost/predef/library/c/gnu.h
+++ b/boost/predef/library/c/gnu.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -55,8 +55,7 @@ Version number available as major, and minor.
#define BOOST_LIB_C_GNU_NAME "GNU"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_GNU,BOOST_LIB_C_GNU_NAME)
-
-
-#endif
diff --git a/boost/predef/library/c/uc.h b/boost/predef/library/c/uc.h
index 8b47de15a8..03081e94c6 100644
--- a/boost/predef/library/c/uc.h
+++ b/boost/predef/library/c/uc.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -41,8 +41,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_LIB_C_UC_NAME "uClibc"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_UC,BOOST_LIB_C_UC_NAME)
-
-
-#endif
diff --git a/boost/predef/library/c/vms.h b/boost/predef/library/c/vms.h
index 0357d05e68..685f1a77d6 100644
--- a/boost/predef/library/c/vms.h
+++ b/boost/predef/library/c/vms.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -41,8 +41,7 @@ Version number available as major, minor, and patch.
#define BOOST_LIB_C_VMS_NAME "VMS"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_VMS,BOOST_LIB_C_VMS_NAME)
-
-
-#endif
diff --git a/boost/predef/library/c/zos.h b/boost/predef/library/c/zos.h
index 4c6f0581d1..222d35539f 100644
--- a/boost/predef/library/c/zos.h
+++ b/boost/predef/library/c/zos.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -50,8 +50,7 @@ Version number available as major, minor, and patch.
#define BOOST_LIB_C_ZOS_NAME "z/OS"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_ZOS,BOOST_LIB_C_ZOS_NAME)
-
-
-#endif
diff --git a/boost/predef/library/std.h b/boost/predef/library/std.h
index 9ab0a863c4..403b6ff37a 100644
--- a/boost/predef/library/std.h
+++ b/boost/predef/library/std.h
@@ -1,11 +1,13 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
+#if !defined(BOOST_PREDEF_LIBRARY_STD_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
#ifndef BOOST_PREDEF_LIBRARY_STD_H
#define BOOST_PREDEF_LIBRARY_STD_H
+#endif
#include <boost/predef/library/std/_prefix.h>
diff --git a/boost/predef/library/std/cxx.h b/boost/predef/library/std/cxx.h
index 1d0cf5f2b9..07b52cd6af 100644
--- a/boost/predef/library/std/cxx.h
+++ b/boost/predef/library/std/cxx.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2011-2013
+Copyright Rene Rivera 2011-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -40,8 +40,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_LIB_STD_CXX_NAME "libc++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_CXX,BOOST_LIB_STD_CXX_NAME)
-
-
-#endif
diff --git a/boost/predef/library/std/dinkumware.h b/boost/predef/library/std/dinkumware.h
index 394e866ea5..0fc077605d 100644
--- a/boost/predef/library/std/dinkumware.h
+++ b/boost/predef/library/std/dinkumware.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -46,8 +46,7 @@ If available version number as major, minor, and patch.
#define BOOST_LIB_STD_DINKUMWARE_NAME "Dinkumware"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_DINKUMWARE,BOOST_LIB_STD_DINKUMWARE_NAME)
-
-
-#endif
diff --git a/boost/predef/library/std/libcomo.h b/boost/predef/library/std/libcomo.h
index 41bbe67781..97d4a53d6f 100644
--- a/boost/predef/library/std/libcomo.h
+++ b/boost/predef/library/std/libcomo.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -41,8 +41,7 @@ Version number available as major.
#define BOOST_LIB_STD_COMO_NAME "Comeau Computing"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_COMO,BOOST_LIB_STD_COMO_NAME)
-
-
-#endif
diff --git a/boost/predef/library/std/modena.h b/boost/predef/library/std/modena.h
index fa7c061cfe..b67ac62f17 100644
--- a/boost/predef/library/std/modena.h
+++ b/boost/predef/library/std/modena.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -39,8 +39,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_LIB_STD_MSIPL_NAME "Modena Software Lib++"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_MSIPL,BOOST_LIB_STD_MSIPL_NAME)
-
-
-#endif
diff --git a/boost/predef/library/std/msl.h b/boost/predef/library/std/msl.h
index 16ddec6905..d73c74c6d8 100644
--- a/boost/predef/library/std/msl.h
+++ b/boost/predef/library/std/msl.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -47,8 +47,7 @@ Version number available as major, minor, and patch.
#define BOOST_LIB_STD_MSL_NAME "Metrowerks"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_MSL,BOOST_LIB_STD_MSL_NAME)
-
-
-#endif
diff --git a/boost/predef/library/std/roguewave.h b/boost/predef/library/std/roguewave.h
index 38471d09ab..9c3f288b6f 100644
--- a/boost/predef/library/std/roguewave.h
+++ b/boost/predef/library/std/roguewave.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -50,8 +50,7 @@ If available version number as major, minor, and patch.
#define BOOST_LIB_STD_RW_NAME "Roguewave"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_RW,BOOST_LIB_STD_RW_NAME)
-
-
-#endif
diff --git a/boost/predef/library/std/sgi.h b/boost/predef/library/std/sgi.h
index 16f0db1076..5d19bbac4d 100644
--- a/boost/predef/library/std/sgi.h
+++ b/boost/predef/library/std/sgi.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -45,8 +45,7 @@ If available version number as major, minor, and patch.
#define BOOST_LIB_STD_SGI_NAME "SGI"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_SGI,BOOST_LIB_STD_SGI_NAME)
-
-
-#endif
diff --git a/boost/predef/library/std/stdcpp3.h b/boost/predef/library/std/stdcpp3.h
index 19ebc8683d..c9802924a7 100644
--- a/boost/predef/library/std/stdcpp3.h
+++ b/boost/predef/library/std/stdcpp3.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -47,8 +47,7 @@ Version number available as year (from 1970), month, and day.
#define BOOST_LIB_STD_GNU_NAME "GNU"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_GNU,BOOST_LIB_STD_GNU_NAME)
-
-
-#endif
diff --git a/boost/predef/library/std/stlport.h b/boost/predef/library/std/stlport.h
index 1b6cebb018..c09483bd9f 100644
--- a/boost/predef/library/std/stlport.h
+++ b/boost/predef/library/std/stlport.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -53,8 +53,7 @@ Version number available as major, minor, and patch.
#define BOOST_LIB_STD_STLPORT_NAME "STLport"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_STLPORT,BOOST_LIB_STD_STLPORT_NAME)
-
-
-#endif
diff --git a/boost/predef/library/std/vacpp.h b/boost/predef/library/std/vacpp.h
index 1c259c558c..632f846c20 100644
--- a/boost/predef/library/std/vacpp.h
+++ b/boost/predef/library/std/vacpp.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -38,8 +38,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_LIB_STD_IBM_NAME "IBM VACPP"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_IBM,BOOST_LIB_STD_IBM_NAME)
-
-
-#endif
diff --git a/boost/predef/make.h b/boost/predef/make.h
index f8c28d19d7..4f2f9ee761 100644
--- a/boost/predef/make.h
+++ b/boost/predef/make.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -84,6 +84,6 @@ If the day is not available, but the month is, the 1st of the month is used as t
/*` `BOOST_PREDEF_MAKE_YYYY(V)` */
#define BOOST_PREDEF_MAKE_YYYY(V) BOOST_PREDEF_MAKE_DATE(V,1,1)
/*` `BOOST_PREDEF_MAKE_YYYYMM(V)` */
-#define BOOST_PREDEF_MAKE_YYYYMM(V) BOOST_PREDEF_MAKE_DATE((V)/100,(V),1)
+#define BOOST_PREDEF_MAKE_YYYYMM(V) BOOST_PREDEF_MAKE_DATE((V)/100,(V)%100,1)
#endif
diff --git a/boost/predef/os.h b/boost/predef/os.h
index abd66661eb..bedf99ec54 100644
--- a/boost/predef/os.h
+++ b/boost/predef/os.h
@@ -1,13 +1,15 @@
/*
-Copyright Rene Rivera 2008-2012
+Copyright Rene Rivera 2008-2015
Copyright Franz Detro 2014
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
+#if !defined(BOOST_PREDEF_OS_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
#ifndef BOOST_PREDEF_OS_H
#define BOOST_PREDEF_OS_H
+#endif
#include <boost/predef/os/aix.h>
#include <boost/predef/os/amigaos.h>
diff --git a/boost/predef/os/aix.h b/boost/predef/os/aix.h
index 07523c8de4..3e5a953f1b 100644
--- a/boost/predef/os/aix.h
+++ b/boost/predef/os/aix.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -60,8 +60,7 @@ Version number available as major, minor, and patch.
#define BOOST_OS_AIX_NAME "IBM AIX"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_AIX,BOOST_OS_AIX_NAME)
-
-
-#endif
diff --git a/boost/predef/os/amigaos.h b/boost/predef/os/amigaos.h
index fae2408bd6..7b32ddf59c 100644
--- a/boost/predef/os/amigaos.h
+++ b/boost/predef/os/amigaos.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -40,8 +40,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_AMIGAOS_NAME "AmigaOS"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_AMIGAOS,BOOST_OS_AMIGAOS_NAME)
-
-
-#endif
diff --git a/boost/predef/os/android.h b/boost/predef/os/android.h
index 0de5870d49..00836e7fce 100644
--- a/boost/predef/os/android.h
+++ b/boost/predef/os/android.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2013
+Copyright Rene Rivera 2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -39,8 +39,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_ANDROID_NAME "Android"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_ANDROID,BOOST_OS_ANDROID_NAME)
-
-
-#endif
diff --git a/boost/predef/os/beos.h b/boost/predef/os/beos.h
index 7a92b944ab..19f4cb71e3 100644
--- a/boost/predef/os/beos.h
+++ b/boost/predef/os/beos.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -39,8 +39,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_BEOS_NAME "BeOS"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BEOS,BOOST_OS_BEOS_NAME)
-
-
-#endif
diff --git a/boost/predef/os/bsd.h b/boost/predef/os/bsd.h
index f370f56bad..fad9aed787 100644
--- a/boost/predef/os/bsd.h
+++ b/boost/predef/os/bsd.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -89,7 +89,15 @@ of BSD. If the above variants is detected the corresponding macro is also set.]
#define BOOST_OS_BSD_NAME "BSD"
-#include <boost/predef/detail/test.h>
-BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD,BOOST_OS_BSD_NAME)
+#else
+
+#include <boost/predef/os/bsd/bsdi.h>
+#include <boost/predef/os/bsd/dragonfly.h>
+#include <boost/predef/os/bsd/free.h>
+#include <boost/predef/os/bsd/open.h>
+#include <boost/predef/os/bsd/net.h>
#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD,BOOST_OS_BSD_NAME)
diff --git a/boost/predef/os/bsd/bsdi.h b/boost/predef/os/bsd/bsdi.h
index cb57e1bcd4..afdcd3eb7c 100644
--- a/boost/predef/os/bsd/bsdi.h
+++ b/boost/predef/os/bsd/bsdi.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2012-2013
+Copyright Rene Rivera 2012-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -42,7 +42,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_BSD_BSDI_NAME "BSDi BSD/OS"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_BSDI,BOOST_OS_BSD_BSDI_NAME)
-
-#endif
diff --git a/boost/predef/os/bsd/dragonfly.h b/boost/predef/os/bsd/dragonfly.h
index 202f8a1de2..1d075798a1 100644
--- a/boost/predef/os/bsd/dragonfly.h
+++ b/boost/predef/os/bsd/dragonfly.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2012-2013
+Copyright Rene Rivera 2012-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -44,7 +44,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_BSD_DRAGONFLY_NAME "DragonFly BSD"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_DRAGONFLY,BOOST_OS_BSD_DRAGONFLY_NAME)
-
-#endif
diff --git a/boost/predef/os/bsd/free.h b/boost/predef/os/bsd/free.h
index 404e8ed830..248011ae7a 100644
--- a/boost/predef/os/bsd/free.h
+++ b/boost/predef/os/bsd/free.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2012-2013
+Copyright Rene Rivera 2012-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -54,7 +54,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_BSD_FREE_NAME "Free BSD"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_FREE,BOOST_OS_BSD_FREE_NAME)
-
-#endif
diff --git a/boost/predef/os/bsd/net.h b/boost/predef/os/bsd/net.h
index dcc4131b8f..387cbde54f 100644
--- a/boost/predef/os/bsd/net.h
+++ b/boost/predef/os/bsd/net.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2012-2013
+Copyright Rene Rivera 2012-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -78,7 +78,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_BSD_NET_NAME "DragonFly BSD"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_NET,BOOST_OS_BSD_NET_NAME)
-
-#endif
diff --git a/boost/predef/os/bsd/open.h b/boost/predef/os/bsd/open.h
index e81ebc6435..423103ac5c 100644
--- a/boost/predef/os/bsd/open.h
+++ b/boost/predef/os/bsd/open.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2012-2013
+Copyright Rene Rivera 2012-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -165,7 +165,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_BSD_OPEN_NAME "OpenBSD"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_OPEN,BOOST_OS_BSD_OPEN_NAME)
-
-#endif
diff --git a/boost/predef/os/cygwin.h b/boost/predef/os/cygwin.h
index 04ee3995e0..1985c97edc 100644
--- a/boost/predef/os/cygwin.h
+++ b/boost/predef/os/cygwin.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -39,8 +39,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_CYGWIN_NAME "Cygwin"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_CYGWIN,BOOST_OS_CYGWIN_NAME)
-
-
-#endif
diff --git a/boost/predef/os/haiku.h b/boost/predef/os/haiku.h
index 4d741cf5ce..d79dbeac88 100644
--- a/boost/predef/os/haiku.h
+++ b/boost/predef/os/haiku.h
@@ -1,6 +1,6 @@
/*
Copyright Jessica Hamilton 2014
-Copyright Rene Rivera 2014
+Copyright Rene Rivera 2014-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -40,8 +40,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_HAIKU_NAME "Haiku"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_HAIKU,BOOST_OS_HAIKU_NAME)
-
-
-#endif
diff --git a/boost/predef/os/hpux.h b/boost/predef/os/hpux.h
index 946196f4a7..29243f4879 100644
--- a/boost/predef/os/hpux.h
+++ b/boost/predef/os/hpux.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -41,8 +41,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_HPUX_NAME "HP-UX"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_HPUX,BOOST_OS_HPUX_NAME)
-
-
-#endif
diff --git a/boost/predef/os/ios.h b/boost/predef/os/ios.h
index b83a9db537..f853815a6d 100644
--- a/boost/predef/os/ios.h
+++ b/boost/predef/os/ios.h
@@ -1,5 +1,6 @@
/*
Copyright Franz Detro 2014
+Copyright Rene Rivera 2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -44,8 +45,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_IOS_NAME "iOS"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_IOS,BOOST_OS_IOS_NAME)
-
-
-#endif
diff --git a/boost/predef/os/irix.h b/boost/predef/os/irix.h
index a9e63b855d..fa6ac41dcd 100644
--- a/boost/predef/os/irix.h
+++ b/boost/predef/os/irix.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -40,8 +40,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_IRIX_NAME "IRIX"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_IRIX,BOOST_OS_IRIX_NAME)
-
-
-#endif
diff --git a/boost/predef/os/linux.h b/boost/predef/os/linux.h
index b436e3fd4d..a297d08954 100644
--- a/boost/predef/os/linux.h
+++ b/boost/predef/os/linux.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -40,8 +40,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_LINUX_NAME "Linux"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_LINUX,BOOST_OS_LINUX_NAME)
-
-
-#endif
diff --git a/boost/predef/os/macos.h b/boost/predef/os/macos.h
index cdcf2cb2b2..4afb30d087 100644
--- a/boost/predef/os/macos.h
+++ b/boost/predef/os/macos.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Copyright Franz Detro 2014
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
@@ -59,8 +59,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_MACOS_NAME "Mac OS"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_MACOS,BOOST_OS_MACOS_NAME)
-
-
-#endif
diff --git a/boost/predef/os/os400.h b/boost/predef/os/os400.h
index f7aacf533b..b3446c26c9 100644
--- a/boost/predef/os/os400.h
+++ b/boost/predef/os/os400.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2011-2013
+Copyright Rene Rivera 2011-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -39,8 +39,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_OS400_NAME "IBM OS/400"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_OS400,BOOST_OS_OS400_NAME)
-
-
-#endif
diff --git a/boost/predef/os/qnxnto.h b/boost/predef/os/qnxnto.h
index dff536f2d8..e76fbf2781 100644
--- a/boost/predef/os/qnxnto.h
+++ b/boost/predef/os/qnxnto.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -53,8 +53,7 @@ version 4 is specifically detected.
#define BOOST_OS_QNX_NAME "QNX"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_QNX,BOOST_OS_QNX_NAME)
-
-
-#endif
diff --git a/boost/predef/os/solaris.h b/boost/predef/os/solaris.h
index 4d47dfec1d..75ddc91dae 100644
--- a/boost/predef/os/solaris.h
+++ b/boost/predef/os/solaris.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -40,8 +40,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_SOLARIS_NAME "Solaris"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_SOLARIS,BOOST_OS_SOLARIS_NAME)
-
-
-#endif
diff --git a/boost/predef/os/unix.h b/boost/predef/os/unix.h
index 3636dda512..a60710427a 100644
--- a/boost/predef/os/unix.h
+++ b/boost/predef/os/unix.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -69,8 +69,8 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_SVR4_NAME "SVR4 Environment"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_UNIX,BOOST_OS_UNIX_NAME)
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_SVR4,BOOST_OS_SVR4_NAME)
-
-#endif
diff --git a/boost/predef/os/vms.h b/boost/predef/os/vms.h
index 3d34f63dd9..2f8f786d4e 100644
--- a/boost/predef/os/vms.h
+++ b/boost/predef/os/vms.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2011-2013
+Copyright Rene Rivera 2011-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -46,8 +46,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_VMS_NAME "VMS"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_VMS,BOOST_OS_VMS_NAME)
-
-
-#endif
diff --git a/boost/predef/os/windows.h b/boost/predef/os/windows.h
index 9072539ae0..9db4390950 100644
--- a/boost/predef/os/windows.h
+++ b/boost/predef/os/windows.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -45,7 +45,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_OS_WINDOWS_NAME "Microsoft Windows"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_OS_WINDOWS,BOOST_OS_WINDOWS_NAME)
-
-#endif
diff --git a/boost/predef/other.h b/boost/predef/other.h
index 04aad1680e..c09ad4945f 100644
--- a/boost/predef/other.h
+++ b/boost/predef/other.h
@@ -1,12 +1,14 @@
/*
-Copyright Rene Rivera 2013
+Copyright Rene Rivera 2013-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
+#if !defined(BOOST_PREDEF_OTHER_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
#ifndef BOOST_PREDEF_OTHER_H
#define BOOST_PREDEF_OTHER_H
+#endif
#include <boost/predef/other/endian.h>
/*#include <boost/predef/other/.h>*/
diff --git a/boost/predef/other/endian.h b/boost/predef/other/endian.h
index 85a028dff9..6d1f43ff4d 100644
--- a/boost/predef/other/endian.h
+++ b/boost/predef/other/endian.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2013-2014
+Copyright Rene Rivera 2013-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -140,7 +140,7 @@ information and acquired knowledge:
!BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
# include <boost/predef/architecture.h>
# if BOOST_ARCH_M68K || \
- BOOST_ARCH_PARISK || \
+ BOOST_ARCH_PARISC || \
BOOST_ARCH_SPARC || \
BOOST_ARCH_SYS370 || \
BOOST_ARCH_SYS390 || \
@@ -189,6 +189,8 @@ information and acquired knowledge:
#define BOOST_ENDIAN_LITTLE_BYTE_NAME "Byte-Swapped Little-Endian"
#define BOOST_ENDIAN_LITTLE_WORD_NAME "Word-Swapped Little-Endian"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_BYTE,BOOST_ENDIAN_BIG_BYTE_NAME)
@@ -200,6 +202,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_BYTE,BOOST_ENDIAN_LITTLE_BYTE_NAME
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_WORD,BOOST_ENDIAN_LITTLE_WORD_NAME)
-
-
-#endif
diff --git a/boost/predef/platform.h b/boost/predef/platform.h
index 468a90d38b..c0c8706e8a 100644
--- a/boost/predef/platform.h
+++ b/boost/predef/platform.h
@@ -1,13 +1,15 @@
/*
-Copyright Rene Rivera 2013
+Copyright Rene Rivera 2013-2015
Copyright (c) Microsoft Corporation 2014
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
+#if !defined(BOOST_PREDEF_PLATFORM_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
#ifndef BOOST_PREDEF_PLATFORM_H
#define BOOST_PREDEF_PLATFORM_H
+#endif
#include <boost/predef/platform/mingw.h>
#include <boost/predef/platform/windows_desktop.h>
diff --git a/boost/predef/platform/mingw.h b/boost/predef/platform/mingw.h
index 6c8d873ca3..64c5837364 100644
--- a/boost/predef/platform/mingw.h
+++ b/boost/predef/platform/mingw.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2008-2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -58,6 +58,8 @@ Version number available as major, minor, and patch.
#define BOOST_PLAT_MINGW_NAME "MinGW"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_MINGW,BOOST_PLAT_MINGW_NAME)
@@ -65,6 +67,3 @@ BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_MINGW,BOOST_PLAT_MINGW_NAME)
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_MINGW_EMULATED,BOOST_PLAT_MINGW_NAME)
#endif
-
-
-#endif
diff --git a/boost/predef/platform/windows_desktop.h b/boost/predef/platform/windows_desktop.h
index 286c27350f..2fd7d5d80c 100644
--- a/boost/predef/platform/windows_desktop.h
+++ b/boost/predef/platform/windows_desktop.h
@@ -1,5 +1,6 @@
/*
Copyright (c) Microsoft Corporation 2014
+Copyright Rene Rivera 2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -38,7 +39,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_PLAT_WINDOWS_DESKTOP_NAME "Windows Desktop"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_DESKTOP,BOOST_PLAT_WINDOWS_DESKTOP_NAME)
-
-#endif
diff --git a/boost/predef/platform/windows_phone.h b/boost/predef/platform/windows_phone.h
index cdf79d1c47..495c9180f9 100644
--- a/boost/predef/platform/windows_phone.h
+++ b/boost/predef/platform/windows_phone.h
@@ -1,5 +1,6 @@
/*
Copyright (c) Microsoft Corporation 2014
+Copyright Rene Rivera 2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -36,7 +37,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_PLAT_WINDOWS_PHONE_NAME "Windows Phone"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_PHONE,BOOST_PLAT_WINDOWS_PHONE_NAME)
-
-#endif
diff --git a/boost/predef/platform/windows_runtime.h b/boost/predef/platform/windows_runtime.h
index 14449383d8..902428e567 100644
--- a/boost/predef/platform/windows_runtime.h
+++ b/boost/predef/platform/windows_runtime.h
@@ -1,5 +1,6 @@
/*
Copyright (c) Microsoft Corporation 2014
+Copyright Rene Rivera 2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -38,7 +39,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_PLAT_WINDOWS_RUNTIME_NAME "Windows Runtime"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_RUNTIME,BOOST_PLAT_WINDOWS_RUNTIME_NAME)
-
-#endif
diff --git a/boost/predef/platform/windows_store.h b/boost/predef/platform/windows_store.h
index 0487c0fa2b..d65821c5de 100644
--- a/boost/predef/platform/windows_store.h
+++ b/boost/predef/platform/windows_store.h
@@ -1,5 +1,6 @@
/*
Copyright (c) Microsoft Corporation 2014
+Copyright Rene Rivera 2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -36,7 +37,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_PLAT_WINDOWS_STORE_NAME "Windows Store"
+#endif
+
#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_STORE,BOOST_PLAT_WINDOWS_STORE_NAME)
-
-#endif
diff --git a/boost/predef/version.h b/boost/predef/version.h
index 0439b2c519..1d57cbbf99 100644
--- a/boost/predef/version.h
+++ b/boost/predef/version.h
@@ -1,5 +1,5 @@
/*
-Copyright Rene Rivera 2014
+Copyright Rene Rivera 2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
@@ -10,6 +10,6 @@ http://www.boost.org/LICENSE_1_0.txt)
#include <boost/predef/version_number.h>
-#define BOOST_PREDEF_VERSION BOOST_VERSION_NUMBER(1,2,0)
+#define BOOST_PREDEF_VERSION BOOST_VERSION_NUMBER(1,3,0)
#endif
diff --git a/boost/predef/version_number.h b/boost/predef/version_number.h
index b77391925c..3903a36b70 100644
--- a/boost/predef/version_number.h
+++ b/boost/predef/version_number.h
@@ -1,6 +1,5 @@
/*
-Copyright Rene Rivera 2005
-Copyright Rene Rivera 2008-2013
+Copyright Rene Rivera 2005, 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)
diff --git a/boost/preprocessor/arithmetic/dec.hpp b/boost/preprocessor/arithmetic/dec.hpp
index 0503359677..23dd0a35a1 100644
--- a/boost/preprocessor/arithmetic/dec.hpp
+++ b/boost/preprocessor/arithmetic/dec.hpp
@@ -284,5 +284,6 @@
# define BOOST_PP_DEC_254 253
# define BOOST_PP_DEC_255 254
# define BOOST_PP_DEC_256 255
+# define BOOST_PP_DEC_257 256
#
# endif
diff --git a/boost/preprocessor/config/config.hpp b/boost/preprocessor/config/config.hpp
index fa5ca5bc79..835b283b7e 100644
--- a/boost/preprocessor/config/config.hpp
+++ b/boost/preprocessor/config/config.hpp
@@ -70,16 +70,18 @@
#
# /* BOOST_PP_VARIADICS */
#
+# define BOOST_PP_VARIADICS_MSVC 0
# if !defined BOOST_PP_VARIADICS
# /* variadic support explicitly disabled for all untested compilers */
-# if defined __GCCXML__ || defined __CUDACC__ || defined __PATHSCALE__ || defined __DMC__ || defined __CODEGEARC__ || defined __BORLANDC__ || defined __MWERKS__ || defined __SUNPRO_CC || defined __HP_aCC && !defined __EDG__ || defined __MRC__ || defined __SC__ || defined __IBMCPP__ || defined __PGI
+# if defined __GCCXML__ || defined __CUDACC__ || defined __PATHSCALE__ || defined __DMC__ || defined __CODEGEARC__ || defined __BORLANDC__ || defined __MWERKS__ || ( defined __SUNPRO_CC && __SUNPRO_CC < 0x5130 ) || defined __HP_aCC && !defined __EDG__ || defined __MRC__ || defined __SC__ || defined __IBMCPP__ || defined __PGI
# define BOOST_PP_VARIADICS 0
# /* VC++ (C/C++) */
# elif defined _MSC_VER && _MSC_VER >= 1400 && (!defined __EDG__ || defined(__INTELLISENSE__)) && !defined __clang__
# define BOOST_PP_VARIADICS 1
+# undef BOOST_PP_VARIADICS_MSVC
# define BOOST_PP_VARIADICS_MSVC 1
# /* Wave (C/C++), GCC (C++) */
-# elif defined __WAVE__ && __WAVE_HAS_VARIADICS__ || defined __GNUC__ && __GXX_EXPERIMENTAL_CXX0X__
+# elif defined __WAVE__ && __WAVE_HAS_VARIADICS__ || defined __GNUC__ && defined __GXX_EXPERIMENTAL_CXX0X__ && __GXX_EXPERIMENTAL_CXX0X__
# define BOOST_PP_VARIADICS 1
# /* EDG-based (C/C++), GCC (C), and unknown (C/C++) */
# elif !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L
@@ -91,6 +93,7 @@
# undef BOOST_PP_VARIADICS
# define BOOST_PP_VARIADICS 1
# if defined _MSC_VER && _MSC_VER >= 1400 && (defined(__INTELLISENSE__) || !(defined __EDG__ || defined __GCCXML__ || defined __CUDACC__ || defined __PATHSCALE__ || defined __clang__ || defined __DMC__ || defined __CODEGEARC__ || defined __BORLANDC__ || defined __MWERKS__ || defined __SUNPRO_CC || defined __HP_aCC || defined __MRC__ || defined __SC__ || defined __IBMCPP__ || defined __PGI))
+# undef BOOST_PP_VARIADICS_MSVC
# define BOOST_PP_VARIADICS_MSVC 1
# endif
# else
diff --git a/boost/preprocessor/library.hpp b/boost/preprocessor/library.hpp
index aa5b777849..3fb03d8837 100644
--- a/boost/preprocessor/library.hpp
+++ b/boost/preprocessor/library.hpp
@@ -32,5 +32,6 @@
# include <boost/preprocessor/stringize.hpp>
# include <boost/preprocessor/tuple.hpp>
# include <boost/preprocessor/variadic.hpp>
+# include <boost/preprocessor/wstringize.hpp>
#
# endif
diff --git a/boost/preprocessor/repetition/for.hpp b/boost/preprocessor/repetition/for.hpp
index 5a63753d9c..c38946bb55 100644
--- a/boost/preprocessor/repetition/for.hpp
+++ b/boost/preprocessor/repetition/for.hpp
@@ -16,6 +16,8 @@
#
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/debug/error.hpp>
+# include <boost/preprocessor/facilities/empty.hpp>
+# include <boost/preprocessor/logical/bool.hpp>
# include <boost/preprocessor/detail/auto_rec.hpp>
#
# /* BOOST_PP_FOR */
@@ -42,7 +44,23 @@
# include <boost/preprocessor/repetition/detail/for.hpp>
# endif
#
-# define BOOST_PP_FOR_257(s, p, o, m) BOOST_PP_ERROR(0x0002)
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC()
+# define BOOST_PP_FOR_257_PR(s, p) BOOST_PP_BOOL(p##(257, s))
+# else
+# define BOOST_PP_FOR_257_PR(s, p) BOOST_PP_BOOL(p(257, s))
+# endif
+
+# define BOOST_PP_FOR_257_ERROR() BOOST_PP_ERROR(0x0002)
+# define BOOST_PP_FOR_257(s, p, o, m) \
+ BOOST_PP_IIF \
+ ( \
+ BOOST_PP_FOR_257_PR(s,p), \
+ BOOST_PP_FOR_257_ERROR, \
+ BOOST_PP_EMPTY \
+ ) \
+ () \
+/**/
+// # define BOOST_PP_FOR_257(s, p, o, m) BOOST_PP_ERROR(0x0002)
#
# define BOOST_PP_FOR_CHECK_BOOST_PP_NIL 1
#
diff --git a/boost/preprocessor/seq/detail/is_empty.hpp b/boost/preprocessor/seq/detail/is_empty.hpp
new file mode 100644
index 0000000000..1a80a2f611
--- /dev/null
+++ b/boost/preprocessor/seq/detail/is_empty.hpp
@@ -0,0 +1,49 @@
+# /* **************************************************************************
+# * *
+# * (C) Copyright Edward Diener 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 for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_SEQ_DETAIL_IS_EMPTY_HPP
+# define BOOST_PREPROCESSOR_SEQ_DETAIL_IS_EMPTY_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/arithmetic/dec.hpp>
+# include <boost/preprocessor/logical/bool.hpp>
+# include <boost/preprocessor/logical/compl.hpp>
+# include <boost/preprocessor/seq/size.hpp>
+#
+/* An empty seq is one that is just BOOST_PP_SEQ_NIL */
+#
+# define BOOST_PP_SEQ_DETAIL_IS_EMPTY(seq) \
+ BOOST_PP_COMPL \
+ ( \
+ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY(seq) \
+ ) \
+/**/
+#
+# define BOOST_PP_SEQ_DETAIL_IS_EMPTY_SIZE(size) \
+ BOOST_PP_COMPL \
+ ( \
+ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY_SIZE(size) \
+ ) \
+/**/
+#
+# define BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY(seq) \
+ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY_SIZE(BOOST_PP_SEQ_DETAIL_EMPTY_SIZE(seq)) \
+/**/
+#
+# define BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY_SIZE(size) \
+ BOOST_PP_BOOL(size) \
+/**/
+#
+# define BOOST_PP_SEQ_DETAIL_EMPTY_SIZE(seq) \
+ BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq (nil))) \
+/**/
+#
+# endif
diff --git a/boost/preprocessor/seq/for_each.hpp b/boost/preprocessor/seq/for_each.hpp
index e997a9a852..3f9c0d781b 100644
--- a/boost/preprocessor/seq/for_each.hpp
+++ b/boost/preprocessor/seq/for_each.hpp
@@ -14,47 +14,94 @@
#
# include <boost/preprocessor/arithmetic/dec.hpp>
# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/control/if.hpp>
+# include <boost/preprocessor/control/iif.hpp>
# include <boost/preprocessor/repetition/for.hpp>
# include <boost/preprocessor/seq/seq.hpp>
# include <boost/preprocessor/seq/size.hpp>
+# include <boost/preprocessor/seq/detail/is_empty.hpp>
# include <boost/preprocessor/tuple/elem.hpp>
# include <boost/preprocessor/tuple/rem.hpp>
#
# /* BOOST_PP_SEQ_FOR_EACH */
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
-# define BOOST_PP_SEQ_FOR_EACH(macro, data, seq) BOOST_PP_FOR((macro, data, seq (nil)), BOOST_PP_SEQ_FOR_EACH_P, BOOST_PP_SEQ_FOR_EACH_O, BOOST_PP_SEQ_FOR_EACH_M)
+# define BOOST_PP_SEQ_FOR_EACH(macro, data, seq) BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK(macro, data, seq)
# else
# define BOOST_PP_SEQ_FOR_EACH(macro, data, seq) BOOST_PP_SEQ_FOR_EACH_D(macro, data, seq)
-# define BOOST_PP_SEQ_FOR_EACH_D(macro, data, seq) BOOST_PP_FOR((macro, data, seq (nil)), BOOST_PP_SEQ_FOR_EACH_P, BOOST_PP_SEQ_FOR_EACH_O, BOOST_PP_SEQ_FOR_EACH_M)
+# define BOOST_PP_SEQ_FOR_EACH_D(macro, data, seq) BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK(macro, data, seq)
# endif
#
-# define BOOST_PP_SEQ_FOR_EACH_P(r, x) BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(BOOST_PP_TUPLE_ELEM(3, 2, x)))
+# define BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EXEC(macro, data, seq) BOOST_PP_FOR((macro, data, seq, BOOST_PP_SEQ_SIZE(seq)), BOOST_PP_SEQ_FOR_EACH_P, BOOST_PP_SEQ_FOR_EACH_O, BOOST_PP_SEQ_FOR_EACH_M)
+# define BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EMPTY(macro, data, seq)
+#
+# define BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK(macro, data, seq) \
+ BOOST_PP_IIF \
+ ( \
+ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY(seq), \
+ BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EXEC, \
+ BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EMPTY \
+ ) \
+ (macro, data, seq) \
+/**/
+#
+# define BOOST_PP_SEQ_FOR_EACH_P(r, x) BOOST_PP_TUPLE_ELEM(4, 3, x)
#
# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
# define BOOST_PP_SEQ_FOR_EACH_O(r, x) BOOST_PP_SEQ_FOR_EACH_O_I x
# else
-# define BOOST_PP_SEQ_FOR_EACH_O(r, x) BOOST_PP_SEQ_FOR_EACH_O_I(BOOST_PP_TUPLE_ELEM(3, 0, x), BOOST_PP_TUPLE_ELEM(3, 1, x), BOOST_PP_TUPLE_ELEM(3, 2, x))
+# define BOOST_PP_SEQ_FOR_EACH_O(r, x) BOOST_PP_SEQ_FOR_EACH_O_I(BOOST_PP_TUPLE_ELEM(4, 0, x), BOOST_PP_TUPLE_ELEM(4, 1, x), BOOST_PP_TUPLE_ELEM(4, 2, x), BOOST_PP_TUPLE_ELEM(4, 3, x))
# endif
#
-# define BOOST_PP_SEQ_FOR_EACH_O_I(macro, data, seq) (macro, data, BOOST_PP_SEQ_TAIL(seq))
+# define BOOST_PP_SEQ_FOR_EACH_O_I(macro, data, seq, sz) \
+ BOOST_PP_SEQ_FOR_EACH_O_I_DEC(macro, data, seq, BOOST_PP_DEC(sz)) \
+/**/
+# define BOOST_PP_SEQ_FOR_EACH_O_I_DEC(macro, data, seq, sz) \
+ ( \
+ macro, \
+ data, \
+ BOOST_PP_IF \
+ ( \
+ sz, \
+ BOOST_PP_SEQ_FOR_EACH_O_I_TAIL, \
+ BOOST_PP_SEQ_FOR_EACH_O_I_NIL \
+ ) \
+ (seq), \
+ sz \
+ ) \
+/**/
+# define BOOST_PP_SEQ_FOR_EACH_O_I_TAIL(seq) BOOST_PP_SEQ_TAIL(seq)
+# define BOOST_PP_SEQ_FOR_EACH_O_I_NIL(seq) BOOST_PP_NIL
#
# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
-# define BOOST_PP_SEQ_FOR_EACH_M(r, x) BOOST_PP_SEQ_FOR_EACH_M_IM(r, BOOST_PP_TUPLE_REM_3 x)
+# define BOOST_PP_SEQ_FOR_EACH_M(r, x) BOOST_PP_SEQ_FOR_EACH_M_IM(r, BOOST_PP_TUPLE_REM_4 x)
# define BOOST_PP_SEQ_FOR_EACH_M_IM(r, im) BOOST_PP_SEQ_FOR_EACH_M_I(r, im)
# else
-# define BOOST_PP_SEQ_FOR_EACH_M(r, x) BOOST_PP_SEQ_FOR_EACH_M_I(r, BOOST_PP_TUPLE_ELEM(3, 0, x), BOOST_PP_TUPLE_ELEM(3, 1, x), BOOST_PP_TUPLE_ELEM(3, 2, x))
+# define BOOST_PP_SEQ_FOR_EACH_M(r, x) BOOST_PP_SEQ_FOR_EACH_M_I(r, BOOST_PP_TUPLE_ELEM(4, 0, x), BOOST_PP_TUPLE_ELEM(4, 1, x), BOOST_PP_TUPLE_ELEM(4, 2, x), BOOST_PP_TUPLE_ELEM(4, 3, x))
# endif
#
-# define BOOST_PP_SEQ_FOR_EACH_M_I(r, macro, data, seq) macro(r, data, BOOST_PP_SEQ_HEAD(seq))
+# define BOOST_PP_SEQ_FOR_EACH_M_I(r, macro, data, seq, sz) macro(r, data, BOOST_PP_SEQ_HEAD(seq))
#
# /* BOOST_PP_SEQ_FOR_EACH_R */
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
-# define BOOST_PP_SEQ_FOR_EACH_R(r, macro, data, seq) BOOST_PP_FOR_ ## r((macro, data, seq (nil)), BOOST_PP_SEQ_FOR_EACH_P, BOOST_PP_SEQ_FOR_EACH_O, BOOST_PP_SEQ_FOR_EACH_M)
+# define BOOST_PP_SEQ_FOR_EACH_R(r, macro, data, seq) BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_R(r, macro, data, seq)
# else
# define BOOST_PP_SEQ_FOR_EACH_R(r, macro, data, seq) BOOST_PP_SEQ_FOR_EACH_R_I(r, macro, data, seq)
-# define BOOST_PP_SEQ_FOR_EACH_R_I(r, macro, data, seq) BOOST_PP_FOR_ ## r((macro, data, seq (nil)), BOOST_PP_SEQ_FOR_EACH_P, BOOST_PP_SEQ_FOR_EACH_O, BOOST_PP_SEQ_FOR_EACH_M)
+# define BOOST_PP_SEQ_FOR_EACH_R_I(r, macro, data, seq) BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_R(r, macro, data, seq)
# endif
#
+# define BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EXEC_R(r, macro, data, seq) BOOST_PP_FOR_ ## r((macro, data, seq, BOOST_PP_SEQ_SIZE(seq)), BOOST_PP_SEQ_FOR_EACH_P, BOOST_PP_SEQ_FOR_EACH_O, BOOST_PP_SEQ_FOR_EACH_M)
+# define BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EMPTY_R(r, macro, data, seq)
+#
+# define BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_R(r, macro, data, seq) \
+ BOOST_PP_IIF \
+ ( \
+ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY(seq), \
+ BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EXEC_R, \
+ BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EMPTY_R \
+ ) \
+ (r, macro, data, seq) \
+/**/
+#
# endif
diff --git a/boost/preprocessor/seq/for_each_i.hpp b/boost/preprocessor/seq/for_each_i.hpp
index c8edf5af44..81028d77de 100644
--- a/boost/preprocessor/seq/for_each_i.hpp
+++ b/boost/preprocessor/seq/for_each_i.hpp
@@ -15,47 +15,95 @@
# include <boost/preprocessor/arithmetic/dec.hpp>
# include <boost/preprocessor/arithmetic/inc.hpp>
# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/control/if.hpp>
+# include <boost/preprocessor/control/iif.hpp>
# include <boost/preprocessor/repetition/for.hpp>
# include <boost/preprocessor/seq/seq.hpp>
# include <boost/preprocessor/seq/size.hpp>
+# include <boost/preprocessor/seq/detail/is_empty.hpp>
# include <boost/preprocessor/tuple/elem.hpp>
# include <boost/preprocessor/tuple/rem.hpp>
#
# /* BOOST_PP_SEQ_FOR_EACH_I */
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
-# define BOOST_PP_SEQ_FOR_EACH_I(macro, data, seq) BOOST_PP_FOR((macro, data, seq (nil), 0), BOOST_PP_SEQ_FOR_EACH_I_P, BOOST_PP_SEQ_FOR_EACH_I_O, BOOST_PP_SEQ_FOR_EACH_I_M)
+# define BOOST_PP_SEQ_FOR_EACH_I(macro, data, seq) BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK(macro, data, seq)
# else
# define BOOST_PP_SEQ_FOR_EACH_I(macro, data, seq) BOOST_PP_SEQ_FOR_EACH_I_I(macro, data, seq)
-# define BOOST_PP_SEQ_FOR_EACH_I_I(macro, data, seq) BOOST_PP_FOR((macro, data, seq (nil), 0), BOOST_PP_SEQ_FOR_EACH_I_P, BOOST_PP_SEQ_FOR_EACH_I_O, BOOST_PP_SEQ_FOR_EACH_I_M)
+# define BOOST_PP_SEQ_FOR_EACH_I_I(macro, data, seq) BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK(macro, data, seq)
# endif
#
-# define BOOST_PP_SEQ_FOR_EACH_I_P(r, x) BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(BOOST_PP_TUPLE_ELEM(4, 2, x)))
+# define BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK_EXEC(macro, data, seq) BOOST_PP_FOR((macro, data, seq, 0, BOOST_PP_SEQ_SIZE(seq)), BOOST_PP_SEQ_FOR_EACH_I_P, BOOST_PP_SEQ_FOR_EACH_I_O, BOOST_PP_SEQ_FOR_EACH_I_M)
+# define BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK_EMPTY(macro, data, seq)
+#
+# define BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK(macro, data, seq) \
+ BOOST_PP_IIF \
+ ( \
+ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY(seq), \
+ BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK_EXEC, \
+ BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK_EMPTY \
+ ) \
+ (macro, data, seq) \
+/**/
+#
+# define BOOST_PP_SEQ_FOR_EACH_I_P(r, x) BOOST_PP_TUPLE_ELEM(5, 4, x)
#
# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
# define BOOST_PP_SEQ_FOR_EACH_I_O(r, x) BOOST_PP_SEQ_FOR_EACH_I_O_I x
# else
-# define BOOST_PP_SEQ_FOR_EACH_I_O(r, x) BOOST_PP_SEQ_FOR_EACH_I_O_I(BOOST_PP_TUPLE_ELEM(4, 0, x), BOOST_PP_TUPLE_ELEM(4, 1, x), BOOST_PP_TUPLE_ELEM(4, 2, x), BOOST_PP_TUPLE_ELEM(4, 3, x))
+# define BOOST_PP_SEQ_FOR_EACH_I_O(r, x) BOOST_PP_SEQ_FOR_EACH_I_O_I(BOOST_PP_TUPLE_ELEM(5, 0, x), BOOST_PP_TUPLE_ELEM(5, 1, x), BOOST_PP_TUPLE_ELEM(5, 2, x), BOOST_PP_TUPLE_ELEM(5, 3, x), BOOST_PP_TUPLE_ELEM(5, 4, x))
# endif
#
-# define BOOST_PP_SEQ_FOR_EACH_I_O_I(macro, data, seq, i) (macro, data, BOOST_PP_SEQ_TAIL(seq), BOOST_PP_INC(i))
+# define BOOST_PP_SEQ_FOR_EACH_I_O_I(macro, data, seq, i, sz) \
+ BOOST_PP_SEQ_FOR_EACH_I_O_I_DEC(macro, data, seq, i, BOOST_PP_DEC(sz)) \
+/**/
+# define BOOST_PP_SEQ_FOR_EACH_I_O_I_DEC(macro, data, seq, i, sz) \
+ ( \
+ macro, \
+ data, \
+ BOOST_PP_IF \
+ ( \
+ sz, \
+ BOOST_PP_SEQ_FOR_EACH_I_O_I_TAIL, \
+ BOOST_PP_SEQ_FOR_EACH_I_O_I_NIL \
+ ) \
+ (seq), \
+ BOOST_PP_INC(i), \
+ sz \
+ ) \
+/**/
+# define BOOST_PP_SEQ_FOR_EACH_I_O_I_TAIL(seq) BOOST_PP_SEQ_TAIL(seq)
+# define BOOST_PP_SEQ_FOR_EACH_I_O_I_NIL(seq) BOOST_PP_NIL
#
# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
-# define BOOST_PP_SEQ_FOR_EACH_I_M(r, x) BOOST_PP_SEQ_FOR_EACH_I_M_IM(r, BOOST_PP_TUPLE_REM_4 x)
+# define BOOST_PP_SEQ_FOR_EACH_I_M(r, x) BOOST_PP_SEQ_FOR_EACH_I_M_IM(r, BOOST_PP_TUPLE_REM_5 x)
# define BOOST_PP_SEQ_FOR_EACH_I_M_IM(r, im) BOOST_PP_SEQ_FOR_EACH_I_M_I(r, im)
# else
-# define BOOST_PP_SEQ_FOR_EACH_I_M(r, x) BOOST_PP_SEQ_FOR_EACH_I_M_I(r, BOOST_PP_TUPLE_ELEM(4, 0, x), BOOST_PP_TUPLE_ELEM(4, 1, x), BOOST_PP_TUPLE_ELEM(4, 2, x), BOOST_PP_TUPLE_ELEM(4, 3, x))
+# define BOOST_PP_SEQ_FOR_EACH_I_M(r, x) BOOST_PP_SEQ_FOR_EACH_I_M_I(r, BOOST_PP_TUPLE_ELEM(5, 0, x), BOOST_PP_TUPLE_ELEM(5, 1, x), BOOST_PP_TUPLE_ELEM(5, 2, x), BOOST_PP_TUPLE_ELEM(5, 3, x), BOOST_PP_TUPLE_ELEM(5, 4, x))
# endif
#
-# define BOOST_PP_SEQ_FOR_EACH_I_M_I(r, macro, data, seq, i) macro(r, data, i, BOOST_PP_SEQ_HEAD(seq))
+# define BOOST_PP_SEQ_FOR_EACH_I_M_I(r, macro, data, seq, i, sz) macro(r, data, i, BOOST_PP_SEQ_HEAD(seq))
#
# /* BOOST_PP_SEQ_FOR_EACH_I_R */
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
-# define BOOST_PP_SEQ_FOR_EACH_I_R(r, macro, data, seq) BOOST_PP_FOR_ ## r((macro, data, seq (nil), 0), BOOST_PP_SEQ_FOR_EACH_I_P, BOOST_PP_SEQ_FOR_EACH_I_O, BOOST_PP_SEQ_FOR_EACH_I_M)
+# define BOOST_PP_SEQ_FOR_EACH_I_R(r, macro, data, seq) BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK(r, macro, data, seq)
# else
# define BOOST_PP_SEQ_FOR_EACH_I_R(r, macro, data, seq) BOOST_PP_SEQ_FOR_EACH_I_R_I(r, macro, data, seq)
-# define BOOST_PP_SEQ_FOR_EACH_I_R_I(r, macro, data, seq) BOOST_PP_FOR_ ## r((macro, data, seq (nil), 0), BOOST_PP_SEQ_FOR_EACH_I_P, BOOST_PP_SEQ_FOR_EACH_I_O, BOOST_PP_SEQ_FOR_EACH_I_M)
+# define BOOST_PP_SEQ_FOR_EACH_I_R_I(r, macro, data, seq) BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK(r, macro, data, seq)
# endif
#
+# define BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK_EXEC(r, macro, data, seq) BOOST_PP_FOR_ ## r((macro, data, seq, 0, BOOST_PP_SEQ_SIZE(seq)), BOOST_PP_SEQ_FOR_EACH_I_P, BOOST_PP_SEQ_FOR_EACH_I_O, BOOST_PP_SEQ_FOR_EACH_I_M)
+# define BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK_EMPTY(r, macro, data, seq)
+#
+# define BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK(r, macro, data, seq) \
+ BOOST_PP_IIF \
+ ( \
+ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY(seq), \
+ BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK_EXEC, \
+ BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK_EMPTY \
+ ) \
+ (r, macro, data, seq) \
+/**/
+#
# endif
diff --git a/boost/preprocessor/seq/replace.hpp b/boost/preprocessor/seq/replace.hpp
index d6107a7626..0cf6b77554 100644
--- a/boost/preprocessor/seq/replace.hpp
+++ b/boost/preprocessor/seq/replace.hpp
@@ -12,18 +12,34 @@
# ifndef BOOST_PREPROCESSOR_SEQ_REPLACE_HPP
# define BOOST_PREPROCESSOR_SEQ_REPLACE_HPP
#
+# include <boost/preprocessor/arithmetic/dec.hpp>
# include <boost/preprocessor/arithmetic/inc.hpp>
# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/comparison/equal.hpp>
+# include <boost/preprocessor/control/iif.hpp>
# include <boost/preprocessor/seq/first_n.hpp>
# include <boost/preprocessor/seq/rest_n.hpp>
+# include <boost/preprocessor/seq/size.hpp>
#
# /* BOOST_PP_SEQ_REPLACE */
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
-# define BOOST_PP_SEQ_REPLACE(seq, i, elem) BOOST_PP_SEQ_FIRST_N(i, seq) (elem) BOOST_PP_SEQ_REST_N(BOOST_PP_INC(i), seq)
+# define BOOST_PP_SEQ_REPLACE(seq, i, elem) BOOST_PP_SEQ_FIRST_N(i, seq) (elem) BOOST_PP_SEQ_REPLACE_DETAIL_REST(seq, i)
# else
# define BOOST_PP_SEQ_REPLACE(seq, i, elem) BOOST_PP_SEQ_REPLACE_I(seq, i, elem)
-# define BOOST_PP_SEQ_REPLACE_I(seq, i, elem) BOOST_PP_SEQ_FIRST_N(i, seq) (elem) BOOST_PP_SEQ_REST_N(BOOST_PP_INC(i), seq)
+# define BOOST_PP_SEQ_REPLACE_I(seq, i, elem) BOOST_PP_SEQ_FIRST_N(i, seq) (elem) BOOST_PP_SEQ_REPLACE_DETAIL_REST(seq, i)
# endif
#
+# define BOOST_PP_SEQ_REPLACE_DETAIL_REST_EMPTY(seq, i)
+# define BOOST_PP_SEQ_REPLACE_DETAIL_REST_VALID(seq, i) BOOST_PP_SEQ_REST_N(BOOST_PP_INC(i), seq)
+# define BOOST_PP_SEQ_REPLACE_DETAIL_REST(seq, i) \
+ BOOST_PP_IIF \
+ ( \
+ BOOST_PP_EQUAL(i,BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq))), \
+ BOOST_PP_SEQ_REPLACE_DETAIL_REST_EMPTY, \
+ BOOST_PP_SEQ_REPLACE_DETAIL_REST_VALID \
+ ) \
+ (seq, i) \
+/**/
+#
# endif
diff --git a/boost/preprocessor/seq/rest_n.hpp b/boost/preprocessor/seq/rest_n.hpp
index 64233760de..4aefba4fa1 100644
--- a/boost/preprocessor/seq/rest_n.hpp
+++ b/boost/preprocessor/seq/rest_n.hpp
@@ -13,18 +13,34 @@
# define BOOST_PREPROCESSOR_SEQ_REST_N_HPP
#
# include <boost/preprocessor/arithmetic/inc.hpp>
+# include <boost/preprocessor/comparison/not_equal.hpp>
# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/control/expr_iif.hpp>
# include <boost/preprocessor/facilities/identity.hpp>
+# include <boost/preprocessor/logical/bitand.hpp>
+# include <boost/preprocessor/seq/detail/is_empty.hpp>
# include <boost/preprocessor/seq/detail/split.hpp>
# include <boost/preprocessor/tuple/elem.hpp>
#
# /* BOOST_PP_SEQ_REST_N */
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
-# define BOOST_PP_SEQ_REST_N(n, seq) BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PP_SEQ_SPLIT(BOOST_PP_INC(n), BOOST_PP_IDENTITY( (nil) seq )))()
+# define BOOST_PP_SEQ_REST_N(n, seq) BOOST_PP_SEQ_REST_N_DETAIL_EXEC(n, seq, BOOST_PP_SEQ_DETAIL_EMPTY_SIZE(seq))
# else
# define BOOST_PP_SEQ_REST_N(n, seq) BOOST_PP_SEQ_REST_N_I(n, seq)
-# define BOOST_PP_SEQ_REST_N_I(n, seq) BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PP_SEQ_SPLIT(BOOST_PP_INC(n), BOOST_PP_IDENTITY( (nil) seq )))()
+# define BOOST_PP_SEQ_REST_N_I(n, seq) BOOST_PP_SEQ_REST_N_DETAIL_EXEC(n, seq, BOOST_PP_SEQ_DETAIL_EMPTY_SIZE(seq))
# endif
#
+# define BOOST_PP_SEQ_REST_N_DETAIL_EXEC(n, seq, size) \
+ BOOST_PP_EXPR_IIF \
+ ( \
+ BOOST_PP_BITAND \
+ ( \
+ BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY_SIZE(size), \
+ BOOST_PP_NOT_EQUAL(n,size) \
+ ), \
+ BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PP_SEQ_SPLIT(BOOST_PP_INC(n), BOOST_PP_IDENTITY( (nil) seq )))() \
+ ) \
+/**/
+#
# endif
diff --git a/boost/preprocessor/seq/size.hpp b/boost/preprocessor/seq/size.hpp
index 385c00a192..b5c8d9d051 100644
--- a/boost/preprocessor/seq/size.hpp
+++ b/boost/preprocessor/seq/size.hpp
@@ -543,5 +543,6 @@
# define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_254 254
# define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_255 255
# define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_256 256
+# define BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_257 257
#
# endif
diff --git a/boost/program_options/detail/config_file.hpp b/boost/program_options/detail/config_file.hpp
index 4c2c15b934..be6bba1447 100644
--- a/boost/program_options/detail/config_file.hpp
+++ b/boost/program_options/detail/config_file.hpp
@@ -27,6 +27,11 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/shared_ptr.hpp>
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable: 4251) // class XYZ needs to have dll-interface to be used by clients of class XYZ
+#endif
+
namespace boost { namespace program_options { namespace detail {
@@ -62,7 +67,7 @@ namespace boost { namespace program_options { namespace detail {
TODO: maybe, we should just accept a pointer to options_description
class.
*/
- class common_config_file_iterator
+ class BOOST_PROGRAM_OPTIONS_DECL common_config_file_iterator
: public eof_iterator<common_config_file_iterator, option>
{
public:
@@ -77,6 +82,11 @@ namespace boost { namespace program_options { namespace detail {
void get();
+#if BOOST_WORKAROUND(_MSC_VER, <= 1900)
+ void decrement() {}
+ void advance(difference_type) {}
+#endif
+
protected: // Stubs for derived classes
// Obtains next line from the config file
@@ -177,4 +187,8 @@ namespace boost { namespace program_options { namespace detail {
}}}
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+
#endif
diff --git a/boost/program_options/detail/parsers.hpp b/boost/program_options/detail/parsers.hpp
index af240c6861..8c5b02e87d 100644
--- a/boost/program_options/detail/parsers.hpp
+++ b/boost/program_options/detail/parsers.hpp
@@ -40,7 +40,8 @@ namespace boost { namespace program_options {
: detail::cmdline(
// Explicit template arguments are required by gcc 3.3.1
// (at least mingw version), and do no harm on other compilers.
- to_internal(detail::make_vector<charT, const charT* const*>(argv+1, argv+argc+!argc)))
+ to_internal(detail::make_vector<charT, const charT* const*>(argv+1, argv+argc+!argc))),
+ m_desc()
{}
diff --git a/boost/program_options/environment_iterator.hpp b/boost/program_options/environment_iterator.hpp
index c8156930db..933919d15d 100644
--- a/boost/program_options/environment_iterator.hpp
+++ b/boost/program_options/environment_iterator.hpp
@@ -40,8 +40,9 @@ namespace boost {
assert(n != s.npos);
value().first = s.substr(0, n);
value().second = s.substr(n+1);
- }
- ++m_environment;
+
+ ++m_environment;
+ }
}
private:
diff --git a/boost/program_options/eof_iterator.hpp b/boost/program_options/eof_iterator.hpp
index 0efa6f7720..4eeef0e937 100644
--- a/boost/program_options/eof_iterator.hpp
+++ b/boost/program_options/eof_iterator.hpp
@@ -10,17 +10,17 @@
namespace boost {
- /** The 'eof_iterator' class is useful for constructing forward iterators
- in cases where iterator extract data from some source and it's easy
- to detect 'eof' -- i.e. the situation where there's no data. One
+ /** The 'eof_iterator' class is useful for constructing forward iterators
+ in cases where iterator extract data from some source and it's easy
+ to detect 'eof' \-- i.e. the situation where there's no data. One
apparent example is reading lines from a file.
-
+
Implementing such iterators using 'iterator_facade' directly would
- require to create class with three core operation, a couple of
- constructors. When using 'eof_iterator', the derived class should define
+ require to create class with three core operation, a couple of
+ constructors. When using 'eof_iterator', the derived class should define
only one method to get new value, plus a couple of constructors.
- The basic idea is that iterator has 'eof' bit. Two iterators are equal
+ The basic idea is that iterator has 'eof' bit. Two iterators are equal
only if both have their 'eof' bits set. The 'get' method either obtains
the new value or sets the 'eof' bit.
@@ -33,13 +33,13 @@ namespace boost {
3. The 'get' method. It should operate this way:
- look at some 'data pointer' to see if new element is available;
if not, it should call 'found_eof'.
- - extract new element and store it at location returned by the 'value'
+ - extract new element and store it at location returned by the 'value'
method.
- advance the data pointer.
- Essentially, the 'get' method has the functionality of both 'increment'
- and 'dereference'. It's very good for the cases where data extraction
- implicitly moves data pointer, like for stream operation.
+ Essentially, the 'get' method has the functionality of both 'increment'
+ and 'dereference'. It's very good for the cases where data extraction
+ implicitly moves data pointer, like for stream operation.
*/
template<class Derived, class ValueType>
class eof_iterator : public iterator_facade<Derived, const ValueType,
@@ -65,16 +65,16 @@ namespace boost {
{
m_at_eof = true;
}
-
+
private: // iterator core operations
friend class iterator_core_access;
-
- void increment()
+
+ void increment()
{
static_cast<Derived&>(*this).get();
}
-
+
bool equal(const eof_iterator& other) const
{
if (m_at_eof && other.m_at_eof)
@@ -82,14 +82,14 @@ namespace boost {
else
return false;
}
-
+
const ValueType& dereference() const
{
return m_value;
}
bool m_at_eof;
- ValueType m_value;
+ ValueType m_value;
};
}
diff --git a/boost/program_options/option.hpp b/boost/program_options/option.hpp
index fa6be5291e..1fa6a19234 100644
--- a/boost/program_options/option.hpp
+++ b/boost/program_options/option.hpp
@@ -15,7 +15,7 @@ namespace boost { namespace program_options {
/** Option found in input source.
Contains a key and a value. The key, in turn, can be a string (name of
- an option), or an integer (position in input source) -- in case no name
+ an option), or an integer (position in input source) \-- in case no name
is specified. The latter is only possible for command line.
The template parameter specifies the type of char used for storing the
option's value.
diff --git a/boost/program_options/options_description.hpp b/boost/program_options/options_description.hpp
index 32f6990293..fac6acc613 100644
--- a/boost/program_options/options_description.hpp
+++ b/boost/program_options/options_description.hpp
@@ -41,7 +41,7 @@ namespace program_options {
are used only to validate input. Second affect interpretation of the
option, for example default value for it or function that should be
called when the value is finally known. Routines which perform parsing
- never use second kind of properties -- they are side effect free.
+ never use second kind of properties \-- they are side effect free.
@sa options_description
*/
class BOOST_PROGRAM_OPTIONS_DECL option_description {
@@ -71,7 +71,7 @@ namespace program_options {
The 'name' parameter is interpreted by the following rules:
- if there's no "," character in 'name', it specifies long name
- otherwise, the part before "," specifies long name and the part
- after -- short name.
+ after \-- short name.
*/
option_description(const char* name,
const value_semantic* s);
@@ -236,6 +236,11 @@ namespace program_options {
void print(std::ostream& os, unsigned width = 0) const;
private:
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1800))
+ // prevent warning C4512: assignment operator could not be generated
+ options_description& operator=(const options_description&);
+#endif
+
typedef std::map<std::string, int>::const_iterator name2index_iterator;
typedef std::pair<name2index_iterator, name2index_iterator>
approximation_range;
diff --git a/boost/program_options/parsers.hpp b/boost/program_options/parsers.hpp
index 96f38f25af..bc798393f8 100644
--- a/boost/program_options/parsers.hpp
+++ b/boost/program_options/parsers.hpp
@@ -28,20 +28,20 @@ namespace boost { namespace program_options {
class positional_options_description;
- /** Results of parsing an input source.
- The primary use of this class is passing information from parsers
+ /** Results of parsing an input source.
+ The primary use of this class is passing information from parsers
component to value storage component. This class does not makes
- much sense itself.
+ much sense itself.
*/
template<class charT>
class basic_parsed_options {
public:
- explicit basic_parsed_options(const options_description* xdescription, int options_prefix = 0)
+ explicit basic_parsed_options(const options_description* xdescription, int options_prefix = 0)
: description(xdescription), m_options_prefix(options_prefix) {}
/** Options found in the source. */
std::vector< basic_option<charT> > options;
- /** Options description that was used for parsing.
- Parsers should return pointer to the instance of
+ /** Options description that was used for parsing.
+ Parsers should return pointer to the instance of
option_description passed to them, and issues of lifetime are
up to the caller. Can be NULL.
*/
@@ -55,7 +55,7 @@ namespace boost { namespace program_options {
* allow_long_disguise
* allow_dash_for_short
* allow_slash_for_short
- */
+ */
int m_options_prefix;
};
@@ -74,7 +74,7 @@ namespace boost { namespace program_options {
/** Stores UTF8 encoded options that were passed to constructor,
to avoid reverse conversion in some cases. */
- basic_parsed_options<char> utf8_encoded_options;
+ basic_parsed_options<char> utf8_encoded_options;
/** Mainly used for the diagnostic messages in exceptions.
* The canonical option prefix for the parser which generated these results,
@@ -84,7 +84,7 @@ namespace boost { namespace program_options {
* allow_long_disguise
* allow_dash_for_short
* allow_slash_for_short
- */
+ */
int m_options_prefix;
};
@@ -101,14 +101,14 @@ namespace boost { namespace program_options {
The class allows one to specify all the information needed for parsing
and to parse the command line. It is primarily needed to
- emulate named function parameters -- a regular function with 5
+ emulate named function parameters \-- a regular function with 5
parameters will be hard to use and creating overloads with a smaller
- nuber of parameters will be confusing.
+ number of parameters will be confusing.
- For the most common case, the function parse_command_line is a better
- alternative.
+ For the most common case, the function parse_command_line is a better
+ alternative.
- There are two typedefs -- command_line_parser and wcommand_line_parser,
+ There are two typedefs \-- command_line_parser and wcommand_line_parser,
for charT == char and charT == wchar_t cases.
*/
template<class charT>
@@ -146,10 +146,10 @@ namespace boost { namespace program_options {
instance of basic_option<charT> will be added to result,
with 'unrecognized' field set to 'true'. It's possible to
collect all unrecognized options with the 'collect_unrecognized'
- funciton.
+ funciton.
*/
basic_command_line_parser& allow_unregistered();
-
+
using detail::cmdline::style_parser;
basic_command_line_parser& extra_style_parser(style_parser s);
@@ -162,19 +162,19 @@ namespace boost { namespace program_options {
typedef basic_command_line_parser<wchar_t> wcommand_line_parser;
/** Creates instance of 'command_line_parser', passes parameters to it,
- and returns the result of calling the 'run' method.
+ and returns the result of calling the 'run' method.
*/
template<class charT>
basic_parsed_options<charT>
parse_command_line(int argc, const charT* const argv[],
const options_description&,
int style = 0,
- function1<std::pair<std::string, std::string>,
+ function1<std::pair<std::string, std::string>,
const std::string&> ext
= ext_parser());
- /** Parse a config file.
-
+ /** Parse a config file.
+
Read from given stream.
*/
template<class charT>
@@ -185,10 +185,10 @@ namespace boost { namespace program_options {
parse_config_file(std::basic_istream<charT>&, const options_description&,
bool allow_unregistered = false);
- /** Parse a config file.
-
+ /** Parse a config file.
+
Read from file with the given name. The character type is
- passed to the file stream.
+ passed to the file stream.
*/
template<class charT>
#if ! BOOST_WORKAROUND(__ICL, BOOST_TESTED_AT(700))
@@ -200,7 +200,7 @@ namespace boost { namespace program_options {
/** Controls if the 'collect_unregistered' function should
include positional options, or not. */
- enum collect_unrecognized_mode
+ enum collect_unrecognized_mode
{ include_positional, exclude_positional };
/** Collects the original tokens for all named options with
@@ -210,34 +210,34 @@ namespace boost { namespace program_options {
options.
*/
template<class charT>
- std::vector< std::basic_string<charT> >
+ std::vector< std::basic_string<charT> >
collect_unrecognized(const std::vector< basic_option<charT> >& options,
enum collect_unrecognized_mode mode);
- /** Parse environment.
+ /** Parse environment.
For each environment variable, the 'name_mapper' function is called to
- obtain the option name. If it returns empty string, the variable is
- ignored.
+ obtain the option name. If it returns empty string, the variable is
+ ignored.
- This is done since naming of environment variables is typically
- different from the naming of command line options.
+ This is done since naming of environment variables is typically
+ different from the naming of command line options.
*/
BOOST_PROGRAM_OPTIONS_DECL parsed_options
- parse_environment(const options_description&,
+ parse_environment(const options_description&,
const function1<std::string, std::string>& name_mapper);
/** Parse environment.
Takes all environment variables which start with 'prefix'. The option
- name is obtained from variable name by removing the prefix and
+ name is obtained from variable name by removing the prefix and
converting the remaining string into lower case.
*/
BOOST_PROGRAM_OPTIONS_DECL parsed_options
parse_environment(const options_description&, const std::string& prefix);
/** @overload
- This function exists to resolve ambiguity between the two above
+ This function exists to resolve ambiguity between the two above
functions when second argument is of 'char*' type. There's implicit
conversion to both function1 and string.
*/
@@ -252,13 +252,13 @@ namespace boost { namespace program_options {
and escape characters '\'
*/
BOOST_PROGRAM_OPTIONS_DECL std::vector<std::string>
- split_unix(const std::string& cmdline, const std::string& seperator = " \t",
+ split_unix(const std::string& cmdline, const std::string& seperator = " \t",
const std::string& quote = "'\"", const std::string& escape = "\\");
-
+
#ifndef BOOST_NO_STD_WSTRING
/** @overload */
BOOST_PROGRAM_OPTIONS_DECL std::vector<std::wstring>
- split_unix(const std::wstring& cmdline, const std::wstring& seperator = L" \t",
+ split_unix(const std::wstring& cmdline, const std::wstring& seperator = L" \t",
const std::wstring& quote = L"'\"", const std::wstring& escape = L"\\");
#endif
@@ -278,7 +278,7 @@ namespace boost { namespace program_options {
split_winmain(const std::wstring& cmdline);
#endif
#endif
-
+
}}
diff --git a/boost/program_options/value_semantic.hpp b/boost/program_options/value_semantic.hpp
index 081e997bb3..be3f10801e 100644
--- a/boost/program_options/value_semantic.hpp
+++ b/boost/program_options/value_semantic.hpp
@@ -13,10 +13,10 @@
#include <boost/function/function1.hpp>
#include <boost/lexical_cast.hpp>
-
#include <string>
#include <vector>
#include <typeinfo>
+#include <limits>
namespace boost { namespace program_options {
@@ -38,6 +38,11 @@ namespace boost { namespace program_options {
should be present on the command line. */
virtual unsigned max_tokens() const = 0;
+ /** Returns true if the option should only take adjacent token,
+ not one from further command-line arguments.
+ */
+ virtual bool adjacent_tokens_only() const = 0;
+
/** Returns true if values from different sources should be composed.
Otherwise, value from the first source is used and values from
other sources are discarded.
@@ -48,7 +53,7 @@ namespace boost { namespace program_options {
*/
virtual bool is_required() const = 0;
-
+
/** Parses a group of tokens that specify a value of option.
Stores the result in 'value_store', using whatever representation
is desired. May be be called several times if value of the same
@@ -134,6 +139,7 @@ namespace boost { namespace program_options {
unsigned min_tokens() const;
unsigned max_tokens() const;
+ bool adjacent_tokens_only() const { return false; }
bool is_composing() const { return false; }
@@ -156,6 +162,7 @@ namespace boost { namespace program_options {
bool m_zero_tokens;
};
+#ifndef BOOST_NO_RTTI
/** Base class for all option that have a fixed type, and are
willing to announce this type to the outside world.
Any 'value_semantics' for which you want to find out the
@@ -172,20 +179,23 @@ namespace boost { namespace program_options {
// class is silly, but just in case.
virtual ~typed_value_base() {}
};
+#endif
/** Class which handles value of a specific type. */
template<class T, class charT = char>
- class typed_value : public value_semantic_codecvt_helper<charT>,
- public typed_value_base
+ class typed_value : public value_semantic_codecvt_helper<charT>
+#ifndef BOOST_NO_RTTI
+ , public typed_value_base
+#endif
{
public:
/** Ctor. The 'store_to' parameter tells where to store
the value when it's known. The parameter can be NULL. */
typed_value(T* store_to)
: m_store_to(store_to), m_composing(false),
- m_multitoken(false), m_zero_tokens(false),
- m_required(false)
+ m_implicit(false), m_multitoken(false),
+ m_zero_tokens(false), m_required(false)
{}
/** Specifies default value, which will be used
@@ -313,7 +323,7 @@ namespace boost { namespace program_options {
unsigned max_tokens() const {
if (m_multitoken) {
- return 32000;
+ return std::numeric_limits<unsigned>::max BOOST_PREVENT_MACRO_SUBSTITUTION();
} else if (m_zero_tokens) {
return 0;
} else {
@@ -321,6 +331,8 @@ namespace boost { namespace program_options {
}
}
+ bool adjacent_tokens_only() const { return !m_implicit_value.empty(); }
+
bool is_required() const { return m_required; }
/** Creates an instance of the 'validator' class and calls
@@ -350,10 +362,12 @@ namespace boost { namespace program_options {
public: // typed_value_base overrides
+#ifndef BOOST_NO_RTTI
const std::type_info& value_type() const
{
return typeid(T);
}
+#endif
private:
diff --git a/boost/program_options/variables_map.hpp b/boost/program_options/variables_map.hpp
index 09badbf795..362dedf283 100644
--- a/boost/program_options/variables_map.hpp
+++ b/boost/program_options/variables_map.hpp
@@ -31,35 +31,35 @@ namespace boost { namespace program_options {
// forward declaration
- /** Stores in 'm' all options that are defined in 'options'.
+ /** Stores in 'm' all options that are defined in 'options'.
If 'm' already has a non-defaulted value of an option, that value
- is not changed, even if 'options' specify some value.
+ is not changed, even if 'options' specify some value.
*/
- BOOST_PROGRAM_OPTIONS_DECL
+ BOOST_PROGRAM_OPTIONS_DECL
void store(const basic_parsed_options<char>& options, variables_map& m,
bool utf8 = false);
- /** Stores in 'm' all options that are defined in 'options'.
+ /** Stores in 'm' all options that are defined in 'options'.
If 'm' already has a non-defaulted value of an option, that value
- is not changed, even if 'options' specify some value.
+ is not changed, even if 'options' specify some value.
This is wide character variant.
*/
- BOOST_PROGRAM_OPTIONS_DECL
- void store(const basic_parsed_options<wchar_t>& options,
+ BOOST_PROGRAM_OPTIONS_DECL
+ void store(const basic_parsed_options<wchar_t>& options,
variables_map& m);
/** Runs all 'notify' function for options in 'm'. */
BOOST_PROGRAM_OPTIONS_DECL void notify(variables_map& m);
- /** Class holding value of option. Contains details about how the
+ /** Class holding value of option. Contains details about how the
value is set and allows to conveniently obtain the value.
*/
class BOOST_PROGRAM_OPTIONS_DECL variable_value {
public:
variable_value() : m_defaulted(false) {}
- variable_value(const boost::any& xv, bool xdefaulted)
- : v(xv), m_defaulted(xdefaulted)
+ variable_value(const boost::any& xv, bool xdefaulted)
+ : v(xv), m_defaulted(xdefaulted)
{}
/** If stored value if of type T, returns that value. Otherwise,
@@ -95,7 +95,7 @@ namespace boost { namespace program_options {
shared_ptr<const value_semantic> m_value_semantic;
friend BOOST_PROGRAM_OPTIONS_DECL
- void store(const basic_parsed_options<char>& options,
+ void store(const basic_parsed_options<char>& options,
variables_map& m, bool);
friend class BOOST_PROGRAM_OPTIONS_DECL variables_map;
@@ -118,11 +118,11 @@ namespace boost { namespace program_options {
- otherwise, returns empty value
- if there's defaulted value
- - if there's next varaible map, which has a non-defauled
+ - if there's next variable map, which has a non-defaulted
value, return that
- otherwise, return value from *this
- - if there's a non-defauled value, returns it.
+ - if there's a non-defaulted value, returns it.
*/
const variable_value& operator[](const std::string& name) const;
@@ -138,8 +138,8 @@ namespace boost { namespace program_options {
const abstract_variables_map* m_next;
};
- /** Concrete variables map which store variables in real map.
-
+ /** Concrete variables map which store variables in real map.
+
This class is derived from std::map<std::string, variable_value>,
so you can use all map operators to examine its content.
*/
@@ -155,8 +155,8 @@ namespace boost { namespace program_options {
{ return abstract_variables_map::operator[](name); }
// Override to clear some extra fields.
- void clear();
-
+ void clear();
+
void notify();
private:
@@ -164,15 +164,15 @@ namespace boost { namespace program_options {
which does 'find' in *this. */
const variable_value& get(const std::string& name) const;
- /** Names of option with 'final' values -- which should not
+ /** Names of option with 'final' values \-- which should not
be changed by subsequence assignments. */
std::set<std::string> m_final;
friend BOOST_PROGRAM_OPTIONS_DECL
- void store(const basic_parsed_options<char>& options,
+ void store(const basic_parsed_options<char>& options,
variables_map& xm,
bool utf8);
-
+
/** Names of required options, filled by parser which has
access to options_description.
The map values are the "canonical" names for each corresponding option.
diff --git a/boost/property_tree/detail/json_parser/narrow_encoding.hpp b/boost/property_tree/detail/json_parser/narrow_encoding.hpp
new file mode 100644
index 0000000000..13218743d1
--- /dev/null
+++ b/boost/property_tree/detail/json_parser/narrow_encoding.hpp
@@ -0,0 +1,159 @@
+#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_NARROW_ENCODING_HPP
+#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_NARROW_ENCODING_HPP
+
+#include <boost/range/iterator_range_core.hpp>
+
+#include <cassert>
+#include <utility>
+
+namespace boost { namespace property_tree {
+ namespace json_parser { namespace detail
+{
+
+ struct external_ascii_superset_encoding
+ {
+ typedef char external_char;
+
+ bool is_nl(char c) const { return c == '\n'; }
+ bool is_ws(char c) const {
+ return c == ' ' || c == '\t' || c == '\n' || c == '\r';
+ }
+
+ bool is_minus(char c) const { return c == '-'; }
+ bool is_plusminus(char c) const { return c == '+' || c == '-'; }
+ bool is_dot(char c) const { return c == '.'; }
+ bool is_eE(char c) const { return c == 'e' || c == 'E'; }
+ bool is_0(char c) const { return c == '0'; }
+ bool is_digit(char c) const { return c >= '0' && c <= '9'; }
+ bool is_digit0(char c) const { return c >= '1' && c <= '9'; }
+
+ bool is_quote(char c) const { return c == '"'; }
+ bool is_backslash(char c) const { return c == '\\'; }
+ bool is_slash(char c) const { return c == '/'; }
+
+ bool is_comma(char c) const { return c == ','; }
+ bool is_open_bracket(char c) const { return c == '['; }
+ bool is_close_bracket(char c) const { return c == ']'; }
+ bool is_colon(char c) const { return c == ':'; }
+ bool is_open_brace(char c) const { return c == '{'; }
+ bool is_close_brace(char c) const { return c == '}'; }
+
+ bool is_a(char c) const { return c == 'a'; }
+ bool is_b(char c) const { return c == 'b'; }
+ bool is_e(char c) const { return c == 'e'; }
+ bool is_f(char c) const { return c == 'f'; }
+ bool is_l(char c) const { return c == 'l'; }
+ bool is_n(char c) const { return c == 'n'; }
+ bool is_r(char c) const { return c == 'r'; }
+ bool is_s(char c) const { return c == 's'; }
+ bool is_t(char c) const { return c == 't'; }
+ bool is_u(char c) const { return c == 'u'; }
+
+ int decode_hexdigit(char c) {
+ if (c >= '0' && c <= '9') return c - '0';
+ if (c >= 'A' && c <= 'F') return c - 'A' + 10;
+ if (c >= 'a' && c <= 'f') return c - 'a' + 10;
+ return -1;
+ }
+ };
+
+ struct utf8_utf8_encoding : external_ascii_superset_encoding
+ {
+ typedef char internal_char;
+
+ template <typename Iterator>
+ boost::iterator_range<Iterator>
+ to_internal(Iterator first, Iterator last) const {
+ return boost::make_iterator_range(first, last);
+ }
+
+ char to_internal_trivial(char c) const {
+ assert(c <= 0x7f);
+ return c;
+ }
+
+ template <typename Iterator, typename Sentinel,
+ typename EncodingErrorFn>
+ void skip_codepoint(Iterator& cur, Sentinel end,
+ EncodingErrorFn error_fn) const {
+ transcode_codepoint(cur, end, DoNothing(), error_fn);
+ }
+
+ template <typename Iterator, typename Sentinel, typename TranscodedFn,
+ typename EncodingErrorFn>
+ void transcode_codepoint(Iterator& cur, Sentinel end,
+ TranscodedFn transcoded_fn, EncodingErrorFn error_fn) const {
+ unsigned char c = *cur;
+ ++cur;
+ if (c <= 0x7f) {
+ // Solo byte, filter out disallowed codepoints.
+ if (c < 0x20) {
+ error_fn();
+ }
+ transcoded_fn(c);
+ return;
+ }
+ int trailing = trail_table(c);
+ if (trailing == -1) {
+ // Standalone trailing byte or overly long sequence.
+ error_fn();
+ }
+ transcoded_fn(c);
+ for (int i = 0; i < trailing; ++i) {
+ if (cur == end || !is_trail(*cur)) {
+ error_fn();
+ }
+ transcoded_fn(*cur);
+ ++cur;
+ }
+ }
+
+ template <typename TranscodedFn>
+ void feed_codepoint(unsigned codepoint,
+ TranscodedFn transcoded_fn) const {
+ if (codepoint <= 0x7f) {
+ transcoded_fn(static_cast<char>(codepoint));
+ } else if (codepoint <= 0x7ff) {
+ transcoded_fn(static_cast<char>(0xc0 | (codepoint >> 6)));
+ transcoded_fn(trail(codepoint));
+ } else if (codepoint <= 0xffff) {
+ transcoded_fn(static_cast<char>(0xe0 | (codepoint >> 12)));
+ transcoded_fn(trail(codepoint >> 6));
+ transcoded_fn(trail(codepoint));
+ } else if (codepoint <= 0x10ffff) {
+ transcoded_fn(static_cast<char>(0xf0 | (codepoint >> 18)));
+ transcoded_fn(trail(codepoint >> 12));
+ transcoded_fn(trail(codepoint >> 6));
+ transcoded_fn(trail(codepoint));
+ }
+ }
+
+ private:
+ struct DoNothing {
+ void operator ()(char) const {}
+ };
+
+ bool is_trail(unsigned char c) const {
+ return (c & 0xc0) == 0x80;
+ }
+
+ int trail_table(unsigned char c) const {
+ static const signed char table[] = {
+ /* not a lead byte */
+ /* 0x10???sss */ -1, -1, -1, -1, -1, -1, -1, -1,
+ /* 0x110??sss */ 1, 1, 1, 1, /* 1 trailing byte */
+ /* 0x1110?sss */ 2, 2, /* 2 trailing bytes */
+ /* 0x11110sss */ 3, /* 3 trailing bytes */
+ /* 0x11111sss */ -1 /* 4 or 5 trailing bytes, disallowed */
+ };
+ return table[(c & 0x7f) >> 3];
+ }
+
+ char trail(unsigned unmasked) const {
+ return static_cast<char>(0x80 | (unmasked & 0x3f));
+ }
+ };
+
+}}}}
+
+#endif
diff --git a/boost/property_tree/detail/json_parser/parser.hpp b/boost/property_tree/detail/json_parser/parser.hpp
new file mode 100644
index 0000000000..c44b99291d
--- /dev/null
+++ b/boost/property_tree/detail/json_parser/parser.hpp
@@ -0,0 +1,524 @@
+#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_PARSER_HPP
+#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_PARSER_HPP
+
+#include <boost/property_tree/detail/json_parser_error.hpp>
+
+#include <boost/bind.hpp>
+#include <boost/format.hpp>
+
+#include <iterator>
+#include <sstream>
+#include <string>
+
+namespace boost { namespace property_tree {
+ namespace json_parser { namespace detail
+{
+
+ template <typename Encoding, typename Iterator, typename Sentinel>
+ class source
+ {
+ public:
+ typedef typename std::iterator_traits<Iterator>::value_type
+ code_unit;
+ typedef bool (Encoding::*encoding_predicate)(code_unit c) const;
+
+ explicit source(Encoding& encoding) : encoding(encoding) {}
+
+ template <typename Range>
+ void set_input(const std::string& filename, const Range& r)
+ {
+ this->filename = filename;
+ cur = r.begin();
+ end = r.end();
+ line = 1;
+ offset = 0;
+ }
+
+ bool done() const { return cur == end; }
+
+ void parse_error(const char* msg) {
+ BOOST_PROPERTY_TREE_THROW(
+ json_parser_error(msg, filename, line));
+ }
+
+ void next() {
+ if (encoding.is_nl(*cur)) {
+ ++line;
+ offset = 0;
+ } else {
+ ++offset;
+ }
+ ++cur;
+ }
+
+ template <typename Action>
+ bool have(encoding_predicate p, Action& a) {
+ bool found = cur != end && (encoding.*p)(*cur);
+ if (found) {
+ a(*cur);
+ next();
+ }
+ return found;
+ }
+
+ bool have(encoding_predicate p) {
+ DoNothing n;
+ return have(p, n);
+ }
+
+ template <typename Action>
+ void expect(encoding_predicate p, const char* msg, Action& a) {
+ if (!have(p, a)) {
+ parse_error(msg);
+ }
+ }
+
+ void expect(encoding_predicate p, const char* msg) {
+ DoNothing n;
+ expect(p, msg, n);
+ }
+
+ code_unit need_cur(const char* msg) {
+ if (cur == end) {
+ parse_error(msg);
+ }
+ return *cur;
+ }
+
+ Iterator& raw_cur() { return cur; }
+ Sentinel raw_end() { return end; }
+
+ private:
+ struct DoNothing {
+ void operator ()(code_unit) const {}
+ };
+
+ Encoding& encoding;
+ Iterator cur;
+ Sentinel end;
+ std::string filename;
+ int line;
+ int offset;
+ };
+
+ template <typename Callbacks, typename Encoding, typename Iterator,
+ typename = typename std::iterator_traits<Iterator>
+ ::iterator_category>
+ class number_callback_adapter
+ {
+ public:
+ number_callback_adapter(Callbacks& callbacks, Encoding& encoding,
+ Iterator& cur)
+ : callbacks(callbacks), encoding(encoding), first(cur), cur(cur)
+ {}
+
+ void operator ()(typename Encoding::external_char) {}
+
+ void finish() const {
+ callbacks.on_number(encoding.to_internal(first, cur));
+ }
+
+ private:
+ number_callback_adapter(const number_callback_adapter&);
+
+ Callbacks& callbacks;
+ Encoding& encoding;
+ Iterator first;
+ Iterator& cur;
+ };
+
+ template <typename Callbacks, typename Encoding, typename Iterator>
+ class number_callback_adapter<Callbacks, Encoding, Iterator,
+ std::input_iterator_tag>
+ {
+ public:
+ number_callback_adapter(Callbacks& callbacks, Encoding& encoding,
+ Iterator&)
+ : callbacks(callbacks), encoding(encoding), first(true)
+ {}
+
+ void operator ()(typename Encoding::external_char c) {
+ if (first) {
+ callbacks.on_begin_number();
+ first = false;
+ }
+ callbacks.on_digit(encoding.to_internal_trivial(c));
+ }
+
+ void finish() const {
+ callbacks.on_end_number();
+ }
+ private:
+ number_callback_adapter(const number_callback_adapter&);
+
+ Callbacks& callbacks;
+ Encoding& encoding;
+ bool first;
+ };
+
+ template <typename Callbacks, typename Encoding, typename Iterator,
+ typename = typename std::iterator_traits<Iterator>
+ ::iterator_category>
+ class string_callback_adapter
+ {
+ public:
+ string_callback_adapter(Callbacks& callbacks, Encoding& encoding,
+ Iterator& cur)
+ : callbacks(callbacks), encoding(encoding), cur(cur),
+ run_begin(cur)
+ {}
+
+ void start_run() {
+ run_begin = cur;
+ }
+
+ void finish_run() {
+ callbacks.on_code_units(encoding.to_internal(run_begin, cur));
+ }
+
+ template <typename Sentinel, typename EncodingErrorFn>
+ void process_codepoint(Sentinel end, EncodingErrorFn error_fn) {
+ encoding.skip_codepoint(cur, end, error_fn);
+ }
+
+ private:
+ string_callback_adapter(const string_callback_adapter&);
+
+ Callbacks& callbacks;
+ Encoding& encoding;
+ Iterator& cur;
+ Iterator run_begin;
+ };
+
+ template <typename Callbacks, typename Encoding, typename Iterator>
+ class string_callback_adapter<Callbacks, Encoding, Iterator,
+ std::input_iterator_tag>
+ {
+ public:
+ string_callback_adapter(Callbacks& callbacks, Encoding& encoding,
+ Iterator& cur)
+ : callbacks(callbacks), encoding(encoding), cur(cur)
+ {}
+
+ void start_run() {}
+
+ void finish_run() {}
+
+ template <typename Sentinel, typename EncodingErrorFn>
+ void process_codepoint(Sentinel end, EncodingErrorFn error_fn) {
+ encoding.transcode_codepoint(cur, end,
+ boost::bind(&Callbacks::on_code_unit,
+ boost::ref(callbacks), _1),
+ error_fn);
+ }
+
+ private:
+ string_callback_adapter(const string_callback_adapter&);
+
+ Callbacks& callbacks;
+ Encoding& encoding;
+ Iterator& cur;
+ };
+
+ template <typename Callbacks, typename Encoding, typename Iterator,
+ typename Sentinel>
+ class parser
+ {
+ typedef detail::number_callback_adapter<Callbacks, Encoding, Iterator>
+ number_adapter;
+ typedef detail::string_callback_adapter<Callbacks, Encoding, Iterator>
+ string_adapter;
+ typedef detail::source<Encoding, Iterator, Sentinel> source;
+ typedef typename source::code_unit code_unit;
+
+ public:
+ parser(Callbacks& callbacks, Encoding& encoding)
+ : callbacks(callbacks), encoding(encoding), src(encoding)
+ {}
+
+ template <typename Range>
+ void set_input(const std::string& filename, const Range& r) {
+ src.set_input(filename, r);
+ }
+
+ void finish() {
+ skip_ws();
+ if (!src.done()) {
+ parse_error("garbage after data");
+ }
+ }
+
+ void parse_value() {
+ if (parse_object()) return;
+ if (parse_array()) return;
+ if (parse_string()) return;
+ if (parse_boolean()) return;
+ if (parse_null()) return;
+ if (parse_number()) return;
+ parse_error("expected value");
+ }
+
+ bool parse_null() {
+ skip_ws();
+ if (!have(&Encoding::is_n)) {
+ return false;
+ }
+ expect(&Encoding::is_u, "expected 'null'");
+ expect(&Encoding::is_l, "expected 'null'");
+ expect(&Encoding::is_l, "expected 'null'");
+ callbacks.on_null();
+ return true;
+ }
+
+ bool parse_boolean() {
+ skip_ws();
+ if (have(&Encoding::is_t)) {
+ expect(&Encoding::is_r, "expected 'true'");
+ expect(&Encoding::is_u, "expected 'true'");
+ expect(&Encoding::is_e, "expected 'true'");
+ callbacks.on_boolean(true);
+ return true;
+ }
+ if (have(&Encoding::is_f)) {
+ expect(&Encoding::is_a, "expected 'false'");
+ expect(&Encoding::is_l, "expected 'false'");
+ expect(&Encoding::is_s, "expected 'false'");
+ expect(&Encoding::is_e, "expected 'false'");
+ callbacks.on_boolean(false);
+ return true;
+ }
+ return false;
+ }
+
+ bool parse_number() {
+ skip_ws();
+
+ number_adapter adapter(callbacks, encoding, src.raw_cur());
+ bool started = false;
+ if (have(&Encoding::is_minus, adapter)) {
+ started = true;
+ }
+ if (!have(&Encoding::is_0, adapter) && !parse_int_part(adapter)) {
+ if (started) {
+ parse_error("expected digits after -");
+ }
+ return false;
+ }
+ parse_frac_part(adapter);
+ parse_exp_part(adapter);
+ adapter.finish();
+ return true;
+ }
+
+ bool parse_string() {
+ skip_ws();
+
+ if (!have(&Encoding::is_quote)) {
+ return false;
+ }
+
+ callbacks.on_begin_string();
+ string_adapter adapter(callbacks, encoding, src.raw_cur());
+ while (!encoding.is_quote(need_cur("unterminated string"))) {
+ if (encoding.is_backslash(*src.raw_cur())) {
+ adapter.finish_run();
+ next();
+ parse_escape();
+ adapter.start_run();
+ } else {
+ adapter.process_codepoint(src.raw_end(),
+ boost::bind(&parser::parse_error,
+ this, "invalid code sequence"));
+ }
+ }
+ adapter.finish_run();
+ callbacks.on_end_string();
+ next();
+ return true;
+ }
+
+ bool parse_array() {
+ skip_ws();
+
+ if (!have(&Encoding::is_open_bracket)) {
+ return false;
+ }
+
+ callbacks.on_begin_array();
+ skip_ws();
+ if (have(&Encoding::is_close_bracket)) {
+ callbacks.on_end_array();
+ return true;
+ }
+ do {
+ parse_value();
+ skip_ws();
+ } while (have(&Encoding::is_comma));
+ expect(&Encoding::is_close_bracket, "expected ']' or ','");
+ callbacks.on_end_array();
+ return true;
+ }
+
+ bool parse_object() {
+ skip_ws();
+
+ if (!have(&Encoding::is_open_brace)) {
+ return false;
+ }
+
+ callbacks.on_begin_object();
+ skip_ws();
+ if (have(&Encoding::is_close_brace)) {
+ callbacks.on_end_object();
+ return true;
+ }
+ do {
+ if (!parse_string()) {
+ parse_error("expected key string");
+ }
+ skip_ws();
+ expect(&Encoding::is_colon, "expected ':'");
+ parse_value();
+ skip_ws();
+ } while (have(&Encoding::is_comma));
+ expect(&Encoding::is_close_brace, "expected '}' or ','");
+ callbacks.on_end_object();
+ return true;
+ }
+
+ private:
+ typedef typename source::encoding_predicate encoding_predicate;
+
+ void parse_error(const char* msg) { src.parse_error(msg); }
+ void next() { src.next(); }
+ template <typename Action>
+ bool have(encoding_predicate p, Action& a) { return src.have(p, a); }
+ bool have(encoding_predicate p) { return src.have(p); }
+ template <typename Action>
+ void expect(encoding_predicate p, const char* msg, Action& a) {
+ src.expect(p, msg, a);
+ }
+ void expect(encoding_predicate p, const char* msg) {
+ src.expect(p, msg);
+ }
+ code_unit need_cur(const char* msg) { return src.need_cur(msg); }
+
+ void skip_ws() {
+ while (have(&Encoding::is_ws)) {
+ }
+ }
+
+ bool parse_int_part(number_adapter& action) {
+ if (!have(&Encoding::is_digit0, action)) {
+ return false;
+ }
+ parse_digits(action);
+ return true;
+ }
+
+ void parse_frac_part(number_adapter& action) {
+ if (!have(&Encoding::is_dot, action)) {
+ return;
+ }
+ expect(&Encoding::is_digit, "need at least one digit after '.'",
+ action);
+ parse_digits(action);
+ }
+
+ void parse_exp_part(number_adapter& action) {
+ if (!have(&Encoding::is_eE, action)) {
+ return;
+ }
+ have(&Encoding::is_plusminus, action);
+ expect(&Encoding::is_digit, "need at least one digit in exponent",
+ action);
+ parse_digits(action);
+ }
+
+ void parse_digits(number_adapter& action) {
+ while (have(&Encoding::is_digit, action)) {
+ }
+ }
+
+ void parse_escape() {
+ if (have(&Encoding::is_quote)) {
+ feed(0x22);
+ } else if (have(&Encoding::is_backslash)) {
+ feed(0x5c);
+ } else if (have(&Encoding::is_slash)) {
+ feed(0x2f);
+ } else if (have(&Encoding::is_b)) {
+ feed(0x08); // backspace
+ } else if (have(&Encoding::is_f)) {
+ feed(0x0c); // formfeed
+ } else if (have(&Encoding::is_n)) {
+ feed(0x0a); // line feed
+ } else if (have(&Encoding::is_r)) {
+ feed(0x0d); // carriage return
+ } else if (have(&Encoding::is_t)) {
+ feed(0x09); // horizontal tab
+ } else if (have(&Encoding::is_u)) {
+ parse_codepoint_ref();
+ } else {
+ parse_error("invalid escape sequence");
+ }
+ }
+
+ unsigned parse_hex_quad() {
+ unsigned codepoint = 0;
+ for (int i = 0; i < 4; ++i) {
+ int value = encoding.decode_hexdigit(
+ need_cur("invalid escape sequence"));
+ if (value < 0) {
+ parse_error("invalid escape sequence");
+ }
+ codepoint *= 16;
+ codepoint += value;
+ next();
+ }
+ return codepoint;
+ }
+
+ static bool is_surrogate_high(unsigned codepoint) {
+ return (codepoint & 0xfc00) == 0xd800;
+ }
+ static bool is_surrogate_low(unsigned codepoint) {
+ return (codepoint & 0xfc00) == 0xdc00;
+ }
+ static unsigned combine_surrogates(unsigned high, unsigned low) {
+ return 0x010000 + (((high & 0x3ff) << 10) | (low & 0x3ff));
+ }
+
+ void parse_codepoint_ref() {
+ unsigned codepoint = parse_hex_quad();
+ if (is_surrogate_low(codepoint)) {
+ parse_error("invalid codepoint, stray low surrogate");
+ }
+ if (is_surrogate_high(codepoint)) {
+ expect(&Encoding::is_backslash,
+ "invalid codepoint, stray high surrogate");
+ expect(&Encoding::is_u,
+ "expected codepoint reference after high surrogate");
+ int low = parse_hex_quad();
+ if (!is_surrogate_low(low)) {
+ parse_error("expected low surrogate after high surrogate");
+ }
+ codepoint = combine_surrogates(codepoint, low);
+ }
+ feed(codepoint);
+ }
+
+ void feed(unsigned codepoint) {
+ encoding.feed_codepoint(codepoint,
+ boost::bind(&Callbacks::on_code_unit,
+ boost::ref(callbacks), _1));
+ }
+
+ Callbacks& callbacks;
+ Encoding& encoding;
+ source src;
+ };
+
+}}}}
+
+#endif
diff --git a/boost/property_tree/detail/json_parser/read.hpp b/boost/property_tree/detail/json_parser/read.hpp
new file mode 100644
index 0000000000..61c0162781
--- /dev/null
+++ b/boost/property_tree/detail/json_parser/read.hpp
@@ -0,0 +1,55 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2015 Sebastian Redl
+//
+// Distributed under the 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 www.boost.org
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_READ_HPP
+#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_READ_HPP
+
+#include <boost/property_tree/detail/json_parser/parser.hpp>
+#include <boost/property_tree/detail/json_parser/narrow_encoding.hpp>
+#include <boost/property_tree/detail/json_parser/wide_encoding.hpp>
+#include <boost/property_tree/detail/json_parser/standard_callbacks.hpp>
+
+#include <boost/range/iterator_range_core.hpp>
+
+#include <istream>
+#include <iterator>
+#include <string>
+
+namespace boost { namespace property_tree {
+ namespace json_parser { namespace detail
+{
+
+ template <typename Ch> struct encoding;
+ template <> struct encoding<char> : utf8_utf8_encoding {};
+ template <> struct encoding<wchar_t> : wide_wide_encoding {};
+
+ template <typename Ptree>
+ void read_json_internal(
+ std::basic_istream<typename Ptree::key_type::value_type> &stream,
+ Ptree &pt, const std::string &filename)
+ {
+ typedef typename Ptree::key_type::value_type char_type;
+ typedef standard_callbacks<Ptree> callbacks_type;
+ typedef detail::encoding<char_type> encoding_type;
+ typedef std::istreambuf_iterator<char_type> iterator;
+ callbacks_type callbacks;
+ encoding_type encoding;
+ detail::parser<callbacks_type, encoding_type, iterator, iterator>
+ parser(callbacks, encoding);
+ parser.set_input(filename,
+ boost::make_iterator_range(iterator(stream), iterator()));
+ parser.parse_value();
+ parser.finish();
+
+ pt.swap(callbacks.output());
+ }
+
+}}}}
+
+#endif
diff --git a/boost/property_tree/detail/json_parser/standard_callbacks.hpp b/boost/property_tree/detail/json_parser/standard_callbacks.hpp
new file mode 100644
index 0000000000..56c378ec9c
--- /dev/null
+++ b/boost/property_tree/detail/json_parser/standard_callbacks.hpp
@@ -0,0 +1,152 @@
+#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_STANDARD_CALLBACKS_HPP
+#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_STANDARD_CALLBACKS_HPP
+
+#include <boost/property_tree/ptree.hpp>
+#include <vector>
+
+namespace boost { namespace property_tree {
+ namespace json_parser { namespace detail
+{
+
+ namespace constants
+ {
+ template <typename Ch> const Ch* null_value();
+ template <> inline const char* null_value() { return "null"; }
+ template <> inline const wchar_t* null_value() { return L"null"; }
+
+ template <typename Ch> const Ch* true_value();
+ template <> inline const char* true_value() { return "true"; }
+ template <> inline const wchar_t* true_value() { return L"true"; }
+
+ template <typename Ch> const Ch* false_value();
+ template <> inline const char* false_value() { return "false"; }
+ template <> inline const wchar_t* false_value() { return L"false"; }
+ }
+
+ template <typename Ptree>
+ class standard_callbacks {
+ public:
+ typedef typename Ptree::data_type string;
+ typedef typename string::value_type char_type;
+
+ void on_null() {
+ new_value() = constants::null_value<char_type>();
+ }
+
+ void on_boolean(bool b) {
+ new_value() = b ? constants::true_value<char_type>()
+ : constants::false_value<char_type>();
+ }
+
+ template <typename Range>
+ void on_number(Range code_units) {
+ new_value().assign(code_units.begin(), code_units.end());
+ }
+ void on_begin_number() {
+ new_value();
+ }
+ void on_digit(char_type d) {
+ current_value() += d;
+ }
+ void on_end_number() {}
+
+ void on_begin_string() {
+ new_value();
+ }
+ template <typename Range>
+ void on_code_units(Range code_units) {
+ current_value().append(code_units.begin(), code_units.end());
+ }
+ void on_code_unit(char_type c) {
+ current_value() += c;
+ }
+ void on_end_string() {}
+
+ void on_begin_array() {
+ new_tree();
+ stack.back().k = array;
+ }
+ void on_end_array() {
+ if (stack.back().k == leaf) stack.pop_back();
+ stack.pop_back();
+ }
+
+ void on_begin_object() {
+ new_tree();
+ stack.back().k = object;
+ }
+ void on_end_object() {
+ if (stack.back().k == leaf) stack.pop_back();
+ stack.pop_back();
+ }
+
+ Ptree& output() { return root; }
+
+ protected:
+ bool is_key() const {
+ return stack.back().k == key;
+ }
+ string& current_value() {
+ layer& l = stack.back();
+ switch (l.k) {
+ case key: return key_buffer;
+ default: return l.t->data();
+ }
+ }
+
+ private:
+ Ptree root;
+ string key_buffer;
+ enum kind { array, object, key, leaf };
+ struct layer { kind k; Ptree* t; };
+ std::vector<layer> stack;
+
+ Ptree& new_tree() {
+ if (stack.empty()) {
+ layer l = {leaf, &root};
+ stack.push_back(l);
+ return root;
+ }
+ layer& l = stack.back();
+ switch (l.k) {
+ case array: {
+ l.t->push_back(std::make_pair(string(), Ptree()));
+ layer nl = {leaf, &l.t->back().second};
+ stack.push_back(nl);
+ return *stack.back().t;
+ }
+ case object:
+ assert(false); // must start with string, i.e. call new_value
+ case key: {
+ l.t->push_back(std::make_pair(key_buffer, Ptree()));
+ l.k = object;
+ layer nl = {leaf, &l.t->back().second};
+ stack.push_back(nl);
+ return *stack.back().t;
+ }
+ case leaf:
+ stack.pop_back();
+ return new_tree();
+ }
+ assert(false);
+ }
+ string& new_value() {
+ if (stack.empty()) return new_tree().data();
+ layer& l = stack.back();
+ switch (l.k) {
+ case leaf:
+ stack.pop_back();
+ return new_value();
+ case object:
+ l.k = key;
+ key_buffer.clear();
+ return key_buffer;
+ default:
+ return new_tree().data();
+ }
+ }
+ };
+
+}}}}
+
+#endif
diff --git a/boost/property_tree/detail/json_parser/wide_encoding.hpp b/boost/property_tree/detail/json_parser/wide_encoding.hpp
new file mode 100644
index 0000000000..0dec1c03b0
--- /dev/null
+++ b/boost/property_tree/detail/json_parser/wide_encoding.hpp
@@ -0,0 +1,171 @@
+#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WIDE_ENCODING_HPP
+#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WIDE_ENCODING_HPP
+
+#include <boost/range/iterator_range_core.hpp>
+
+#include <cassert>
+#include <utility>
+
+namespace boost { namespace property_tree {
+ namespace json_parser { namespace detail
+{
+
+ struct external_wide_encoding
+ {
+ typedef wchar_t external_char;
+
+ bool is_nl(wchar_t c) const { return c == L'\n'; }
+ bool is_ws(wchar_t c) const {
+ return c == L' ' || c == L'\t' || c == L'\n' || c == L'\r';
+ }
+
+ bool is_minus(wchar_t c) const { return c == L'-'; }
+ bool is_plusminus(wchar_t c) const { return c == L'+' || c == L'-'; }
+ bool is_dot(wchar_t c) const { return c == L'.'; }
+ bool is_eE(wchar_t c) const { return c == L'e' || c == L'E'; }
+ bool is_0(wchar_t c) const { return c == L'0'; }
+ bool is_digit(wchar_t c) const { return c >= L'0' && c <= L'9'; }
+ bool is_digit0(wchar_t c) const { return c >= L'1' && c <= L'9'; }
+
+ bool is_quote(wchar_t c) const { return c == L'"'; }
+ bool is_backslash(wchar_t c) const { return c == L'\\'; }
+ bool is_slash(wchar_t c) const { return c == L'/'; }
+
+ bool is_comma(wchar_t c) const { return c == L','; }
+ bool is_open_bracket(wchar_t c) const { return c == L'['; }
+ bool is_close_bracket(wchar_t c) const { return c == L']'; }
+ bool is_colon(wchar_t c) const { return c == L':'; }
+ bool is_open_brace(wchar_t c) const { return c == L'{'; }
+ bool is_close_brace(wchar_t c) const { return c == L'}'; }
+
+ bool is_a(wchar_t c) const { return c == L'a'; }
+ bool is_b(wchar_t c) const { return c == L'b'; }
+ bool is_e(wchar_t c) const { return c == L'e'; }
+ bool is_f(wchar_t c) const { return c == L'f'; }
+ bool is_l(wchar_t c) const { return c == L'l'; }
+ bool is_n(wchar_t c) const { return c == L'n'; }
+ bool is_r(wchar_t c) const { return c == L'r'; }
+ bool is_s(wchar_t c) const { return c == L's'; }
+ bool is_t(wchar_t c) const { return c == L't'; }
+ bool is_u(wchar_t c) const { return c == L'u'; }
+
+ int decode_hexdigit(wchar_t c) {
+ if (c >= L'0' && c <= L'9') return c - L'0';
+ if (c >= L'A' && c <= L'F') return c - L'A' + 10;
+ if (c >= L'a' && c <= L'f') return c - L'a' + 10;
+ return -1;
+ }
+ };
+
+ template <bool B> struct is_utf16 {};
+
+ class wide_wide_encoding : public external_wide_encoding
+ {
+ typedef is_utf16<sizeof(wchar_t) == 2> test_utf16;
+ public:
+ typedef wchar_t internal_char;
+
+ template <typename Iterator>
+ boost::iterator_range<Iterator>
+ to_internal(Iterator first, Iterator last) const {
+ return boost::make_iterator_range(first, last);
+ }
+
+ wchar_t to_internal_trivial(wchar_t c) const {
+ assert(!is_surrogate_high(c) && !is_surrogate_low(c));
+ return c;
+ }
+
+ template <typename Iterator, typename Sentinel,
+ typename EncodingErrorFn>
+ void skip_codepoint(Iterator& cur, Sentinel end,
+ EncodingErrorFn error_fn) const {
+ transcode_codepoint(cur, end, DoNothing(), error_fn);
+ }
+
+ template <typename Iterator, typename Sentinel, typename TranscodedFn,
+ typename EncodingErrorFn>
+ void transcode_codepoint(Iterator& cur, Sentinel end,
+ TranscodedFn transcoded_fn, EncodingErrorFn error_fn) const {
+ return transcode_codepoint(cur, end, transcoded_fn, error_fn,
+ test_utf16());
+ }
+
+ template <typename TranscodedFn>
+ void feed_codepoint(unsigned codepoint,
+ TranscodedFn transcoded_fn) const {
+ feed_codepoint(codepoint, transcoded_fn, test_utf16());
+ }
+
+ private:
+ struct DoNothing {
+ void operator ()(wchar_t) const {}
+ };
+
+ template <typename Iterator, typename Sentinel, typename TranscodedFn,
+ typename EncodingErrorFn>
+ void transcode_codepoint(Iterator& cur, Sentinel end,
+ TranscodedFn transcoded_fn,
+ EncodingErrorFn error_fn,
+ is_utf16<false>) const {
+ wchar_t c = *cur;
+ if (c < 0x20) {
+ error_fn();
+ }
+ transcoded_fn(c);
+ ++cur;
+ }
+ template <typename Iterator, typename Sentinel, typename TranscodedFn,
+ typename EncodingErrorFn>
+ void transcode_codepoint(Iterator& cur, Sentinel end,
+ TranscodedFn transcoded_fn,
+ EncodingErrorFn error_fn,
+ is_utf16<true>) const {
+ wchar_t c = *cur;
+ if (c < 0x20) {
+ error_fn();
+ }
+ if (is_surrogate_low(c)) {
+ error_fn();
+ }
+ transcoded_fn(c);
+ ++cur;
+ if (is_surrogate_high(c)) {
+ c = *cur;
+ if (!is_surrogate_low(c)) {
+ error_fn();
+ }
+ transcoded_fn(c);
+ ++cur;
+ }
+ }
+
+ template <typename TranscodedFn>
+ void feed_codepoint(unsigned codepoint, TranscodedFn transcoded_fn,
+ is_utf16<false>) const {
+ transcoded_fn(static_cast<wchar_t>(codepoint));
+ }
+ template <typename TranscodedFn>
+ void feed_codepoint(unsigned codepoint, TranscodedFn transcoded_fn,
+ is_utf16<true>) const {
+ if (codepoint < 0x10000) {
+ transcoded_fn(static_cast<wchar_t>(codepoint));
+ } else {
+ codepoint -= 0x10000;
+ transcoded_fn(static_cast<wchar_t>((codepoint >> 10) | 0xd800));
+ transcoded_fn(static_cast<wchar_t>(
+ (codepoint & 0x3ff) | 0xdc00));
+ }
+ }
+
+ static bool is_surrogate_high(unsigned codepoint) {
+ return (codepoint & 0xfc00) == 0xd800;
+ }
+ static bool is_surrogate_low(unsigned codepoint) {
+ return (codepoint & 0xfc00) == 0xdc00;
+ }
+ };
+
+}}}}
+
+#endif
diff --git a/boost/property_tree/detail/json_parser_read.hpp b/boost/property_tree/detail/json_parser_read.hpp
deleted file mode 100644
index 798552f6f1..0000000000
--- a/boost/property_tree/detail/json_parser_read.hpp
+++ /dev/null
@@ -1,332 +0,0 @@
-// ----------------------------------------------------------------------------
-// Copyright (C) 2002-2006 Marcin Kalicinski
-//
-// Distributed under the 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 www.boost.org
-// ----------------------------------------------------------------------------
-#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_READ_HPP_INCLUDED
-#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_READ_HPP_INCLUDED
-
-//#define BOOST_SPIRIT_DEBUG
-
-#include <boost/property_tree/ptree.hpp>
-#include <boost/property_tree/detail/ptree_utils.hpp>
-#include <boost/property_tree/detail/json_parser_error.hpp>
-#include <boost/spirit/include/classic.hpp>
-#include <boost/limits.hpp>
-#include <string>
-#include <locale>
-#include <istream>
-#include <vector>
-#include <algorithm>
-
-namespace boost { namespace property_tree { namespace json_parser
-{
-
- ///////////////////////////////////////////////////////////////////////
- // Json parser context
-
- template<class Ptree>
- struct context
- {
- typedef typename Ptree::key_type Str;
- typedef typename Str::value_type Ch;
- typedef typename std::vector<Ch>::iterator It;
-
- Str string;
- Str name;
- Ptree root;
- std::vector<Ptree *> stack;
-
- struct a_object_s
- {
- context &c;
- a_object_s(context &c): c(c) { }
- void operator()(Ch) const
- {
- if (c.stack.empty())
- c.stack.push_back(&c.root);
- else
- {
- Ptree *parent = c.stack.back();
- Ptree *child = &parent->push_back(std::make_pair(c.name, Ptree()))->second;
- c.stack.push_back(child);
- c.name.clear();
- }
- }
- };
-
- struct a_object_e
- {
- context &c;
- a_object_e(context &c): c(c) { }
- void operator()(Ch) const
- {
- BOOST_ASSERT(c.stack.size() >= 1);
- c.stack.pop_back();
- }
- };
-
- struct a_name
- {
- context &c;
- a_name(context &c): c(c) { }
- void operator()(It, It) const
- {
- c.name.swap(c.string);
- c.string.clear();
- }
- };
-
- struct a_string_val
- {
- context &c;
- a_string_val(context &c): c(c) { }
- void operator()(It, It) const
- {
- BOOST_ASSERT(c.stack.size() >= 1);
- c.stack.back()->push_back(std::make_pair(c.name, Ptree(c.string)));
- c.name.clear();
- c.string.clear();
- }
- };
-
- struct a_literal_val
- {
- context &c;
- a_literal_val(context &c): c(c) { }
- void operator()(It b, It e) const
- {
- BOOST_ASSERT(c.stack.size() >= 1);
- c.stack.back()->push_back(std::make_pair(c.name,
- Ptree(Str(b, e))));
- c.name.clear();
- c.string.clear();
- }
- };
-
- struct a_char
- {
- context &c;
- a_char(context &c): c(c) { }
- void operator()(It b, It) const
- {
- c.string += *b;
- }
- };
-
- struct a_escape
- {
- context &c;
- a_escape(context &c): c(c) { }
- void operator()(Ch ch) const
- {
- switch (ch)
- {
- case Ch('\"'): c.string += Ch('\"'); break;
- case Ch('\\'): c.string += Ch('\\'); break;
- case Ch('/'): c.string += Ch('/'); break;
- case Ch('b'): c.string += Ch('\b'); break;
- case Ch('f'): c.string += Ch('\f'); break;
- case Ch('n'): c.string += Ch('\n'); break;
- case Ch('r'): c.string += Ch('\r'); break;
- case Ch('t'): c.string += Ch('\t'); break;
- default: BOOST_ASSERT(0);
- }
- }
- };
-
- struct a_unicode
- {
- context &c;
- a_unicode(context &c): c(c) { }
- void operator()(unsigned long u) const
- {
- u = (std::min)(u, static_cast<unsigned long>((std::numeric_limits<Ch>::max)()));
- c.string += Ch(u);
- }
- };
-
- };
-
- ///////////////////////////////////////////////////////////////////////
- // Json grammar
-
- template<class Ptree>
- struct json_grammar :
- public boost::spirit::classic::grammar<json_grammar<Ptree> >
- {
-
- typedef context<Ptree> Context;
- typedef typename Ptree::key_type Str;
- typedef typename Str::value_type Ch;
-
- mutable Context c;
-
- template<class Scanner>
- struct definition
- {
-
- boost::spirit::classic::rule<Scanner>
- root, object, member, array, item, value, string, number;
- boost::spirit::classic::rule<
- typename boost::spirit::classic::lexeme_scanner<Scanner>::type>
- character, escape;
-
- definition(const json_grammar &self)
- {
-
- using namespace boost::spirit::classic;
- // There's a boost::assertion too, so another explicit using
- // here:
- using boost::spirit::classic::assertion;
-
- // Assertions
- assertion<std::string> expect_root("expected object or array");
- assertion<std::string> expect_eoi("expected end of input");
- assertion<std::string> expect_objclose("expected ',' or '}'");
- assertion<std::string> expect_arrclose("expected ',' or ']'");
- assertion<std::string> expect_name("expected object name");
- assertion<std::string> expect_colon("expected ':'");
- assertion<std::string> expect_value("expected value");
- assertion<std::string> expect_escape("invalid escape sequence");
-
- // JSON grammar rules
- root
- = expect_root(object | array)
- >> expect_eoi(end_p)
- ;
-
- object
- = ch_p('{')[typename Context::a_object_s(self.c)]
- >> (ch_p('}')[typename Context::a_object_e(self.c)]
- | (list_p(member, ch_p(','))
- >> expect_objclose(ch_p('}')[typename Context::a_object_e(self.c)])
- )
- )
- ;
-
- member
- = expect_name(string[typename Context::a_name(self.c)])
- >> expect_colon(ch_p(':'))
- >> expect_value(value)
- ;
-
- array
- = ch_p('[')[typename Context::a_object_s(self.c)]
- >> (ch_p(']')[typename Context::a_object_e(self.c)]
- | (list_p(item, ch_p(','))
- >> expect_arrclose(ch_p(']')[typename Context::a_object_e(self.c)])
- )
- )
- ;
-
- item
- = expect_value(value)
- ;
-
- value
- = string[typename Context::a_string_val(self.c)]
- | (number | str_p("true") | "false" | "null")[typename Context::a_literal_val(self.c)]
- | object
- | array
- ;
-
- number
- = !ch_p("-") >>
- (ch_p("0") | (range_p(Ch('1'), Ch('9')) >> *digit_p)) >>
- !(ch_p(".") >> +digit_p) >>
- !(chset_p(detail::widen<Str>("eE").c_str()) >>
- !chset_p(detail::widen<Str>("-+").c_str()) >>
- +digit_p)
- ;
-
- string
- = +(lexeme_d[confix_p('\"', *character, '\"')])
- ;
-
- character
- = (anychar_p - "\\" - "\"")
- [typename Context::a_char(self.c)]
- | ch_p("\\") >> expect_escape(escape)
- ;
-
- escape
- = chset_p(detail::widen<Str>("\"\\/bfnrt").c_str())
- [typename Context::a_escape(self.c)]
- | 'u' >> uint_parser<unsigned long, 16, 4, 4>()
- [typename Context::a_unicode(self.c)]
- ;
-
- // Debug
- BOOST_SPIRIT_DEBUG_RULE(root);
- BOOST_SPIRIT_DEBUG_RULE(object);
- BOOST_SPIRIT_DEBUG_RULE(member);
- BOOST_SPIRIT_DEBUG_RULE(array);
- BOOST_SPIRIT_DEBUG_RULE(item);
- BOOST_SPIRIT_DEBUG_RULE(value);
- BOOST_SPIRIT_DEBUG_RULE(string);
- BOOST_SPIRIT_DEBUG_RULE(number);
- BOOST_SPIRIT_DEBUG_RULE(escape);
- BOOST_SPIRIT_DEBUG_RULE(character);
-
- }
-
- const boost::spirit::classic::rule<Scanner> &start() const
- {
- return root;
- }
-
- };
-
- };
-
- template<class It, class Ch>
- unsigned long count_lines(It begin, It end)
- {
- return static_cast<unsigned long>(std::count(begin, end, Ch('\n')) + 1);
- }
-
- template<class Ptree>
- void read_json_internal(std::basic_istream<typename Ptree::key_type::value_type> &stream,
- Ptree &pt,
- const std::string &filename)
- {
-
- using namespace boost::spirit::classic;
- typedef typename Ptree::key_type::value_type Ch;
- typedef typename std::vector<Ch>::iterator It;
-
- // Load data into vector
- std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()),
- std::istreambuf_iterator<Ch>());
- if (!stream.good())
- BOOST_PROPERTY_TREE_THROW(json_parser_error("read error", filename, 0));
-
- // Prepare grammar
- json_grammar<Ptree> g;
-
- // Parse
- try
- {
- parse_info<It> pi = parse(v.begin(), v.end(), g,
- space_p | comment_p("//") | comment_p("/*", "*/"));
- if (!pi.hit || !pi.full)
- BOOST_PROPERTY_TREE_THROW((parser_error<std::string, It>(v.begin(), "syntax error")));
- }
- catch (parser_error<std::string, It> &e)
- {
- BOOST_PROPERTY_TREE_THROW(json_parser_error(e.descriptor, filename, count_lines<It, Ch>(v.begin(), e.where)));
- }
-
- // Swap grammar context root and pt
- pt.swap(g.c.root);
-
- }
-
-} } }
-
-#endif
diff --git a/boost/property_tree/detail/rapidxml.hpp b/boost/property_tree/detail/rapidxml.hpp
index d3615c1193..9e3d76af9d 100644
--- a/boost/property_tree/detail/rapidxml.hpp
+++ b/boost/property_tree/detail/rapidxml.hpp
@@ -65,7 +65,7 @@ namespace boost { namespace property_tree { namespace detail {namespace rapidxml
//! Gets pointer to character data where error happened.
//! Ch should be the same as char type of xml_document that produced the error.
- //! \return Pointer to location within the parsed string where error occured.
+ //! \return Pointer to location within the parsed string where error occurred.
template<class Ch>
Ch *where() const
{
diff --git a/boost/property_tree/json_parser.hpp b/boost/property_tree/json_parser.hpp
index d3bc32edb1..d8a3e1025f 100644
--- a/boost/property_tree/json_parser.hpp
+++ b/boost/property_tree/json_parser.hpp
@@ -1,5 +1,6 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
+// Copyright (C) 2015 Sebastian Redl
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,9 +12,9 @@
#define BOOST_PROPERTY_TREE_JSON_PARSER_HPP_INCLUDED
#include <boost/property_tree/ptree.hpp>
-#include <boost/property_tree/detail/json_parser_read.hpp>
-#include <boost/property_tree/detail/json_parser_write.hpp>
#include <boost/property_tree/detail/json_parser_error.hpp>
+#include <boost/property_tree/detail/json_parser/read.hpp>
+#include <boost/property_tree/detail/json_parser_write.hpp>
#include <fstream>
#include <string>
@@ -42,7 +43,7 @@ namespace boost { namespace property_tree { namespace json_parser
> &stream,
Ptree &pt)
{
- read_json_internal(stream, pt, std::string());
+ detail::read_json_internal(stream, pt, std::string());
}
/**
@@ -71,7 +72,7 @@ namespace boost { namespace property_tree { namespace json_parser
BOOST_PROPERTY_TREE_THROW(json_parser_error(
"cannot open file", filename, 0));
stream.imbue(loc);
- read_json_internal(stream, pt, filename);
+ detail::read_json_internal(stream, pt, filename);
}
/**
diff --git a/boost/property_tree/ptree_serialization.hpp b/boost/property_tree/ptree_serialization.hpp
index 4dc916c0d0..a8181ca3b7 100644
--- a/boost/property_tree/ptree_serialization.hpp
+++ b/boost/property_tree/ptree_serialization.hpp
@@ -14,7 +14,7 @@
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/collections_save_imp.hpp>
-#include <boost/serialization/collections_load_imp.hpp>
+#include <boost/serialization/detail/stack_constructor.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/utility.hpp>
@@ -48,6 +48,41 @@ namespace boost { namespace property_tree
ar << make_nvp("data", t.data());
}
+ namespace detail
+ {
+ template <class Archive, class K, class D, class C>
+ inline void load_children(Archive &ar,
+ basic_ptree<K, D, C> &t)
+ {
+ namespace bsl = boost::serialization;
+ namespace bsa = boost::archive;
+
+ typedef basic_ptree<K, D, C> tree;
+ typedef typename tree::value_type value_type;
+
+ bsl::collection_size_type count;
+ ar >> BOOST_SERIALIZATION_NVP(count);
+ bsl::item_version_type item_version(0);
+ const bsa::library_version_type library_version(
+ ar.get_library_version()
+ );
+ if(bsa::library_version_type(3) < library_version){
+ ar >> BOOST_SERIALIZATION_NVP(item_version);
+ }
+ // Can't use the serialization helper, it expects resize() to exist
+ // for default-constructible elements.
+ // This is a copy/paste of the fallback version.
+ t.clear();
+ while(count-- > 0){
+ bsl::detail::stack_construct<Archive, value_type>
+ u(ar, item_version);
+ ar >> bsl::make_nvp("item", u.reference());
+ t.push_back(u.reference());
+ ar.reset_object_address(& t.back() , & u.reference());
+ }
+ }
+ }
+
/**
* De-serialize the property tree to the given archive.
* @note In addition to de-serializing from regular archives, this supports
@@ -66,18 +101,10 @@ namespace boost { namespace property_tree
basic_ptree<K, D, C> &t,
const unsigned int file_version)
{
- using namespace boost::serialization;
- // Load children
- stl::load_collection<Archive,
- basic_ptree<K, D, C>,
- stl::archive_input_seq<Archive,
- basic_ptree<K, D, C> >,
- stl::no_reserve_imp<
- basic_ptree<K, D, C> >
- >(ar, t);
+ namespace bsl = boost::serialization;
- // Load data (must be after load_collection, as it calls clear())
- ar >> make_nvp("data", t.data());
+ detail::load_children(ar, t);
+ ar >> bsl::make_nvp("data", t.data());
}
/**
diff --git a/boost/python.hpp b/boost/python.hpp
index ae49abaf10..11067c1702 100644
--- a/boost/python.hpp
+++ b/boost/python.hpp
@@ -53,6 +53,7 @@
# include <boost/python/pointee.hpp>
# include <boost/python/pure_virtual.hpp>
# include <boost/python/ptr.hpp>
+# include <boost/python/raw_function.hpp>
# include <boost/python/reference_existing_object.hpp>
# include <boost/python/register_ptr_to_python.hpp>
# include <boost/python/return_arg.hpp>
@@ -61,7 +62,9 @@
# include <boost/python/return_value_policy.hpp>
# include <boost/python/scope.hpp>
# include <boost/python/self.hpp>
+# include <boost/python/slice.hpp>
# include <boost/python/slice_nil.hpp>
+# include <boost/python/stl_iterator.hpp>
# include <boost/python/str.hpp>
# include <boost/python/to_python_converter.hpp>
# include <boost/python/to_python_indirect.hpp>
diff --git a/boost/python/args.hpp b/boost/python/args.hpp
index 8f8791d76f..55d1283b5a 100644
--- a/boost/python/args.hpp
+++ b/boost/python/args.hpp
@@ -102,7 +102,6 @@ namespace detail
return this->operator,(python::arg(name));
}
-# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<typename T>
struct is_keywords
{
@@ -126,31 +125,6 @@ namespace detail
typedef mpl::bool_<value> type;
BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
};
-# else
- typedef char (&yes_keywords_t)[1];
- typedef char (&no_keywords_t)[2];
-
- no_keywords_t is_keywords_test(...);
-
- template<std::size_t nkeywords>
- yes_keywords_t is_keywords_test(void (*)(keywords<nkeywords>&));
-
- template<std::size_t nkeywords>
- yes_keywords_t is_keywords_test(void (*)(keywords<nkeywords> const&));
-
- template<typename T>
- class is_reference_to_keywords
- {
- public:
- BOOST_STATIC_CONSTANT(
- bool, value = (
- sizeof(detail::is_keywords_test( (void (*)(T))0 ))
- == sizeof(detail::yes_keywords_t)));
-
- typedef mpl::bool_<value> type;
- BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
- };
-# endif
}
inline detail::keywords<1> args(char const* name)
diff --git a/boost/python/back_reference.hpp b/boost/python/back_reference.hpp
index c1daba60c1..e68066f7d5 100644
--- a/boost/python/back_reference.hpp
+++ b/boost/python/back_reference.hpp
@@ -29,7 +29,6 @@ struct back_reference
T m_value;
};
-# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<typename T>
class is_back_reference
{
@@ -44,36 +43,6 @@ class is_back_reference<back_reference<T> >
BOOST_STATIC_CONSTANT(bool, value = true);
};
-# else // no partial specialization
-
-}} // namespace boost::python
-
-#include <boost/type.hpp>
-
-namespace boost { namespace python {
-
-namespace detail
-{
- typedef char (&yes_back_reference_t)[1];
- typedef char (&no_back_reference_t)[2];
-
- no_back_reference_t is_back_reference_test(...);
-
- template<typename T>
- yes_back_reference_t is_back_reference_test(boost::type< back_reference<T> >);
-}
-
-template<typename T>
-class is_back_reference
-{
- public:
- BOOST_STATIC_CONSTANT(
- bool, value = (
- sizeof(detail::is_back_reference_test(boost::type<T>()))
- == sizeof(detail::yes_back_reference_t)));
-};
-
-# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
//
// implementations
diff --git a/boost/python/bases.hpp b/boost/python/bases.hpp
index 0bd7350e55..614d62232b 100644
--- a/boost/python/bases.hpp
+++ b/boost/python/bases.hpp
@@ -24,7 +24,6 @@ namespace boost { namespace python {
namespace detail
{
-# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T> struct specifies_bases
: mpl::false_
{
@@ -35,23 +34,6 @@ namespace boost { namespace python {
: mpl::true_
{
};
-# else
- template < BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, class Base) >
- static char is_bases_helper(bases< BOOST_PYTHON_BASE_PARAMS > const&);
-
- static char (& is_bases_helper(...) )[256];
-
- template <class T>
- struct specifies_bases
- {
- private:
- static typename add_reference<T>::type make();
- BOOST_STATIC_CONSTANT(bool, non_ref = !is_reference<T>::value);
- public:
- BOOST_STATIC_CONSTANT(bool, value = non_ref & (sizeof(is_bases_helper(make())) == 1));
- typedef mpl::bool_<value> type;
- };
-# endif
template <class T, class Prev = bases<> >
struct select_bases
: mpl::if_<
diff --git a/boost/python/class.hpp b/boost/python/class.hpp
index 253667bbd7..f43b615ace 100644
--- a/boost/python/class.hpp
+++ b/boost/python/class.hpp
@@ -45,8 +45,7 @@
# if BOOST_WORKAROUND(__MWERKS__, <= 0x3004) \
/* pro9 reintroduced the bug */ \
|| (BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
- && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201))) \
- || BOOST_WORKAROUND(__GNUC__, < 3)
+ && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# define BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING 1
@@ -302,7 +301,6 @@ class class_ : public objects::class_base
}
// Property creation
-# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
template <class Get>
self& add_property(char const* name, Get fget, char const* docstr = 0)
{
@@ -317,47 +315,6 @@ class class_ : public objects::class_base
name, this->make_getter(fget), this->make_setter(fset), docstr);
return *this;
}
-# else
- private:
- template <class Get>
- self& add_property_impl(char const* name, Get fget, char const* docstr, int)
- {
- base::add_property(name, this->make_getter(fget), docstr);
- return *this;
- }
-
- template <class Get, class Set>
- self& add_property_impl(char const* name, Get fget, Set fset, ...)
- {
- base::add_property(
- name, this->make_getter(fget), this->make_setter(fset), 0);
- return *this;
- }
-
- public:
- template <class Get>
- self& add_property(char const* name, Get fget)
- {
- base::add_property(name, this->make_getter(fget), 0);
- return *this;
- }
-
- template <class Get, class DocStrOrSet>
- self& add_property(char const* name, Get fget, DocStrOrSet docstr_or_set)
- {
- this->add_property_impl(name, this->make_getter(fget), docstr_or_set, 0);
- return *this;
- }
-
- template <class Get, class Set>
- self&
- add_property(char const* name, Get fget, Set fset, char const* docstr)
- {
- base::add_property(
- name, this->make_getter(fget), this->make_setter(fset), docstr);
- return *this;
- }
-# endif
template <class Get>
self& add_static_property(char const* name, Get fget)
diff --git a/boost/python/converter/arg_from_python.hpp b/boost/python/converter/arg_from_python.hpp
index e2edce7e1c..61bbaad570 100755..100644
--- a/boost/python/converter/arg_from_python.hpp
+++ b/boost/python/converter/arg_from_python.hpp
@@ -115,9 +115,9 @@ struct arg_rvalue_from_python
arg_rvalue_from_python(PyObject*);
bool convertible() const;
-# if BOOST_MSVC < 1301 || _MSC_FULL_VER > 13102196
+# if _MSC_FULL_VER > 13102196
typename arg_rvalue_from_python<T>::
-# endif
+# endif
result_type operator()();
private:
diff --git a/boost/python/converter/arg_to_python_base.hpp b/boost/python/converter/arg_to_python_base.hpp
index d85b302e48..c66ce9c3e0 100755..100644
--- a/boost/python/converter/arg_to_python_base.hpp
+++ b/boost/python/converter/arg_to_python_base.hpp
@@ -13,17 +13,9 @@ struct registration;
namespace detail
{
struct BOOST_PYTHON_DECL arg_to_python_base
-# if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102179
: handle<>
-# endif
{
arg_to_python_base(void const volatile* source, registration const&);
-# if defined(BOOST_MSVC) && BOOST_MSVC > 1300 && _MSC_FULL_VER <= 13102179
- PyObject* get() const { return m_ptr.get(); }
- PyObject* release() { return m_ptr.release(); }
- private:
- handle<> m_ptr;
-# endif
};
}
diff --git a/boost/python/converter/object_manager.hpp b/boost/python/converter/object_manager.hpp
index 84e44d475b..4668245545 100755..100644
--- a/boost/python/converter/object_manager.hpp
+++ b/boost/python/converter/object_manager.hpp
@@ -121,7 +121,6 @@ struct is_object_manager
{
};
-# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct is_reference_to_object_manager
: mpl::false_
@@ -151,79 +150,6 @@ struct is_reference_to_object_manager<T const volatile&>
: is_object_manager<T>
{
};
-# else
-
-namespace detail
-{
- typedef char (&yes_reference_to_object_manager)[1];
- typedef char (&no_reference_to_object_manager)[2];
-
- // A number of nastinesses go on here in order to work around MSVC6
- // bugs.
- template <class T>
- struct is_object_manager_help
- {
- typedef typename mpl::if_<
- is_object_manager<T>
- , yes_reference_to_object_manager
- , no_reference_to_object_manager
- >::type type;
-
- // If we just use the type instead of the result of calling this
- // function, VC6 will ICE.
- static type call();
- };
-
- // A set of overloads for each cv-qualification. The same argument
- // is passed twice: the first one is used to unwind the cv*, and the
- // second one is used to avoid relying on partial ordering for
- // overload resolution.
- template <class U>
- typename is_object_manager_help<U>
- is_object_manager_helper(U*, void*);
-
- template <class U>
- typename is_object_manager_help<U>
- is_object_manager_helper(U const*, void const*);
-
- template <class U>
- typename is_object_manager_help<U>
- is_object_manager_helper(U volatile*, void volatile*);
-
- template <class U>
- typename is_object_manager_help<U>
- is_object_manager_helper(U const volatile*, void const volatile*);
-
- template <class T>
- struct is_reference_to_object_manager_nonref
- : mpl::false_
- {
- };
-
- template <class T>
- struct is_reference_to_object_manager_ref
- {
- static T sample_object;
- BOOST_STATIC_CONSTANT(
- bool, value
- = (sizeof(is_object_manager_helper(&sample_object, &sample_object).call())
- == sizeof(detail::yes_reference_to_object_manager)
- )
- );
- typedef mpl::bool_<value> type;
- };
-}
-
-template <class T>
-struct is_reference_to_object_manager
- : mpl::if_<
- is_reference<T>
- , detail::is_reference_to_object_manager_ref<T>
- , detail::is_reference_to_object_manager_nonref<T>
- >::type
-{
-};
-# endif
}}} // namespace boost::python::converter
diff --git a/boost/python/converter/registered.hpp b/boost/python/converter/registered.hpp
index 2404cb0ff2..68bb3c4a70 100644
--- a/boost/python/converter/registered.hpp
+++ b/boost/python/converter/registered.hpp
@@ -44,8 +44,7 @@ struct registered
{
};
-# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
- && !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
+# if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
// collapses a few more types to the same static instance. MSVC7.1
// fails to strip cv-qualification from array types in typeid. For
// some reason we can't use this collapse there or array converters
diff --git a/boost/python/converter/registered_pointee.hpp b/boost/python/converter/registered_pointee.hpp
index d9e7ac75a8..974cb6d810 100644
--- a/boost/python/converter/registered_pointee.hpp
+++ b/boost/python/converter/registered_pointee.hpp
@@ -14,7 +14,6 @@ namespace boost { namespace python { namespace converter {
struct registration;
-# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct registered_pointee
: registered<
@@ -26,37 +25,6 @@ struct registered_pointee
>
{
};
-# else
-namespace detail
-{
- template <class T>
- struct registered_pointee_base
- {
- static registration const& converters;
- };
-}
-
-template <class T>
-struct registered_pointee
- : detail::registered_pointee_base<
- typename add_reference<
- typename add_cv<T>::type
- >::type
- >
-{
-};
-
-//
-// implementations
-//
-namespace detail
-{
- template <class T>
- registration const& registered_pointee_base<T>::converters
- = registry::lookup(pointer_type_id<T>());
-}
-
-# endif
}}} // namespace boost::python::converter
#endif // REGISTERED_POINTEE_DWA2002710_HPP
diff --git a/boost/python/copy_const_reference.hpp b/boost/python/copy_const_reference.hpp
index 19e3b42332..55bede136f 100644
--- a/boost/python/copy_const_reference.hpp
+++ b/boost/python/copy_const_reference.hpp
@@ -16,7 +16,7 @@ namespace detail
{
template <class R>
struct copy_const_reference_expects_a_const_reference_return_type
-# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
+# if defined(__GNUC__) || defined(__EDG__)
{}
# endif
;
diff --git a/boost/python/copy_non_const_reference.hpp b/boost/python/copy_non_const_reference.hpp
index 78b70f5d3b..15fef62d67 100644
--- a/boost/python/copy_non_const_reference.hpp
+++ b/boost/python/copy_non_const_reference.hpp
@@ -16,7 +16,7 @@ namespace detail
{
template <class R>
struct copy_non_const_reference_expects_a_non_const_reference_return_type
-# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
+# if defined(__GNUC__) || defined(__EDG__)
{}
# endif
;
diff --git a/boost/python/data_members.hpp b/boost/python/data_members.hpp
index b0851fb1b3..139bde3270 100644
--- a/boost/python/data_members.hpp
+++ b/boost/python/data_members.hpp
@@ -270,7 +270,7 @@ inline object make_getter(D& x)
return detail::make_getter(x, policy, is_member_pointer<D>(), 0L);
}
-# if !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) && !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+# if !BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
template <class D>
inline object make_getter(D const& d)
{
@@ -305,7 +305,7 @@ inline object make_setter(D& x)
return detail::make_setter(x, default_call_policies(), is_member_pointer<D>(), 0);
}
-# if !(BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(__EDG_VERSION__, <= 238))
+# if BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
template <class D>
inline object make_setter(D const& x)
{
diff --git a/boost/python/default_call_policies.hpp b/boost/python/default_call_policies.hpp
index 3d32d2eb49..fcc242a924 100644
--- a/boost/python/default_call_policies.hpp
+++ b/boost/python/default_call_policies.hpp
@@ -23,7 +23,7 @@ namespace detail
{
// for "readable" error messages
template <class T> struct specify_a_return_value_policy_to_wrap_functions_returning
-# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
+# if defined(__GNUC__) || defined(__EDG__)
{}
# endif
;
diff --git a/boost/python/detail/borrowed_ptr.hpp b/boost/python/detail/borrowed_ptr.hpp
index b88457b83a..d91d05c90f 100755..100644
--- a/boost/python/detail/borrowed_ptr.hpp
+++ b/boost/python/detail/borrowed_ptr.hpp
@@ -19,7 +19,6 @@ template<class T> class borrowed
typedef T type;
};
-# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<typename T>
struct is_borrowed_ptr
{
@@ -68,35 +67,6 @@ struct is_borrowed_ptr<T*>
};
# endif
-# else // no partial specialization
-
-typedef char (&yes_borrowed_ptr_t)[1];
-typedef char (&no_borrowed_ptr_t)[2];
-
-no_borrowed_ptr_t is_borrowed_ptr_test(...);
-
-template <class T>
-typename mpl::if_c<
- is_pointer<T>::value
- , T
- , int
- >::type
-is_borrowed_ptr_test1(boost::type<T>);
-
-template<typename T>
-yes_borrowed_ptr_t is_borrowed_ptr_test(borrowed<T> const volatile*);
-
-template<typename T>
-class is_borrowed_ptr
-{
- public:
- BOOST_STATIC_CONSTANT(
- bool, value = (
- sizeof(detail::is_borrowed_ptr_test(is_borrowed_ptr_test1(boost::type<T>())))
- == sizeof(detail::yes_borrowed_ptr_t)));
-};
-
-# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
}
diff --git a/boost/python/detail/config.hpp b/boost/python/detail/config.hpp
index 76595ebbfc..1857d39a40 100644
--- a/boost/python/detail/config.hpp
+++ b/boost/python/detail/config.hpp
@@ -29,9 +29,6 @@
# endif
# if defined(BOOST_MSVC)
-# if _MSC_VER < 1300
-# define BOOST_MSVC6_OR_EARLIER 1
-# endif
# pragma warning (disable : 4786) // disable truncated debug symbols
# pragma warning (disable : 4251) // disable exported dll function
diff --git a/boost/python/detail/construct.hpp b/boost/python/detail/construct.hpp
index 5f15d22c6e..e69fbc7538 100644
--- a/boost/python/detail/construct.hpp
+++ b/boost/python/detail/construct.hpp
@@ -8,13 +8,7 @@
namespace boost { namespace python { namespace detail {
template <class T, class Arg>
-void construct_pointee(void* storage, Arg& x
-# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
- , T const volatile*
-# else
- , T const*
-# endif
- )
+void construct_pointee(void* storage, Arg& x, T const volatile*)
{
new (storage) T(x);
}
diff --git a/boost/python/detail/cv_category.hpp b/boost/python/detail/cv_category.hpp
index 1765b36f8c..d32dd0fdbe 100644
--- a/boost/python/detail/cv_category.hpp
+++ b/boost/python/detail/cv_category.hpp
@@ -12,7 +12,7 @@ template <bool is_const_, bool is_volatile_>
struct cv_tag
{
BOOST_STATIC_CONSTANT(bool, is_const = is_const_);
- BOOST_STATIC_CONSTANT(bool, is_volatile = is_const_);
+ BOOST_STATIC_CONSTANT(bool, is_volatile = is_volatile_);
};
typedef cv_tag<false,false> cv_unqualified;
diff --git a/boost/python/detail/destroy.hpp b/boost/python/detail/destroy.hpp
index 0172dca28f..3ea6455330 100644
--- a/boost/python/detail/destroy.hpp
+++ b/boost/python/detail/destroy.hpp
@@ -7,25 +7,12 @@
# include <boost/type_traits/is_array.hpp>
# include <boost/detail/workaround.hpp>
-# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
-# include <boost/type_traits/is_enum.hpp>
-# endif
namespace boost { namespace python { namespace detail {
-template <
- bool array
-# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
- , bool enum_ // vc7 has a problem destroying enums
-# endif
- > struct value_destroyer;
+template <bool array> struct value_destroyer;
template <>
-struct value_destroyer<
- false
-# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
- , false
-# endif
- >
+struct value_destroyer<false>
{
template <class T>
static void execute(T const volatile* p)
@@ -35,12 +22,7 @@ struct value_destroyer<
};
template <>
-struct value_destroyer<
- true
-# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
- , false
-# endif
- >
+struct value_destroyer<true>
{
template <class A, class T>
static void execute(A*, T const volatile* const first)
@@ -49,9 +31,6 @@ struct value_destroyer<
{
value_destroyer<
boost::is_array<T>::value
-# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
- , boost::is_enum<T>::value
-# endif
>::execute(p);
}
}
@@ -63,25 +42,6 @@ struct value_destroyer<
}
};
-# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
-template <>
-struct value_destroyer<true,true>
-{
- template <class T>
- static void execute(T const volatile*)
- {
- }
-};
-
-template <>
-struct value_destroyer<false,true>
-{
- template <class T>
- static void execute(T const volatile*)
- {
- }
-};
-# endif
template <class T>
inline void destroy_referent_impl(void* p, T& (*)())
{
@@ -89,9 +49,6 @@ inline void destroy_referent_impl(void* p, T& (*)())
// must come *before* T for metrowerks
value_destroyer<
(boost::is_array<T>::value)
-# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
- , (boost::is_enum<T>::value)
-# endif
>::execute((const volatile T*)p);
}
diff --git a/boost/python/detail/enable_if.hpp b/boost/python/detail/enable_if.hpp
index 46a1d532b3..7a37be121a 100755..100644
--- a/boost/python/detail/enable_if.hpp
+++ b/boost/python/detail/enable_if.hpp
@@ -7,40 +7,7 @@
# include <boost/python/detail/sfinae.hpp>
# include <boost/detail/workaround.hpp>
-# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
-# include <boost/mpl/if.hpp>
-
-namespace boost { namespace python { namespace detail {
-
-template <class T> struct always_void { typedef void type; };
-
-template <class C, class T = int>
-struct enable_if_arg
-{
- typedef typename mpl::if_<C,T,int&>::type type;
-};
-
-template <class C, class T = int>
-struct disable_if_arg
-{
- typedef typename mpl::if_<C,int&,T>::type type;
-};
-
-template <class C, class T = typename always_void<C>::type>
-struct enable_if_ret
-{
- typedef typename mpl::if_<C,T,int[2]>::type type;
-};
-
-template <class C, class T = typename always_void<C>::type>
-struct disable_if_ret
-{
- typedef typename mpl::if_<C,int[2],T>::type type;
-};
-
-}}} // namespace boost::python::detail
-
-# elif !defined(BOOST_NO_SFINAE)
+#if !defined(BOOST_NO_SFINAE)
# include <boost/utility/enable_if.hpp>
namespace boost { namespace python { namespace detail {
diff --git a/boost/python/detail/force_instantiate.hpp b/boost/python/detail/force_instantiate.hpp
index 63e2874945..a8901b2da7 100755..100644
--- a/boost/python/detail/force_instantiate.hpp
+++ b/boost/python/detail/force_instantiate.hpp
@@ -10,23 +10,9 @@ namespace boost { namespace python { namespace detail {
// Allows us to force the argument to be instantiated without
// incurring unused variable warnings
-# if !defined(BOOST_MSVC) || BOOST_MSVC < 1300 || _MSC_FULL_VER > 13102196
-
template <class T>
inline void force_instantiate(T const&) {}
-# else
-
-# pragma optimize("g", off)
-inline void force_instantiate_impl(...) {}
-# pragma optimize("", on)
-template <class T>
-inline void force_instantiate(T const& x)
-{
- detail::force_instantiate_impl(&x);
-}
-# endif
-
}}} // namespace boost::python::detail
#endif // FORCE_INSTANTIATE_DWA200265_HPP
diff --git a/boost/python/detail/if_else.hpp b/boost/python/detail/if_else.hpp
index 244e63a8ae..3f505c5edb 100644
--- a/boost/python/detail/if_else.hpp
+++ b/boost/python/detail/if_else.hpp
@@ -25,46 +25,11 @@ struct if_selected
};
};
-# if defined(BOOST_MSVC) && (BOOST_MSVC == 1300)
-namespace msvc70_aux {
-
-template< bool > struct inherit_from
-{
- template< typename T > struct result
- {
- typedef T type;
- };
-};
-
-template<> struct inherit_from<true>
-{
- template< typename T > struct result
- {
- struct type {};
- };
-};
-
-template< typename T >
-struct never_true
-{
- BOOST_STATIC_CONSTANT(bool, value = false);
-};
-
-} // namespace msvc70_aux
-
-#endif // # if defined(BOOST_MSVC) && (BOOST_MSVC == 1300)
-
template <class T>
struct elif_selected
{
-# if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__MWERKS__) && __MWERKS__ <= 0x2407)
+# if !(defined(__MWERKS__) && __MWERKS__ <= 0x2407)
template <class U> class then;
-# elif defined(BOOST_MSVC) && (BOOST_MSVC == 1300)
- template <class U>
- struct then : msvc70_aux::inherit_from< msvc70_aux::never_true<U>::value >
- ::template result< if_selected<T> >::type
- {
- };
# else
template <class U>
struct then : if_selected<T>
@@ -73,7 +38,7 @@ struct elif_selected
# endif
};
-# if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__MWERKS__) && __MWERKS__ <= 0x2407)
+# if !(defined(__MWERKS__) && __MWERKS__ <= 0x2407)
template <class T>
template <class U>
class elif_selected<T>::then : public if_selected<T>
diff --git a/boost/python/detail/msvc_typeinfo.hpp b/boost/python/detail/msvc_typeinfo.hpp
index 10f845058a..bfc84164f0 100644
--- a/boost/python/detail/msvc_typeinfo.hpp
+++ b/boost/python/detail/msvc_typeinfo.hpp
@@ -7,15 +7,18 @@
#include <typeinfo>
#include <boost/type.hpp>
-#include <boost/type_traits/config.hpp>
//
-// Fix for MSVC's broken typeid() implementation which doesn't strip
+// Fix for icc's broken typeid() implementation which doesn't strip
// decoration. This fix doesn't handle cv-qualified array types. It
// could probably be done, but I haven't figured it out yet.
//
-# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 700
+// Note: This file is badly named. It initially was MSVC specific, but was
+// extended to cover intel too. Now the old version of MSVC is no longer
+// supported, but the intel version is still supported.
+
+# if defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 700
namespace boost { namespace python { namespace detail {
@@ -44,8 +47,14 @@ inline typeinfo typeid_ref(type<T>*, ...)
return detail::typeid_ref_1((T(*)())0);
}
+#if defined(BOOST_MSVC) || (defined(__BORLANDC__) && !defined(BOOST_DISABLE_WIN32))
+# define BOOST_PYTT_DECL __cdecl
+#else
+# define BOOST_PYTT_DECL /**/
+#endif
+
template< typename T > T&(* is_ref_tester1(type<T>) )(type<T>) { return 0; }
-inline char BOOST_TT_DECL is_ref_tester1(...) { return 0; }
+inline char BOOST_PYTT_DECL is_ref_tester1(...) { return 0; }
template <class T>
inline typeinfo msvc_typeid(boost::type<T>*)
@@ -71,5 +80,5 @@ inline typeinfo assert_array_typeid_compiles()
}}} // namespace boost::python::detail
-# endif // BOOST_MSVC
+# endif // BOOST_INTEL_CXX_VERSION
#endif // MSVC_TYPEINFO_DWA200222_HPP
diff --git a/boost/python/detail/referent_storage.hpp b/boost/python/detail/referent_storage.hpp
index 0a1ef5a04e..2cddf696d5 100644
--- a/boost/python/detail/referent_storage.hpp
+++ b/boost/python/detail/referent_storage.hpp
@@ -42,7 +42,6 @@ union aligned_storage
// but sizeof() is broken in CodeWarriors <= 8.0
template <class T> struct referent_size;
-# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct referent_size<T&>
@@ -51,15 +50,6 @@ union aligned_storage
std::size_t, value = sizeof(T));
};
-# else
-
- template <class T> struct referent_size
- {
- static T f();
- BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(f()));
- };
-
-# endif
// A metafunction returning a POD type which can store U, where T ==
// U&. If T is not a reference type, returns a POD which can store T.
diff --git a/boost/python/detail/result.hpp b/boost/python/detail/result.hpp
index 9b8b486423..8ccc3c5029 100644
--- a/boost/python/detail/result.hpp
+++ b/boost/python/detail/result.hpp
@@ -43,9 +43,7 @@ namespace boost { namespace python { namespace detail {
template <class R, class T>
boost::type<R>* result(R (T::*), int = 0) { return 0; }
-# if (defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140) \
- || (defined(__GNUC__) && __GNUC__ < 3) \
- || (defined(__MWERKS__) && __MWERKS__ < 0x3000)
+# if (defined(__MWERKS__) && __MWERKS__ < 0x3000)
// This code actually works on all implementations, but why use it when we don't have to?
template <class T>
struct get_result_type
diff --git a/boost/python/detail/string_literal.hpp b/boost/python/detail/string_literal.hpp
index 50193b6436..a56e72ec6b 100644
--- a/boost/python/detail/string_literal.hpp
+++ b/boost/python/detail/string_literal.hpp
@@ -14,7 +14,6 @@
namespace boost { namespace python { namespace detail {
-# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct is_string_literal : mpl::false_
{
@@ -45,43 +44,6 @@ struct is_string_literal<T[n]>
{
};
# endif
-# else
-template <bool is_array = true>
-struct string_literal_helper
-{
- typedef char (&yes_string_literal)[1];
- typedef char (&no_string_literal)[2];
-
- template <class T>
- struct apply
- {
- typedef apply<T> self;
- static T x;
- static yes_string_literal check(char const*);
- static no_string_literal check(char*);
- static no_string_literal check(void const volatile*);
-
- BOOST_STATIC_CONSTANT(
- bool, value = sizeof(self::check(x)) == sizeof(yes_string_literal));
- typedef mpl::bool_<value> type;
- };
-};
-
-template <>
-struct string_literal_helper<false>
-{
- template <class T>
- struct apply : mpl::false_
- {
- };
-};
-
-template <class T>
-struct is_string_literal
- : string_literal_helper<is_array<T>::value>::apply<T>
-{
-};
-# endif
}}} // namespace boost::python::detail
diff --git a/boost/python/detail/type_list.hpp b/boost/python/detail/type_list.hpp
index 9483c1945c..0ad3f63d84 100644
--- a/boost/python/detail/type_list.hpp
+++ b/boost/python/detail/type_list.hpp
@@ -30,10 +30,6 @@
# include <boost/mpl/vector/vector10.hpp>
# endif
-# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
# include <boost/python/detail/type_list_impl.hpp>
-# else
-# include <boost/python/detail/type_list_impl_no_pts.hpp>
-# endif
#endif // TYPE_LIST_DWA2002913_HPP
diff --git a/boost/python/detail/type_list_impl_no_pts.hpp b/boost/python/detail/type_list_impl_no_pts.hpp
deleted file mode 100644
index 15d9252374..0000000000
--- a/boost/python/detail/type_list_impl_no_pts.hpp
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifndef BOOST_PP_IS_ITERATING
-// 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 TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP
-# define TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP
-
-# include <boost/python/detail/type_list.hpp>
-
-# include <boost/preprocessor/enum_params.hpp>
-# include <boost/preprocessor/enum_params_with_a_default.hpp>
-# include <boost/preprocessor/cat.hpp>
-# include <boost/preprocessor/repeat.hpp>
-# include <boost/preprocessor/empty.hpp>
-# include <boost/preprocessor/iterate.hpp>
-# include <boost/mpl/void.hpp>
-
-namespace boost { namespace python { namespace detail {
-
-template< typename T >
-struct is_list_arg
-{
- enum { value = true };
-};
-
-template<>
-struct is_list_arg<mpl::void_>
-{
- enum { value = false };
-};
-
-template<int> struct type_list_impl_chooser;
-
-# define BOOST_PYTHON_LIST_ACTUAL_PARAMS BOOST_PP_ENUM_PARAMS_Z(1,BOOST_PYTHON_LIST_SIZE,T)
-# define BOOST_PYTHON_LIST_FORMAL_PARAMS BOOST_PP_ENUM_PARAMS_Z(1,BOOST_PYTHON_LIST_SIZE,class T)
-
-# define BOOST_PP_ITERATION_PARAMS_1 \
- (3, (0, BOOST_PYTHON_LIST_SIZE, <boost/python/detail/type_list_impl_no_pts.hpp>))
-# include BOOST_PP_ITERATE()
-
-# define BOOST_PYTHON_PLUS() +
-# define BOOST_PYTHON_IS_LIST_ARG(z, n, data) \
- BOOST_PP_IF(n, BOOST_PYTHON_PLUS, BOOST_PP_EMPTY)() \
- is_list_arg< BOOST_PP_CAT(T,n) >::value
-
-template<
- BOOST_PYTHON_LIST_FORMAL_PARAMS
- >
-struct type_list_count_args
-{
- enum { value =
- BOOST_PP_REPEAT_1(BOOST_PYTHON_LIST_SIZE, BOOST_PYTHON_IS_LIST_ARG, _)
- };
-};
-
-template<
- BOOST_PYTHON_LIST_FORMAL_PARAMS
- >
-struct type_list_impl
-{
- typedef type_list_count_args< BOOST_PYTHON_LIST_ACTUAL_PARAMS > arg_num_;
- typedef typename detail::type_list_impl_chooser< arg_num_::value >
- ::template result_< BOOST_PYTHON_LIST_ACTUAL_PARAMS >::type type;
-};
-
-template<
- BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_LIST_SIZE, class T, mpl::void_)
- >
-struct type_list
- : detail::type_list_impl< BOOST_PYTHON_LIST_ACTUAL_PARAMS >::type
-{
- typedef typename detail::type_list_impl<
- BOOST_PYTHON_LIST_ACTUAL_PARAMS
- >::type type;
-};
-
-# undef BOOST_PYTHON_IS_LIST_ARG
-# undef BOOST_PYTHON_PLUS
-# undef BOOST_PYTHON_LIST_FORMAL_PARAMS
-# undef BOOST_PYTHON_LIST_ACTUAL_PARAMS
-
-}}} // namespace boost::python::detail
-
-# endif // TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP
-
-#else // BOOST_PP_IS_ITERATING
-
-# define N BOOST_PP_ITERATION()
-
-template<>
-struct type_list_impl_chooser<N>
-{
- template<
- BOOST_PYTHON_LIST_FORMAL_PARAMS
- >
- struct result_
- {
- typedef typename BOOST_PP_CAT(mpl::vector,N)<
- BOOST_PP_ENUM_PARAMS(N, T)
- >::type type;
- };
-};
-
-# undef N
-
-#endif // BOOST_PP_IS_ITERATING
diff --git a/boost/python/detail/value_is_xxx.hpp b/boost/python/detail/value_is_xxx.hpp
index 2b12564907..fbb9defd0b 100644
--- a/boost/python/detail/value_is_xxx.hpp
+++ b/boost/python/detail/value_is_xxx.hpp
@@ -9,35 +9,6 @@
# include <boost/mpl/bool.hpp>
# include <boost/preprocessor/enum_params.hpp>
-# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
-# include <boost/type_traits/is_reference.hpp>
-# include <boost/type_traits/add_reference.hpp>
-
-# define BOOST_PYTHON_VALUE_IS_XXX_DEF(name, qualified_name, nargs) \
-template <class X_> \
-struct value_is_##name \
-{ \
- typedef char yes; \
- typedef char (&no)[2]; \
- \
- static typename add_reference<X_>::type dummy; \
- \
- template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class U) > \
- static yes test( \
- qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, U) > const&, int \
- ); \
- \
- template <class U> \
- static no test(U&, ...); \
- \
- BOOST_STATIC_CONSTANT( \
- bool, value \
- = (sizeof(test(dummy, 0)) == sizeof(yes))); \
- \
- typedef mpl::bool_<value> type; \
-};
-
-# else
# include <boost/type_traits/remove_reference.hpp>
# include <boost/type_traits/remove_cv.hpp>
@@ -57,6 +28,5 @@ struct value_is_##name \
\
};
-# endif
#endif // VALUE_IS_XXX_DWA2003224_HPP
diff --git a/boost/python/extract.hpp b/boost/python/extract.hpp
index 544c61f070..bfdeb83ce7 100644
--- a/boost/python/extract.hpp
+++ b/boost/python/extract.hpp
@@ -21,8 +21,7 @@
# include <boost/python/detail/void_return.hpp>
# include <boost/call_traits.hpp>
-#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(BOOST_INTEL_WIN, <= 900)
-// workaround for VC++ 6.x or 7.0
+#if BOOST_WORKAROUND(BOOST_INTEL_WIN, <= 900)
# define BOOST_EXTRACT_WORKAROUND ()
#else
# define BOOST_EXTRACT_WORKAROUND
diff --git a/boost/python/handle.hpp b/boost/python/handle.hpp
index 461a219ad8..ee9a7cd09d 100755..100644
--- a/boost/python/handle.hpp
+++ b/boost/python/handle.hpp
@@ -87,8 +87,6 @@ class handle
return *this;
}
-#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
-
template<typename Y>
handle& operator=(handle<Y> const & r) // never throws
{
@@ -97,8 +95,6 @@ class handle
return *this;
}
-#endif
-
template <typename Y>
handle(handle<Y> const& r)
: m_p(python::xincref(python::upcast<T>(r.get())))
@@ -159,7 +155,6 @@ typedef handle<PyTypeObject> type_handle;
//
// Compile-time introspection
//
-# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<typename T>
class is_handle
{
@@ -173,28 +168,6 @@ class is_handle<handle<T> >
public:
BOOST_STATIC_CONSTANT(bool, value = true);
};
-# else
-namespace detail
-{
- typedef char (&yes_handle_t)[1];
- typedef char (&no_handle_t)[2];
-
- no_handle_t is_handle_test(...);
-
- template<typename T>
- yes_handle_t is_handle_test(boost::type< handle<T> >);
-}
-
-template<typename T>
-class is_handle
-{
- public:
- BOOST_STATIC_CONSTANT(
- bool, value = (
- sizeof(detail::is_handle_test(boost::type<T>()))
- == sizeof(detail::yes_handle_t)));
-};
-# endif
//
// implementations
diff --git a/boost/python/init.hpp b/boost/python/init.hpp
index 6598fd3547..b82ab01e15 100644
--- a/boost/python/init.hpp
+++ b/boost/python/init.hpp
@@ -76,27 +76,6 @@ namespace detail
//
// This metaprogram checks if T is an optional
//
-#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
-
- template <class T>
- struct is_optional {
-
- private:
-
- template <BOOST_PYTHON_OVERLOAD_TYPES>
- static boost::type_traits::yes_type f(optional<BOOST_PYTHON_OVERLOAD_ARGS>);
- static boost::type_traits::no_type f(...);
- static T t();
-
- public:
-
- BOOST_STATIC_CONSTANT(
- bool, value =
- sizeof(f(t())) == sizeof(::boost::type_traits::yes_type));
- typedef mpl::bool_<value> type;
- };
-
-#else
template <class T>
struct is_optional
@@ -108,7 +87,6 @@ namespace detail
: mpl::true_
{};
-#endif
template <int NDefaults>
struct define_class_init_helper;
diff --git a/boost/python/make_constructor.hpp b/boost/python/make_constructor.hpp
index 8ae722bbe3..47cdf469c7 100644
--- a/boost/python/make_constructor.hpp
+++ b/boost/python/make_constructor.hpp
@@ -104,14 +104,6 @@ namespace detail
// If the BasePolicy_ supplied a result converter it would be
// ignored; issue an error if it's not the default.
-#if defined _MSC_VER && _MSC_VER < 1300
- typedef is_same<
- typename BasePolicy_::result_converter
- , default_result_converter
- > same_result_converter;
- //see above for explanation
- BOOST_STATIC_ASSERT(same_result_converter::value) ;
-#else
BOOST_MPL_ASSERT_MSG(
(is_same<
typename BasePolicy_::result_converter
@@ -120,7 +112,6 @@ namespace detail
, MAKE_CONSTRUCTOR_SUPPLIES_ITS_OWN_RESULT_CONVERTER_THAT_WOULD_OVERRIDE_YOURS
, (typename BasePolicy_::result_converter)
);
-#endif
typedef constructor_result_converter result_converter;
typedef offset_args<typename BasePolicy_::argument_package, mpl::int_<1> > argument_package;
};
diff --git a/boost/python/manage_new_object.hpp b/boost/python/manage_new_object.hpp
index d81421dace..9585b13a6f 100644
--- a/boost/python/manage_new_object.hpp
+++ b/boost/python/manage_new_object.hpp
@@ -17,7 +17,7 @@ namespace detail
{
template <class R>
struct manage_new_object_requires_a_pointer_return_type
-# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
+# if defined(__GNUC__) || defined(__EDG__)
{}
# endif
;
diff --git a/boost/python/object/class_metadata.hpp b/boost/python/object/class_metadata.hpp
index 155ae35d06..c71cf67c4e 100644
--- a/boost/python/object/class_metadata.hpp
+++ b/boost/python/object/class_metadata.hpp
@@ -53,11 +53,7 @@ struct register_base_of
template <class Base>
inline void operator()(Base*) const
{
-# if !BOOST_WORKAROUND(BOOST_MSVC, == 1200)
BOOST_MPL_ASSERT_NOT((is_same<Base,Derived>));
-# else
- BOOST_STATIC_ASSERT(!(is_same<Base,Derived>::value));
-# endif
// Register the Base class
register_dynamic_id<Base>();
diff --git a/boost/python/object/forward.hpp b/boost/python/object/forward.hpp
index 2faf3321ec..30613d8ebd 100644
--- a/boost/python/object/forward.hpp
+++ b/boost/python/object/forward.hpp
@@ -12,13 +12,7 @@
# include <boost/ref.hpp>
# include <boost/python/detail/value_arg.hpp>
# include <boost/python/detail/copy_ctor_mutates_rhs.hpp>
-# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-# include <boost/type_traits/is_enum.hpp>
-# include <boost/mpl/and.hpp>
-# include <boost/mpl/not.hpp>
-# else
-# include <boost/mpl/or.hpp>
-# endif
+# include <boost/mpl/or.hpp>
namespace boost { namespace python { namespace objects {
@@ -42,24 +36,13 @@ struct reference_to_value
template <class T>
struct forward
: mpl::if_<
-# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
- // vc6 chokes on unforwarding enums nested in classes
- mpl::and_<
- is_scalar<T>
- , mpl::not_<
- is_enum<T>
- >
- >
-# else
mpl::or_<python::detail::copy_ctor_mutates_rhs<T>, is_scalar<T> >
-# endif
, T
, reference_to_value<T>
>
{
};
-# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<typename T>
struct unforward
{
@@ -86,88 +69,6 @@ struct unforward_cref<reference_to_value<T> >
{
};
-# else // no partial specialization
-
-namespace detail
-{
- typedef char (&yes_reference_to_value_t)[1];
- typedef char (&no_reference_to_value_t)[2];
-
- no_reference_to_value_t is_reference_to_value_test(...);
-
- template<typename T>
- yes_reference_to_value_t is_reference_to_value_test(boost::type< reference_to_value<T> >);
-
- template<bool wrapped>
- struct unforwarder
- {
- template <class T>
- struct apply
- {
- typedef typename unwrap_reference<T>::type& type;
- };
- };
-
- template<>
- struct unforwarder<true>
- {
- template <class T>
- struct apply
- {
- typedef typename T::reference type;
- };
- };
-
- template<bool wrapped = false>
- struct cref_unforwarder
- {
- template <class T>
- struct apply
- : python::detail::value_arg<
- typename unwrap_reference<T>::type
- >
- {
- };
- };
-
- template<>
- struct cref_unforwarder<true>
- {
- template <class T>
- struct apply
- : python::detail::value_arg<
- typename T::reference
- >
- {
- };
- };
-
- template<typename T>
- struct is_reference_to_value
- {
- BOOST_STATIC_CONSTANT(
- bool, value = (
- sizeof(is_reference_to_value_test(boost::type<T>()))
- == sizeof(yes_reference_to_value_t)));
- typedef mpl::bool_<value> type;
- };
-}
-
-template <typename T>
-struct unforward
- : public detail::unforwarder<
- detail::is_reference_to_value<T>::value
- >::template apply<T>
-{};
-
-template <typename T>
-struct unforward_cref
- : public detail::cref_unforwarder<
- detail::is_reference_to_value<T>::value
- >::template apply<T>
-{};
-
-# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
typename reference_to_value<T>::reference
diff --git a/boost/python/object/iterator.hpp b/boost/python/object/iterator.hpp
index ab748fe82d..db5224713f 100644
--- a/boost/python/object/iterator.hpp
+++ b/boost/python/object/iterator.hpp
@@ -71,35 +71,7 @@ struct iterator_range
# endif
};
-# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- // for compilers which can't deduce the value_type of pointers, we
- // have a special implementation of next. This takes advantage of
- // the fact that T* results are treated like T& results by
- // Boost.Python's function wrappers.
- struct next_ptr
- {
- typedef Iterator result_type;
-
- result_type
- operator()(iterator_range<NextPolicies,Iterator>& self)
- {
- if (self.m_start == self.m_finish)
- stop_iteration_error();
- return self.m_start++;
- }
- };
-
- typedef mpl::if_<
- is_same<
- boost::detail::please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee<Iterator>
- , typename traits_t::value_type
- >
- , next_ptr
- , next
- >::type next_fn;
-# else
typedef next next_fn;
-# endif
object m_sequence; // Keeps the sequence alive while iterating.
Iterator m_start;
diff --git a/boost/python/object/pointer_holder.hpp b/boost/python/object/pointer_holder.hpp
index 4627e34ad2..27d95193a0 100644
--- a/boost/python/object/pointer_holder.hpp
+++ b/boost/python/object/pointer_holder.hpp
@@ -46,11 +46,7 @@ template <class T> class wrapper;
namespace boost { namespace python { namespace objects {
-# if BOOST_WORKAROUND(__GNUC__, == 2)
-# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward<A##n>::type)objects::do_unforward(a##n,0)
-# else
-# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0)
-# endif
+#define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0)
template <class Pointer, class Value>
struct pointer_holder : instance_holder
diff --git a/boost/python/object/value_holder.hpp b/boost/python/object/value_holder.hpp
index f4d452cab1..a4e91786d1 100644
--- a/boost/python/object/value_holder.hpp
+++ b/boost/python/object/value_holder.hpp
@@ -33,11 +33,7 @@
namespace boost { namespace python { namespace objects {
-# if BOOST_WORKAROUND(__GNUC__, == 2)
-# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward<A##n>::type)objects::do_unforward(a##n,0)
-# else
-# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0)
-# endif
+#define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0)
template <class Value>
struct value_holder : instance_holder
diff --git a/boost/python/object_core.hpp b/boost/python/object_core.hpp
index 9c9dc10bfc..6185779667 100644
--- a/boost/python/object_core.hpp
+++ b/boost/python/object_core.hpp
@@ -36,12 +36,6 @@
# include <boost/type_traits/is_convertible.hpp>
# include <boost/type_traits/remove_reference.hpp>
-# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
-# include <boost/type_traits/add_pointer.hpp>
-# endif
-
-# include <boost/mpl/if.hpp>
-
namespace boost { namespace python {
namespace detail
@@ -98,11 +92,7 @@ namespace api
class object_operators : public def_visitor<U>
{
protected:
-# if !defined(BOOST_MSVC) || BOOST_MSVC >= 1300
typedef object const& object_cref;
-# else
- typedef object object_cref;
-# endif
public:
// function call
//
@@ -139,25 +129,11 @@ namespace api
template <class T>
const_object_item
- operator[](T const& key) const
-# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
- ;
-# else
- {
- return (*this)[object(key)];
- }
-# endif
+ operator[](T const& key) const;
template <class T>
object_item
- operator[](T const& key)
-# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
- ;
-# else
- {
- return (*this)[object(key)];
- }
-# endif
+ operator[](T const& key);
// slicing
//
@@ -175,29 +151,11 @@ namespace api
template <class T, class V>
const_object_slice
- slice(T const& start, V const& end) const
-# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
- ;
-# else
- {
- return this->slice(
- slice_bound<T>::type(start)
- , slice_bound<V>::type(end));
- }
-# endif
+ slice(T const& start, V const& end) const;
template <class T, class V>
object_slice
- slice(T const& start, V const& end)
-# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
- ;
-# else
- {
- return this->slice(
- slice_bound<T>::type(start)
- , slice_bound<V>::type(end));
- }
-# endif
+ slice(T const& start, V const& end);
private: // def visitation for adding callable objects as class methods
@@ -248,26 +206,6 @@ namespace api
PyObject* m_ptr;
};
-# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- template <class T, class U>
- struct is_derived_impl
- {
- static T x;
- template <class X>
- static X* to_pointer(X const&);
-
- static char test(U const*);
- typedef char (&no)[2];
- static no test(...);
-
- BOOST_STATIC_CONSTANT(bool, value = sizeof(test(to_pointer(x))) == 1);
- };
-
- template <class T, class U>
- struct is_derived
- : mpl::bool_<is_derived_impl<T,U>::value>
- {};
-# else
template <class T, class U>
struct is_derived
: is_convertible<
@@ -275,28 +213,13 @@ namespace api
, U const*
>
{};
-# endif
template <class T>
typename objects::unforward_cref<T>::type do_unforward_cref(T const& x)
{
-# if BOOST_WORKAROUND(__GNUC__, == 2)
- typedef typename objects::unforward_cref<T>::type ret;
- return ret(x);
-# else
return x;
-# endif
}
-# if BOOST_WORKAROUND(__GNUC__, == 2)
- // GCC 2.x has non-const string literals; this hacks around that problem.
- template <unsigned N>
- char const (& do_unforward_cref(char const(&x)[N]) )[N]
- {
- return x;
- }
-# endif
-
class object;
template <class T>
@@ -323,14 +246,7 @@ namespace api
// explicit conversion from any C++ object to Python
template <class T>
- explicit object(
- T const& x
-# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
- // use some SFINAE to un-confuse MSVC about its
- // copy-initialization ambiguity claim.
- , typename mpl::if_<is_proxy<T>,int&,int>::type* = 0
-# endif
- )
+ explicit object(T const& x)
: object_base(object_base_initializer(x))
{
}
@@ -348,7 +264,7 @@ namespace api
// Macros for forwarding constructors in classes derived from
// object. Derived classes will usually want these as an
// implementation detail
-# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base) \
+# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(derived, base) \
inline explicit derived(::boost::python::detail::borrowed_reference p) \
: base(p) {} \
inline explicit derived(::boost::python::detail::new_reference p) \
@@ -356,23 +272,6 @@ namespace api
inline explicit derived(::boost::python::detail::new_non_null_reference p) \
: base(p) {}
-# if !defined(BOOST_MSVC) || BOOST_MSVC >= 1300
-# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_
-# else
- // MSVC6 has a bug which causes an explicit template constructor to
- // be preferred over an appropriate implicit conversion operator
- // declared on the argument type. Normally, that would cause a
- // runtime failure when using extract<T> to extract a type with a
- // templated constructor. This additional constructor will turn that
- // runtime failure into an ambiguity error at compile-time due to
- // the lack of partial ordering, or at least a link-time error if no
- // generalized template constructor is declared.
-# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(derived, base) \
- BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base) \
- template <class T> \
- explicit derived(extract<T> const&);
-# endif
-
//
// object_initializer -- get the handle to construct the object with,
// based on whether T is a proxy or derived from object
diff --git a/boost/python/object_items.hpp b/boost/python/object_items.hpp
index f0761dadbb..b048689a7c 100755..100644
--- a/boost/python/object_items.hpp
+++ b/boost/python/object_items.hpp
@@ -44,7 +44,6 @@ object_operators<U>::operator[](object_cref key) const
return const_object_item(x, key);
}
-# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
template <class U>
template <class T>
inline const_object_item
@@ -60,8 +59,6 @@ object_operators<U>::operator[](T const& key)
{
return (*this)[object(key)];
}
-# endif
-
inline object const_item_policies::get(object const& target, object const& key)
{
diff --git a/boost/python/object_slices.hpp b/boost/python/object_slices.hpp
index 748c2e954b..6cd3dc2974 100644
--- a/boost/python/object_slices.hpp
+++ b/boost/python/object_slices.hpp
@@ -99,7 +99,7 @@ object_operators<U>::slice(object_cref start, slice_nil) const
object_cref2 x = *static_cast<U const*>(this);
return const_object_slice(x, api::slice_key(borrowed(start.ptr()), allow_null((PyObject*)0)));
}
-# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
+
template <class U>
template <class T, class V>
inline const_object_slice
@@ -119,8 +119,6 @@ object_operators<U>::slice(T const& start, V const& end)
typename slice_bound<T>::type(start)
, typename slice_bound<V>::type(end));
}
-# endif
-
inline object const_slice_policies::get(object const& target, key_type const& key)
{
diff --git a/boost/python/opaque_pointer_converter.hpp b/boost/python/opaque_pointer_converter.hpp
index 10eb4234c8..e95c49bbfe 100644
--- a/boost/python/opaque_pointer_converter.hpp
+++ b/boost/python/opaque_pointer_converter.hpp
@@ -172,28 +172,19 @@ PyTypeObject opaque<Pointee>::type_object =
};
}} // namespace boost::python
-# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
-
-# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee)
-
-# else
-
// If you change the below, don't forget to alter the end of type_id.hpp
# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \
namespace boost { namespace python { \
template<> \
- inline type_info type_id<Pointee>(BOOST_PYTHON_EXPLICIT_TT_DEF(Pointee)) \
+ inline type_info type_id<Pointee>() \
{ \
return type_info (typeid (Pointee *)); \
} \
template<> \
- inline type_info type_id<const volatile Pointee&>( \
- BOOST_PYTHON_EXPLICIT_TT_DEF(const volatile Pointee&)) \
+ inline type_info type_id<const volatile Pointee&>() \
{ \
return type_info (typeid (Pointee *)); \
} \
}}
-# endif
-
# endif // OPAQUE_POINTER_CONVERTER_HPP_
diff --git a/boost/python/other.hpp b/boost/python/other.hpp
index eeece99b7d..24a24ad8d1 100755..100644
--- a/boost/python/other.hpp
+++ b/boost/python/other.hpp
@@ -7,9 +7,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-# if _MSC_VER+0 >= 1020
-# pragma once
-# endif
+# pragma once
# include <boost/config.hpp>
@@ -20,7 +18,6 @@ template<class T> struct other
typedef T type;
};
-# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace detail
{
template<typename T>
@@ -51,63 +48,6 @@ namespace detail
typedef T type;
};
}
-# else // no partial specialization
-
-}} // namespace boost::python
-
-#include <boost/type.hpp>
-
-namespace boost { namespace python {
-
-namespace detail
-{
- typedef char (&yes_other_t)[1];
- typedef char (&no_other_t)[2];
-
- no_other_t is_other_test(...);
-
- template<typename T>
- yes_other_t is_other_test(type< other<T> >);
-
- template<bool wrapped>
- struct other_unwrapper
- {
- template <class T>
- struct apply
- {
- typedef T type;
- };
- };
-
- template<>
- struct other_unwrapper<true>
- {
- template <class T>
- struct apply
- {
- typedef typename T::type type;
- };
- };
-
- template<typename T>
- class is_other
- {
- public:
- BOOST_STATIC_CONSTANT(
- bool, value = (
- sizeof(detail::is_other_test(type<T>()))
- == sizeof(detail::yes_other_t)));
- };
-
- template <typename T>
- class unwrap_other
- : public detail::other_unwrapper<
- is_other<T>::value
- >::template apply<T>
- {};
-}
-
-# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
}} // namespace boost::python
diff --git a/boost/python/proxy.hpp b/boost/python/proxy.hpp
index a956eac1cc..d3331d5676 100755..100644
--- a/boost/python/proxy.hpp
+++ b/boost/python/proxy.hpp
@@ -15,11 +15,7 @@ class proxy : public object_operators<proxy<Policies> >
{
typedef typename Policies::key_type key_type;
-# if !defined(BOOST_MSVC) || BOOST_MSVC >= 1300
typedef proxy const& assignment_self;
-# else
- typedef proxy assignment_self;
-# endif
public:
proxy(object const& target, key_type const& key);
operator object() const;
diff --git a/boost/python/ptr.hpp b/boost/python/ptr.hpp
index af1339c426..287daba458 100644
--- a/boost/python/ptr.hpp
+++ b/boost/python/ptr.hpp
@@ -11,9 +11,7 @@
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2001 Peter Dimov
-# if _MSC_VER+0 >= 1020
-# pragma once
-# endif
+# pragma once
# include <boost/config.hpp>
# include <boost/mpl/bool.hpp>
@@ -38,7 +36,6 @@ inline pointer_wrapper<T> ptr(T t)
return pointer_wrapper<T>(t);
}
-# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<typename T>
class is_pointer_wrapper
: public mpl::false_
@@ -64,64 +61,6 @@ class unwrap_pointer<pointer_wrapper<T> >
public:
typedef T type;
};
-# else // no partial specialization
-
-}} // namespace boost::python
-
-#include <boost/type.hpp>
-
-namespace boost { namespace python {
-
-namespace detail
-{
- typedef char (&yes_pointer_wrapper_t)[1];
- typedef char (&no_pointer_wrapper_t)[2];
-
- no_pointer_wrapper_t is_pointer_wrapper_test(...);
-
- template<typename T>
- yes_pointer_wrapper_t is_pointer_wrapper_test(boost::type< pointer_wrapper<T> >);
-
- template<bool wrapped>
- struct pointer_unwrapper
- {
- template <class T>
- struct apply
- {
- typedef T type;
- };
- };
-
- template<>
- struct pointer_unwrapper<true>
- {
- template <class T>
- struct apply
- {
- typedef typename T::type type;
- };
- };
-}
-
-template<typename T>
-class is_pointer_wrapper
-{
- public:
- BOOST_STATIC_CONSTANT(
- bool, value = (
- sizeof(detail::is_pointer_wrapper_test(boost::type<T>()))
- == sizeof(detail::yes_pointer_wrapper_t)));
- typedef mpl::bool_<value> type;
-};
-
-template <typename T>
-class unwrap_pointer
- : public detail::pointer_unwrapper<
- is_pointer_wrapper<T>::value
- >::template apply<T>
-{};
-
-# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
}} // namespace boost::python
diff --git a/boost/python/pure_virtual.hpp b/boost/python/pure_virtual.hpp
index b3b34ffcdb..58e9aedef1 100755..100644
--- a/boost/python/pure_virtual.hpp
+++ b/boost/python/pure_virtual.hpp
@@ -47,7 +47,7 @@ namespace detail
// replaced by void, and whose first argument is replaced by C&.
template <class C, class S>
typename replace_front2<S,void,C&>::type
- error_signature(S BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(C))
+ error_signature(S)
{
typedef typename replace_front2<S,void,C&>::type r;
return r();
diff --git a/boost/python/reference_existing_object.hpp b/boost/python/reference_existing_object.hpp
index bb8ddf7380..8c2410715b 100644
--- a/boost/python/reference_existing_object.hpp
+++ b/boost/python/reference_existing_object.hpp
@@ -17,7 +17,7 @@ namespace detail
{
template <class R>
struct reference_existing_object_requires_a_pointer_or_reference_return_type
-# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
+# if defined(__GNUC__) || defined(__EDG__)
{}
# endif
;
diff --git a/boost/python/register_ptr_to_python.hpp b/boost/python/register_ptr_to_python.hpp
index 7a22fe5052..d39bd0cf71 100644
--- a/boost/python/register_ptr_to_python.hpp
+++ b/boost/python/register_ptr_to_python.hpp
@@ -12,7 +12,7 @@
namespace boost { namespace python {
template <class P>
-void register_ptr_to_python(BOOST_EXPLICIT_TEMPLATE_TYPE(P))
+void register_ptr_to_python()
{
typedef typename boost::python::pointee<P>::type X;
objects::class_value_wrapper<
diff --git a/boost/python/return_arg.hpp b/boost/python/return_arg.hpp
index c36f898d7d..e869a58d12 100755..100644
--- a/boost/python/return_arg.hpp
+++ b/boost/python/return_arg.hpp
@@ -29,7 +29,7 @@ namespace detail
{
template <std::size_t>
struct return_arg_pos_argument_must_be_positive
-# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
+# if defined(__GNUC__) || defined(__EDG__)
{}
# endif
;
diff --git a/boost/python/return_internal_reference.hpp b/boost/python/return_internal_reference.hpp
index acb89e6dc8..cc60f4422a 100644
--- a/boost/python/return_internal_reference.hpp
+++ b/boost/python/return_internal_reference.hpp
@@ -18,7 +18,7 @@ namespace detail
{
template <std::size_t>
struct return_internal_reference_owner_arg_must_be_greater_than_zero
-# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
+# if defined(__GNUC__) || defined(__EDG__)
{}
# endif
;
diff --git a/boost/python/suite/indexing/indexing_suite.hpp b/boost/python/suite/indexing/indexing_suite.hpp
index b636b2111c..40301fdff5 100644
--- a/boost/python/suite/indexing/indexing_suite.hpp
+++ b/boost/python/suite/indexing/indexing_suite.hpp
@@ -131,11 +131,7 @@ namespace boost { namespace python {
typedef detail::container_element<Container, Index, DerivedPolicies>
container_element_t;
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
- struct return_policy : return_internal_reference<> {};
-#else
typedef return_internal_reference<> return_policy;
-#endif
typedef typename mpl::if_<
no_proxy
diff --git a/boost/python/to_python_converter.hpp b/boost/python/to_python_converter.hpp
index 378d159e97..4391b6dce9 100644
--- a/boost/python/to_python_converter.hpp
+++ b/boost/python/to_python_converter.hpp
@@ -48,12 +48,7 @@ template < class T, class Conversion, bool has_get_pytype=false >
struct to_python_converter
{
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
-#if 0 //defined _MSC_VER && _MSC_VER >=1310
- //probably other compilers could come here as well
- typedef typename detail::test_get_pytype<Conversion> HasGetPytype;
-#else
typedef boost::mpl::bool_<has_get_pytype> HasGetPytype;
-#endif
static PyTypeObject const* get_pytype_1(boost::mpl::true_ *)
{
diff --git a/boost/python/to_python_value.hpp b/boost/python/to_python_value.hpp
index a48948d256..aaabb9cf75 100644
--- a/boost/python/to_python_value.hpp
+++ b/boost/python/to_python_value.hpp
@@ -147,11 +147,6 @@ namespace detail
template <class T>
inline PyObject* registry_to_python_value<T>::operator()(argument_type x) const
{
- typedef converter::registered<argument_type> r;
-# if BOOST_WORKAROUND(__GNUC__, < 3)
- // suppresses an ICE, somehow
- (void)r::converters;
-# endif
return converter::registered<argument_type>::converters.to_python(&x);
}
diff --git a/boost/python/type_id.hpp b/boost/python/type_id.hpp
index 4a5727d514..38b7f7b453 100644
--- a/boost/python/type_id.hpp
+++ b/boost/python/type_id.hpp
@@ -15,11 +15,9 @@
# include <boost/static_assert.hpp>
# include <boost/detail/workaround.hpp>
# include <boost/type_traits/same_traits.hpp>
-# include <boost/type_traits/broken_compiler_spec.hpp>
# ifndef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
# if defined(__GNUC__) \
- && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) \
&& !defined(__EDG_VERSION__)
# define BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
# endif
@@ -30,7 +28,7 @@ namespace boost { namespace python {
// for this compiler at least, cross-shared-library type_info
// comparisons don't work, so use typeid(x).name() instead. It's not
// yet clear what the best default strategy is.
-# if (defined(__GNUC__) && __GNUC__ >= 3) \
+# if defined(__GNUC__) \
|| defined(_AIX) \
|| ( defined(__sgi) && defined(__host_mips)) \
|| (defined(__hpux) && defined(__HP_aCC)) \
@@ -69,21 +67,18 @@ struct type_info : private totally_ordered<type_info>
base_id_t m_base_type;
};
-# ifdef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
-# define BOOST_PYTHON_EXPLICIT_TT_DEF(T) ::boost::type<T>*
-# else
-# define BOOST_PYTHON_EXPLICIT_TT_DEF(T)
-# endif
+
+// This macro is obsolete. Port away and remove.
+# define BOOST_PYTHON_EXPLICIT_TT_DEF(T)
template <class T>
-inline type_info type_id(BOOST_EXPLICIT_TEMPLATE_TYPE(T))
+inline type_info type_id()
{
return type_info(
# if !defined(_MSC_VER) \
- || (!BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
- && !BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700))
+ || !BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700)
typeid(T)
-# else // strip the decoration which msvc and Intel mistakenly leave in
+# else // strip the decoration which Intel mistakenly leaves in
python::detail::msvc_typeid((boost::type<T>*)0)
# endif
);
@@ -99,7 +94,7 @@ inline type_info type_id(BOOST_EXPLICIT_TEMPLATE_TYPE(T))
# define BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(T) \
template <> \
-inline type_info type_id<T>(BOOST_PYTHON_EXPLICIT_TT_DEF(T)) \
+inline type_info type_id<T>() \
{ \
return type_info(typeid(T)); \
}
@@ -171,22 +166,19 @@ inline char const* type_info::name() const
BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_info const&);
-# if !BOOST_WORKAROUND(BOOST_MSVC, == 1200)
template<>
-inline type_info type_id<void>(BOOST_PYTHON_EXPLICIT_TT_DEF(void))
+inline type_info type_id<void>()
{
return type_info (typeid (void *));
}
# ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
template<>
-inline type_info type_id<const volatile void>(BOOST_PYTHON_EXPLICIT_TT_DEF(const volatile void))
+inline type_info type_id<const volatile void>()
{
return type_info (typeid (void *));
}
# endif
-# endif
-
}} // namespace boost::python
#endif // TYPE_ID_DWA2002517_HPP
diff --git a/boost/python/with_custodian_and_ward.hpp b/boost/python/with_custodian_and_ward.hpp
index 9399478f23..3431c6f22c 100644
--- a/boost/python/with_custodian_and_ward.hpp
+++ b/boost/python/with_custodian_and_ward.hpp
@@ -85,14 +85,10 @@ struct with_custodian_and_ward_postcall : BasePolicy_
static PyObject* postcall(ArgumentPackage const& args_, PyObject* result)
{
std::size_t arity_ = detail::arity(args_);
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
- if ( custodian > arity_ || ward > arity_ )
-#else
// check if either custodian or ward exceeds the arity
// (this weird formulation avoids "always false" warnings
// for arity_ = 0)
if ( (std::max)(custodian, ward) > arity_ )
-#endif
{
PyErr_SetString(
PyExc_IndexError
diff --git a/boost/range/adaptor/filtered.hpp b/boost/range/adaptor/filtered.hpp
index b6d3ab1927..1fb778e58d 100644
--- a/boost/range/adaptor/filtered.hpp
+++ b/boost/range/adaptor/filtered.hpp
@@ -56,23 +56,23 @@ namespace boost
{ }
};
- template< class ForwardRange, class Predicate >
- inline filtered_range<Predicate, ForwardRange>
- operator|(ForwardRange& r,
+ template< class SinglePassRange, class Predicate >
+ inline filtered_range<Predicate, SinglePassRange>
+ operator|(SinglePassRange& r,
const filter_holder<Predicate>& f)
{
- BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
- return filtered_range<Predicate, ForwardRange>( f.val, r );
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange>));
+ return filtered_range<Predicate, SinglePassRange>( f.val, r );
}
- template< class ForwardRange, class Predicate >
- inline filtered_range<Predicate, const ForwardRange>
- operator|(const ForwardRange& r,
+ template< class SinglePassRange, class Predicate >
+ inline filtered_range<Predicate, const SinglePassRange>
+ operator|(const SinglePassRange& r,
const filter_holder<Predicate>& f )
{
BOOST_RANGE_CONCEPT_ASSERT((
- ForwardRangeConcept<const ForwardRange>));
- return filtered_range<Predicate, const ForwardRange>( f.val, r );
+ SinglePassRangeConcept<const SinglePassRange>));
+ return filtered_range<Predicate, const SinglePassRange>( f.val, r );
}
} // 'range_detail'
@@ -93,23 +93,26 @@ namespace boost
range_detail::forwarder<range_detail::filter_holder>();
}
- template<class ForwardRange, class Predicate>
- inline filtered_range<Predicate, ForwardRange>
- filter(ForwardRange& rng, Predicate filter_pred)
+ template<class SinglePassRange, class Predicate>
+ inline filtered_range<Predicate, SinglePassRange>
+ filter(SinglePassRange& rng, Predicate filter_pred)
{
- BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((
+ SinglePassRangeConcept<SinglePassRange>));
- return range_detail::filtered_range<Predicate, ForwardRange>( filter_pred, rng );
+ return range_detail::filtered_range<
+ Predicate, SinglePassRange>( filter_pred, rng );
}
- template<class ForwardRange, class Predicate>
- inline filtered_range<Predicate, const ForwardRange>
- filter(const ForwardRange& rng, Predicate filter_pred)
+ template<class SinglePassRange, class Predicate>
+ inline filtered_range<Predicate, const SinglePassRange>
+ filter(const SinglePassRange& rng, Predicate filter_pred)
{
BOOST_RANGE_CONCEPT_ASSERT((
- ForwardRangeConcept<const ForwardRange>));
+ SinglePassRangeConcept<const SinglePassRange>));
- return range_detail::filtered_range<Predicate, const ForwardRange>( filter_pred, rng );
+ return range_detail::filtered_range<
+ Predicate, const SinglePassRange>( filter_pred, rng );
}
} // 'adaptors'
diff --git a/boost/range/adaptor/strided.hpp b/boost/range/adaptor/strided.hpp
index c5fea86d5c..560b8200c7 100644
--- a/boost/range/adaptor/strided.hpp
+++ b/boost/range/adaptor/strided.hpp
@@ -603,7 +603,7 @@ namespace boost
template<
class Rng,
class Category =
- typename iterator_traversal<
+ typename iterators::pure_iterator_traversal<
typename range_iterator<Rng>::type
>::type
>
diff --git a/boost/range/detail/common.hpp b/boost/range/detail/common.hpp
index b0ad535775..00b665bef8 100644
--- a/boost/range/detail/common.hpp
+++ b/boost/range/detail/common.hpp
@@ -18,9 +18,10 @@
#include <boost/range/config.hpp>
#include <boost/range/detail/sfinae.hpp>
#include <boost/type_traits/is_void.hpp>
-#include <boost/type_traits/detail/ice_or.hpp>
+#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp>
+#include <boost/mpl/or.hpp>
#include <cstddef>
//////////////////////////////////////////////////////////////////////////////
@@ -70,7 +71,7 @@ namespace boost
BOOST_STATIC_CONSTANT( bool, is_const_wchar_t_ptr_ = sizeof( boost::range_detail::is_const_wchar_t_ptr_impl( ptr ) ) == sizeof( yes_type ) );
BOOST_STATIC_CONSTANT( bool, is_char_array_ = sizeof( boost::range_detail::is_char_array_impl( ptr ) ) == sizeof( yes_type ) );
BOOST_STATIC_CONSTANT( bool, is_wchar_t_array_ = sizeof( boost::range_detail::is_wchar_t_array_impl( ptr ) ) == sizeof( yes_type ) );
- BOOST_STATIC_CONSTANT( bool, is_string_ = (boost::type_traits::ice_or<is_const_char_ptr_, is_const_wchar_t_ptr_>::value ));
+ BOOST_STATIC_CONSTANT( bool, is_string_ = (boost::mpl::or_<boost::mpl::bool_<is_const_char_ptr_>, boost::mpl::bool_<is_const_wchar_t_ptr_> >::value ));
BOOST_STATIC_CONSTANT( bool, is_array_ = boost::is_array<C>::value );
};
diff --git a/boost/range/difference_type.hpp b/boost/range/difference_type.hpp
index afd8b07cc0..6bb3c5f552 100644
--- a/boost/range/difference_type.hpp
+++ b/boost/range/difference_type.hpp
@@ -15,20 +15,32 @@
# pragma once
#endif
+#include <boost/mpl/and.hpp>
#include <boost/range/config.hpp>
#include <boost/range/iterator.hpp>
+#include <boost/range/has_range_iterator.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/type_traits/remove_reference.hpp>
namespace boost
{
+ namespace range_detail
+ {
+ template< class T, bool B = has_type<range_iterator<T> >::value >
+ struct range_difference
+ { };
+
+ template< class T >
+ struct range_difference<T, true>
+ : iterator_difference<
+ BOOST_DEDUCED_TYPENAME range_iterator<T>::type
+ >
+ { };
+ }
+
template< class T >
struct range_difference
- : iterator_difference<
- BOOST_DEDUCED_TYPENAME range_iterator<
- BOOST_DEDUCED_TYPENAME remove_reference<T>::type
- >::type
- >
+ : range_detail::range_difference<BOOST_DEDUCED_TYPENAME remove_reference<T>::type>
{ };
}
diff --git a/boost/range/iterator.hpp b/boost/range/iterator.hpp
index f15bf3b342..2956353ab5 100644
--- a/boost/range/iterator.hpp
+++ b/boost/range/iterator.hpp
@@ -46,31 +46,29 @@ namespace boost
};
}
-#endif
-
template< typename C, typename Enabler=void >
struct range_iterator
{
-#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
-
+
typedef BOOST_RANGE_DEDUCED_TYPENAME
range_detail_vc7_1::range_iterator<C>::type type;
-
-#else
- private:
- typedef typename remove_reference<C>::type param_t;
+ };
+
+#else
- public:
- typedef typename mpl::eval_if_c<
- is_const<param_t>::value,
- range_const_iterator<typename remove_const<param_t>::type>,
- range_mutable_iterator<param_t>
- >::type type;
-
-#endif
+ template< typename C, typename Enabler=void >
+ struct range_iterator
+ : mpl::if_c<
+ is_const<typename remove_reference<C>::type>::value,
+ range_const_iterator<typename remove_const<typename remove_reference<C>::type>::type>,
+ range_mutable_iterator<typename remove_reference<C>::type>
+ >::type
+ {
};
-
+
+#endif
+
} // namespace boost
#endif
diff --git a/boost/range/iterator_range_core.hpp b/boost/range/iterator_range_core.hpp
index 2fbeb686e2..a9e9fc0f13 100644
--- a/boost/range/iterator_range_core.hpp
+++ b/boost/range/iterator_range_core.hpp
@@ -66,13 +66,13 @@ namespace boost
template< class ForwardRange >
static IteratorT adl_begin( ForwardRange& r )
{
- return static_cast<IteratorT>( boost::begin( r ) );
+ return IteratorT( boost::begin( r ) );
}
template< class ForwardRange >
static IteratorT adl_end( ForwardRange& r )
{
- return static_cast<IteratorT>( boost::end( r ) );
+ return IteratorT( boost::end( r ) );
}
};
diff --git a/boost/range/size.hpp b/boost/range/size.hpp
index d007bfca44..7f38db8c1e 100644
--- a/boost/range/size.hpp
+++ b/boost/range/size.hpp
@@ -54,11 +54,20 @@ namespace boost
inline typename range_size<const SinglePassRange>::type
size(const SinglePassRange& rng)
{
+// Very strange things happen on some compilers that have the range concept
+// asserts disabled. This preprocessor condition is clearly redundant on a
+// working compiler but is vital for at least some compilers such as clang 4.2
+// but only on the Mac!
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT == 1
+ BOOST_RANGE_CONCEPT_ASSERT((boost::SinglePassRangeConcept<SinglePassRange>));
+#endif
+
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
!BOOST_WORKAROUND(__GNUC__, < 3) \
/**/
using namespace range_detail;
#endif
+
return range_calculate_size(rng);
}
diff --git a/boost/range/size_type.hpp b/boost/range/size_type.hpp
index db5a59b5ee..f41c32128d 100644
--- a/boost/range/size_type.hpp
+++ b/boost/range/size_type.hpp
@@ -18,6 +18,7 @@
#include <boost/range/config.hpp>
#include <boost/range/difference_type.hpp>
#include <boost/range/concepts.hpp>
+#include <boost/range/has_range_iterator.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/make_unsigned.hpp>
@@ -51,7 +52,7 @@ namespace boost
};
template<typename C, typename Enabler=void>
- struct range_size
+ struct range_size_
{
typedef BOOST_DEDUCED_TYPENAME make_unsigned<
BOOST_DEDUCED_TYPENAME range_difference<C>::type
@@ -59,7 +60,7 @@ namespace boost
};
template<typename C>
- struct range_size<
+ struct range_size_<
C,
BOOST_DEDUCED_TYPENAME ::boost::enable_if<has_size_type<C>, void>::type
>
@@ -67,29 +68,25 @@ namespace boost
typedef BOOST_DEDUCED_TYPENAME C::size_type type;
};
+ template<typename C, bool B = range_detail::has_type< range_iterator<C> >::value>
+ struct range_size
+ { };
+
+ template<typename C>
+ struct range_size<C, true>
+ : range_size_<C>
+ { };
}
template< class T >
struct range_size :
detail::range_size<T>
- {
-// Very strange things happen on some compilers that have the range concept
-// asserts disabled. This preprocessor condition is clearly redundant on a
-// working compiler but is vital for at least some compilers such as clang 4.2
-// but only on the Mac!
-#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT == 1
- BOOST_RANGE_CONCEPT_ASSERT((boost::SinglePassRangeConcept<T>));
-#endif
- };
+ { };
template< class T >
- struct range_size<const T >
- : detail::range_size<T>
- {
-#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT == 1
- BOOST_RANGE_CONCEPT_ASSERT((boost::SinglePassRangeConcept<T>));
-#endif
- };
+ struct range_size<const T > :
+ detail::range_size<T>
+ { };
} // namespace boost
diff --git a/boost/range/sub_range.hpp b/boost/range/sub_range.hpp
index 8d5d168ce9..d1c3b99b0d 100644
--- a/boost/range/sub_range.hpp
+++ b/boost/range/sub_range.hpp
@@ -182,8 +182,8 @@ public:
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) )
sub_range(const sub_range& r)
- : base(impl::adl_begin(static_cast<const base&>(r)),
- impl::adl_end(static_cast<const base&>(r)))
+ : base(impl::adl_begin(const_cast<base&>(static_cast<const base&>(r))),
+ impl::adl_end(const_cast<base&>(static_cast<const base&>(r))))
{ }
#endif
diff --git a/boost/serialization/access.hpp b/boost/serialization/access.hpp
index ec88ff5aca..f6581accc9 100644
--- a/boost/serialization/access.hpp
+++ b/boost/serialization/access.hpp
@@ -18,8 +18,6 @@
#include <boost/config.hpp>
-#include <boost/serialization/pfto.hpp>
-
namespace boost {
namespace archive {
@@ -66,19 +64,19 @@ public:
friend inline void serialize(
Archive & ar,
T & t,
- const BOOST_PFTO unsigned int file_version
+ const unsigned int file_version
);
template<class Archive, class T>
friend inline void save_construct_data(
Archive & ar,
const T * t,
- const BOOST_PFTO unsigned int file_version
+ const unsigned int file_version
);
template<class Archive, class T>
friend inline void load_construct_data(
Archive & ar,
T * t,
- const BOOST_PFTO unsigned int file_version
+ const unsigned int file_version
);
#endif
diff --git a/boost/serialization/array.hpp b/boost/serialization/array.hpp
index 35c640ce45..97ac0c2501 100644
--- a/boost/serialization/array.hpp
+++ b/boost/serialization/array.hpp
@@ -33,17 +33,8 @@ namespace boost { namespace serialization {
// traits to specify whether to use an optimized array serialization
-#ifdef __BORLANDC__
-// workaround for Borland compiler
-template <class Archive>
-struct use_array_optimization {
- template <class T> struct apply : boost::mpl::false_ {};
-};
-
-#else
template <class Archive>
struct use_array_optimization : boost::mpl::always<boost::mpl::false_> {};
-#endif
template<class T>
class array :
@@ -125,10 +116,7 @@ private:
template<class T>
inline
-#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-const
-#endif
-array< T > make_array( T* t, std::size_t s){
+const array< T > make_array( T* t, std::size_t s){
return array< T >(t, s);
}
@@ -154,10 +142,6 @@ void serialize(Archive& ar, std::array<T,N>& a, const unsigned int /* version */
} } // end namespace boost::serialization
-#ifdef __BORLANDC__
-// ignore optimizations for Borland
-#define BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(Archive)
-#else
#define BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(Archive) \
namespace boost { namespace serialization { \
template <> struct use_array_optimization<Archive> { \
@@ -166,6 +150,5 @@ template <> struct use_array_optimization<Archive> { \
, typename boost::remove_const<ValueType>::type \
>::type {}; \
}; }}
-#endif // __BORLANDC__
#endif //BOOST_SERIALIZATION_ARRAY_HPP
diff --git a/boost/serialization/base_object.hpp b/boost/serialization/base_object.hpp
index 562dbd5061..7ede6473e0 100644
--- a/boost/serialization/base_object.hpp
+++ b/boost/serialization/base_object.hpp
@@ -84,16 +84,6 @@ namespace detail
};
} // namespace detail
-#if defined(__BORLANDC__) && __BORLANDC__ < 0x610
-template<class Base, class Derived>
-const Base &
-base_object(const Derived & d)
-{
- BOOST_STATIC_ASSERT(! is_pointer<Derived>::value);
- detail::base_register<Base, Derived>::invoke();
- return access::cast_reference<const Base, Derived>(d);
-}
-#else
template<class Base, class Derived>
typename detail::base_cast<Base, Derived>::type &
base_object(Derived &d)
@@ -104,7 +94,6 @@ base_object(Derived &d)
detail::base_register<type, Derived>::invoke();
return access::cast_reference<type, Derived>(d);
}
-#endif
} // namespace serialization
} // namespace boost
diff --git a/boost/serialization/binary_object.hpp b/boost/serialization/binary_object.hpp
index 7e2307680e..23c734be3d 100644
--- a/boost/serialization/binary_object.hpp
+++ b/boost/serialization/binary_object.hpp
@@ -68,10 +68,7 @@ struct binary_object :
// just a little helper to support the convention that all serialization
// wrappers follow the naming convention make_xxxxx
inline
-#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-const
-#endif
-binary_object
+const binary_object
make_binary_object(/* const */ void * t, std::size_t size){
return binary_object(t, size);
}
diff --git a/boost/serialization/collections_load_imp.hpp b/boost/serialization/collections_load_imp.hpp
index 2291e74226..246b64ed65 100644
--- a/boost/serialization/collections_load_imp.hpp
+++ b/boost/serialization/collections_load_imp.hpp
@@ -38,6 +38,8 @@ namespace std{
#include <boost/serialization/detail/stack_constructor.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/serialization/item_version_type.hpp>
+#include <boost/serialization/detail/is_default_constructible.hpp>
+#include <boost/utility/enable_if.hpp>
namespace boost{
namespace serialization {
@@ -47,116 +49,53 @@ namespace stl {
// implementation of serialization for STL containers
//
-// sequential container input
-template<class Archive, class Container>
-struct archive_input_seq
-{
- inline typename Container::iterator
- operator()(
- Archive &ar,
- Container &s,
- const unsigned int v,
- typename Container::iterator hint
- ){
- typedef typename Container::value_type type;
- detail::stack_construct<Archive, type> t(ar, v);
- // borland fails silently w/o full namespace
- ar >> boost::serialization::make_nvp("item", t.reference());
- s.push_back(t.reference());
- ar.reset_object_address(& s.back() , & t.reference());
- return hint;
- }
-};
-
-// map input
-template<class Archive, class Container>
-struct archive_input_map
-{
- inline typename Container::iterator
- operator()(
- Archive &ar,
- Container &s,
- const unsigned int v,
- typename Container::iterator hint
- ){
- typedef typename Container::value_type type;
- detail::stack_construct<Archive, type> t(ar, v);
- // borland fails silently w/o full namespace
- ar >> boost::serialization::make_nvp("item", t.reference());
- typename Container::iterator result =
- s.insert(hint, t.reference());
- // note: the following presumes that the map::value_type was NOT tracked
- // in the archive. This is the usual case, but here there is no way
- // to determine that.
- ar.reset_object_address(
- & (result->second),
- & t.reference().second
- );
- return result;
- }
-};
-
-// set input
-template<class Archive, class Container>
-struct archive_input_set
-{
- inline typename Container::iterator
- operator()(
- Archive &ar,
- Container &s,
- const unsigned int v,
- typename Container::iterator hint
- ){
- typedef typename Container::value_type type;
- detail::stack_construct<Archive, type> t(ar, v);
- // borland fails silently w/o full namespace
- ar >> boost::serialization::make_nvp("item", t.reference());
- typename Container::iterator result =
- s.insert(hint, t.reference());
- ar.reset_object_address(& (* result), & t.reference());
- return result;
- }
-};
-
-template<class Container>
-class reserve_imp
-{
-public:
- void operator()(Container &s, std::size_t count) const {
- s.reserve(count);
- }
-};
-
-template<class Container>
-class no_reserve_imp
-{
-public:
- void operator()(Container & /* s */, std::size_t /* count */) const{}
-};
-
-template<class Archive, class Container, class InputFunction, class R>
-inline void load_collection(Archive & ar, Container &s)
-{
- s.clear();
- const boost::archive::library_version_type library_version(
- ar.get_library_version()
- );
- // retrieve number of elements
- item_version_type item_version(0);
- collection_size_type count;
- ar >> BOOST_SERIALIZATION_NVP(count);
- if(boost::archive::library_version_type(3) < library_version){
- ar >> BOOST_SERIALIZATION_NVP(item_version);
+template<
+ class Archive,
+ class T
+>
+typename boost::enable_if<
+ typename detail::is_default_constructible<
+ typename T::value_type
+ >,
+ void
+>::type
+collection_load_impl(
+ Archive & ar,
+ T & t,
+ collection_size_type count,
+ item_version_type item_version
+){
+ t.resize(count);
+ typename T::iterator hint;
+ hint = t.begin();
+ while(count-- > 0){
+ ar >> boost::serialization::make_nvp("item", *hint++);
}
+}
- R rx;
- rx(s, count);
- InputFunction ifunc;
- typename Container::iterator hint;
- hint = s.begin();
+template<
+ class Archive,
+ class T
+>
+typename boost::disable_if<
+ typename detail::is_default_constructible<
+ typename T::value_type
+ >,
+ void
+>::type
+collection_load_impl(
+ Archive & ar,
+ T & t,
+ collection_size_type count,
+ item_version_type item_version
+){
+ t.clear();
while(count-- > 0){
- hint = ifunc(ar, s, item_version, hint);
- }
+ detail::stack_construct<Archive, typename T::value_type> u(ar, item_version);
+ ar >> boost::serialization::make_nvp("item", u.reference());
+ t.push_back(u.reference());
+ ar.reset_object_address(& t.back() , & u.reference());
+ }
}
} // namespace stl
diff --git a/boost/serialization/config.hpp b/boost/serialization/config.hpp
index ce586a7d38..ea8cb9239e 100644
--- a/boost/serialization/config.hpp
+++ b/boost/serialization/config.hpp
@@ -17,7 +17,6 @@
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
-#include <boost/preprocessor/facilities/empty.hpp>
// note: this version incorporates the related code into the the
// the same library as BOOST_ARCHIVE. This could change some day in the
@@ -28,7 +27,6 @@
#undef BOOST_SERIALIZATION_DECL
#endif
-#ifdef BOOST_HAS_DECLSPEC // defined in config system
// 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_SERIALIZATION_DYN_LINK
@@ -39,24 +37,15 @@
#endif
// export if this is our own source, otherwise import:
#if defined(BOOST_SERIALIZATION_SOURCE)
- #if defined(__BORLANDC__)
- #define BOOST_SERIALIZATION_DECL(T) T __export
- #else
- #define BOOST_SERIALIZATION_DECL(T) __declspec(dllexport) T
- #endif
+ #define BOOST_SERIALIZATION_DECL BOOST_SYMBOL_EXPORT
#else
- #if defined(__BORLANDC__)
- #define BOOST_SERIALIZATION_DECL(T) T __import
- #else
- #define BOOST_SERIALIZATION_DECL(T) __declspec(dllimport) T
- #endif
+ #define BOOST_SERIALIZATION_DECL BOOST_SYMBOL_IMPORT
#endif // defined(BOOST_SERIALIZATION_SOURCE)
#endif // defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK)
-#endif // BOOST_HAS_DECLSPEC
// if BOOST_SERIALIZATION_DECL isn't defined yet define it now:
#ifndef BOOST_SERIALIZATION_DECL
- #define BOOST_SERIALIZATION_DECL(T) T
+ #define BOOST_SERIALIZATION_DECL
#endif
// enable automatic library variant selection ------------------------------//
diff --git a/boost/serialization/deque.hpp b/boost/serialization/deque.hpp
index e182f7b67f..f4b58c325f 100644
--- a/boost/serialization/deque.hpp
+++ b/boost/serialization/deque.hpp
@@ -21,8 +21,8 @@
#include <boost/config.hpp>
#include <boost/serialization/collections_save_imp.hpp>
+#include <boost/serialization/collections_load_imp.hpp>
#include <boost/serialization/detail/stack_constructor.hpp>
-#include <boost/serialization/detail/is_default_constructible.hpp>
#include <boost/serialization/split_free.hpp>
namespace boost {
@@ -43,7 +43,7 @@ template<class Archive, class U, class Allocator>
inline void load(
Archive & ar,
std::deque<U, Allocator> &t,
- const unsigned int /*file_version*/
+ const unsigned int /* file_version */
){
const boost::archive::library_version_type library_version(
ar.get_library_version()
@@ -55,23 +55,7 @@ inline void load(
if(boost::archive::library_version_type(3) < library_version){
ar >> BOOST_SERIALIZATION_NVP(item_version);
}
- if(detail::is_default_constructible<U>()){
- t.resize(count);
- typename std::deque<U, Allocator>::iterator hint;
- hint = t.begin();
- while(count-- > 0){
- ar >> boost::serialization::make_nvp("item", *hint++);
- }
- }
- else{
- t.clear();
- while(count-- > 0){
- detail::stack_construct<Archive, U> u(ar, item_version);
- ar >> boost::serialization::make_nvp("item", u.reference());
- t.push_back(u.reference());
- ar.reset_object_address(& t.back() , & u.reference());
- }
- }
+ stl::collection_load_impl(ar, t, count, item_version);
}
// split non-intrusive serialization function member into separate
diff --git a/boost/serialization/detail/is_default_constructible.hpp b/boost/serialization/detail/is_default_constructible.hpp
index d928e69341..451cca4d6f 100644
--- a/boost/serialization/detail/is_default_constructible.hpp
+++ b/boost/serialization/detail/is_default_constructible.hpp
@@ -16,7 +16,10 @@
// See http://www.boost.org for updates, documentation, and revision history.
-#ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS
+#include <boost/config.hpp>
+
+#if defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 1101) \
+|| ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
#include <type_traits>
namespace boost{
namespace serialization {
diff --git a/boost/serialization/detail/shared_count_132.hpp b/boost/serialization/detail/shared_count_132.hpp
index a63e48849b..a5872557cf 100644
--- a/boost/serialization/detail/shared_count_132.hpp
+++ b/boost/serialization/detail/shared_count_132.hpp
@@ -45,11 +45,6 @@ namespace std{
} // namespace std
#endif
-#ifdef __BORLANDC__
-# pragma warn -8026 // Functions with excep. spec. are not expanded inline
-# pragma warn -8027 // Functions containing try are not expanded inline
-#endif
-
namespace boost_132 {
// Debug hooks
@@ -71,10 +66,6 @@ void sp_array_destructor_hook(void * px);
// Hence, the temporary #pragma option -pc below. The version
// check is deliberately conservative.
-#if defined(__BORLANDC__) && __BORLANDC__ == 0x551
-# pragma option push -pc
-#endif
-
class bad_weak_ptr: public std::exception
{
public:
@@ -85,10 +76,6 @@ public:
}
};
-#if defined(__BORLANDC__) && __BORLANDC__ == 0x551
-# pragma option pop
-#endif
-
namespace detail{
class sp_counted_base
@@ -201,12 +188,12 @@ public:
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
-template<class T> void cbi_call_constructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &, int)
+template<class T> void cbi_call_constructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &)
{
boost::sp_scalar_constructor_hook(px, sizeof(T), pn);
}
-template<class T> void cbi_call_constructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &, int)
+template<class T> void cbi_call_constructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &)
{
boost::sp_array_constructor_hook(px);
}
@@ -215,12 +202,12 @@ template<class P, class D> void cbi_call_constructor_hook(sp_counted_base *, P c
{
}
-template<class T> void cbi_call_destructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &, int)
+template<class T> void cbi_call_destructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &)
{
boost::sp_scalar_destructor_hook(px, sizeof(T), pn);
}
-template<class T> void cbi_call_destructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &, int)
+template<class T> void cbi_call_destructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &)
{
boost::sp_array_destructor_hook(px);
}
@@ -561,9 +548,4 @@ inline shared_count::shared_count(weak_count const & r): pi_(r.pi_)
BOOST_SERIALIZATION_ASSUME_ABSTRACT(boost_132::detail::sp_counted_base)
-#ifdef __BORLANDC__
-# pragma warn .8027 // Functions containing try are not expanded inline
-# pragma warn .8026 // Functions with excep. spec. are not expanded inline
-#endif
-
#endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
diff --git a/boost/serialization/detail/shared_ptr_132.hpp b/boost/serialization/detail/shared_ptr_132.hpp
index 969b53a77b..ee98b7b944 100644
--- a/boost/serialization/detail/shared_ptr_132.hpp
+++ b/boost/serialization/detail/shared_ptr_132.hpp
@@ -120,13 +120,8 @@ public:
{
}
-#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x564) )
template<class Y>
explicit shared_ptr(Y * p): px(p), pn(p, boost::checked_deleter<Y>()) // Y must be complete
-#else
- template<class Y>
- explicit shared_ptr(Y * p): px(p), pn(p, boost::checked_deleter<Y>()) // Y must be complete
-#endif
{
detail::sp_enable_shared_from_this( pn, p, p );
}
@@ -145,15 +140,13 @@ public:
// generated copy constructor, assignment, destructor are fine...
// except that Borland C++ has a bug, and g++ with -Wsynth warns
-#if defined(__BORLANDC__) || defined(__GNUC__)
-
+#if defined(__GNUC__)
shared_ptr & operator=(shared_ptr const & r) // never throws
{
px = r.px;
pn = r.pn; // shared_count::op= doesn't throw
return *this;
}
-
#endif
template<class Y>
diff --git a/boost/serialization/detail/stack_constructor.hpp b/boost/serialization/detail/stack_constructor.hpp
index 70a80296b7..9027717a92 100644
--- a/boost/serialization/detail/stack_constructor.hpp
+++ b/boost/serialization/detail/stack_constructor.hpp
@@ -36,11 +36,7 @@ struct stack_allocate
private:
typedef typename boost::aligned_storage<
sizeof(T),
- #if BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x560))
- 8
- #else
- boost::alignment_of<T>::value
- #endif
+ boost::alignment_of<T>::value
> type;
type storage_;
};
diff --git a/boost/serialization/ephemeral.hpp b/boost/serialization/ephemeral.hpp
index b913fef0b2..09e5016124 100644
--- a/boost/serialization/ephemeral.hpp
+++ b/boost/serialization/ephemeral.hpp
@@ -63,10 +63,7 @@ private:
template<class T>
inline
-#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-const
-#endif
-ephemeral_object<T> ephemeral(const char * name, T & t){
+const ephemeral_object<T> ephemeral(const char * name, T & t){
return ephemeral_object<T>(name, t);
}
diff --git a/boost/serialization/export.hpp b/boost/serialization/export.hpp
index 99354782aa..9da9434a5f 100644
--- a/boost/serialization/export.hpp
+++ b/boost/serialization/export.hpp
@@ -86,9 +86,6 @@ struct ptr_serialization_support
{
# if defined(BOOST_MSVC) || defined(__SUNPRO_CC)
virtual BOOST_DLLEXPORT void instantiate() BOOST_USED;
-# elif defined(__BORLANDC__)
- static BOOST_DLLEXPORT void instantiate() BOOST_USED;
- enum { x = sizeof(instantiate(),3) };
# else
static BOOST_DLLEXPORT void instantiate() BOOST_USED;
typedef instantiate_function<
@@ -102,17 +99,11 @@ BOOST_DLLEXPORT void
ptr_serialization_support<Archive,Serializable>::instantiate()
{
export_impl<Archive,Serializable>::enable_save(
- #if ! defined(__BORLANDC__)
- typename
- #endif
- Archive::is_saving()
+ typename Archive::is_saving()
);
export_impl<Archive,Serializable>::enable_load(
- #if ! defined(__BORLANDC__)
- typename
- #endif
- Archive::is_loading()
+ typename Archive::is_loading()
);
}
diff --git a/boost/serialization/extended_type_info.hpp b/boost/serialization/extended_type_info.hpp
index d4b57afa61..c96a576e60 100644
--- a/boost/serialization/extended_type_info.hpp
+++ b/boost/serialization/extended_type_info.hpp
@@ -41,7 +41,7 @@ namespace void_cast_detail{
class void_caster;
}
-class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) extended_type_info :
+class BOOST_SYMBOL_VISIBLE extended_type_info :
private boost::noncopyable
{
private:
@@ -56,12 +56,12 @@ private:
const char * m_key;
protected:
- void key_unregister() const;
- void key_register() const;
+ BOOST_SERIALIZATION_DECL void key_unregister() const;
+ BOOST_SERIALIZATION_DECL void key_register() const;
// this class can't be used as is. It's just the
// common functionality for all type_info replacement
// systems. Hence, make these protected
- extended_type_info(
+ BOOST_SERIALIZATION_DECL extended_type_info(
const unsigned int type_info_key,
const char * key
);
@@ -69,20 +69,20 @@ protected:
#if defined(__GNUC__)
virtual
#endif
- ~extended_type_info();
+ BOOST_SERIALIZATION_DECL ~extended_type_info();
public:
const char * get_key() const {
return m_key;
}
virtual const char * get_debug_info() const = 0;
- bool operator<(const extended_type_info &rhs) const;
- bool operator==(const extended_type_info &rhs) const;
+ BOOST_SERIALIZATION_DECL bool operator<(const extended_type_info &rhs) const;
+ BOOST_SERIALIZATION_DECL bool operator==(const extended_type_info &rhs) const;
bool operator!=(const extended_type_info &rhs) const {
return !(operator==(rhs));
}
// note explicit "export" of static function to work around
// gcc 4.5 mingw error
- static const extended_type_info *
+ static BOOST_SERIALIZATION_DECL const extended_type_info *
find(const char *key);
// for plugins
virtual void * construct(unsigned int /*count*/ = 0, ...) const = 0;
diff --git a/boost/serialization/extended_type_info_no_rtti.hpp b/boost/serialization/extended_type_info_no_rtti.hpp
index 62b2473811..aaa8b44459 100644
--- a/boost/serialization/extended_type_info_no_rtti.hpp
+++ b/boost/serialization/extended_type_info_no_rtti.hpp
@@ -52,16 +52,16 @@ namespace no_rtti_system {
// common base class to share type_info_key. This is used to
// identify the method used to keep track of the extended type
-class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) extended_type_info_no_rtti_0 :
+class BOOST_SYMBOL_VISIBLE extended_type_info_no_rtti_0 :
public extended_type_info
{
protected:
- extended_type_info_no_rtti_0(const char * key);
- ~extended_type_info_no_rtti_0();
+ BOOST_SERIALIZATION_DECL extended_type_info_no_rtti_0(const char * key);
+ BOOST_SERIALIZATION_DECL ~extended_type_info_no_rtti_0();
public:
- virtual bool
+ virtual BOOST_SERIALIZATION_DECL bool
is_less_than(const boost::serialization::extended_type_info &rhs) const ;
- virtual bool
+ virtual BOOST_SERIALIZATION_DECL bool
is_equal(const boost::serialization::extended_type_info &rhs) const ;
};
diff --git a/boost/serialization/extended_type_info_typeid.hpp b/boost/serialization/extended_type_info_typeid.hpp
index 6a003be1a0..d9e99e03c8 100644
--- a/boost/serialization/extended_type_info_typeid.hpp
+++ b/boost/serialization/extended_type_info_typeid.hpp
@@ -49,7 +49,7 @@ namespace boost {
namespace serialization {
namespace typeid_system {
-class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) extended_type_info_typeid_0 :
+class BOOST_SYMBOL_VISIBLE extended_type_info_typeid_0 :
public extended_type_info
{
virtual const char * get_debug_info() const {
@@ -59,16 +59,16 @@ class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) extended_type_info_typeid_0 :
}
protected:
const std::type_info * m_ti;
- extended_type_info_typeid_0(const char * key);
- ~extended_type_info_typeid_0();
- void type_register(const std::type_info & ti);
- void type_unregister();
- const extended_type_info *
+ BOOST_SERIALIZATION_DECL extended_type_info_typeid_0(const char * key);
+ BOOST_SERIALIZATION_DECL ~extended_type_info_typeid_0();
+ BOOST_SERIALIZATION_DECL void type_register(const std::type_info & ti);
+ BOOST_SERIALIZATION_DECL void type_unregister();
+ BOOST_SERIALIZATION_DECL const extended_type_info *
get_extended_type_info(const std::type_info & ti) const;
public:
- virtual bool
+ virtual BOOST_SERIALIZATION_DECL bool
is_less_than(const extended_type_info &rhs) const;
- virtual bool
+ virtual BOOST_SERIALIZATION_DECL bool
is_equal(const extended_type_info &rhs) const;
const std::type_info & get_typeid() const {
return *m_ti;
diff --git a/boost/serialization/factory.hpp b/boost/serialization/factory.hpp
index b601af6268..916d75d7dd 100644
--- a/boost/serialization/factory.hpp
+++ b/boost/serialization/factory.hpp
@@ -21,7 +21,6 @@
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/comparison/greater.hpp>
-#include <boost/preprocessor/facilities/empty.hpp>
namespace std{
#if defined(__LIBCOMO__)
diff --git a/boost/serialization/force_include.hpp b/boost/serialization/force_include.hpp
index 468be37fe8..55ab79d0d5 100644
--- a/boost/serialization/force_include.hpp
+++ b/boost/serialization/force_include.hpp
@@ -31,11 +31,7 @@
// release mode.
#if defined(BOOST_HAS_DECLSPEC) && !defined(__COMO__)
-# if defined(__BORLANDC__)
-# define BOOST_DLLEXPORT __export
-# else
-# define BOOST_DLLEXPORT __declspec(dllexport)
-# endif
+# define BOOST_DLLEXPORT __declspec(dllexport)
#elif ! defined(_WIN32) && ! defined(_WIN64)
# if defined(__MWERKS__)
# define BOOST_DLLEXPORT __declspec(dllexport)
diff --git a/boost/serialization/forward_list.hpp b/boost/serialization/forward_list.hpp
index 612413b97d..fd52f860b7 100644
--- a/boost/serialization/forward_list.hpp
+++ b/boost/serialization/forward_list.hpp
@@ -16,20 +16,12 @@
// See http://www.boost.org for updates, documentation, and revision history.
-#include <cstddef> // size_t
#include <forward_list>
#include <iterator> // distance
-#include <boost/config.hpp> // msvc 6.0 needs this for warning suppression
-#if defined(BOOST_NO_STDC_NAMESPACE)
-namespace std{
- using ::size_t;
-} // namespace std
-#endif
-
#include <boost/serialization/collections_save_imp.hpp>
+#include <boost/serialization/collections_load_imp.hpp>
#include <boost/archive/detail/basic_iarchive.hpp>
-#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/serialization/item_version_type.hpp>
@@ -53,6 +45,42 @@ inline void save(
>(ar, t, count);
}
+namespace stl {
+
+template<
+ class Archive,
+ class T,
+ class Allocator
+>
+typename boost::disable_if<
+ typename detail::is_default_constructible<
+ typename std::forward_list<T, Allocator>::value_type
+ >,
+ void
+>::type
+collection_load_impl(
+ Archive & ar,
+ std::forward_list<T, Allocator> &t,
+ collection_size_type count,
+ item_version_type item_version
+){
+ t.clear();
+ boost::serialization::detail::stack_construct<Archive, T> u(ar, item_version);
+ ar >> boost::serialization::make_nvp("item", u.reference());
+ t.push_front(u.reference());
+ typename std::forward_list<T, Allocator>::iterator last;
+ last = t.begin();
+ ar.reset_object_address(&(*t.begin()) , & u.reference());
+ while(--count > 0){
+ detail::stack_construct<Archive, T> u(ar, item_version);
+ ar >> boost::serialization::make_nvp("item", u.reference());
+ last = t.insert_after(last, u.reference());
+ ar.reset_object_address(&(*last) , & u.reference());
+ }
+}
+
+} // stl
+
template<class Archive, class U, class Allocator>
inline void load(
Archive & ar,
@@ -69,29 +97,7 @@ inline void load(
if(boost::archive::library_version_type(3) < library_version){
ar >> BOOST_SERIALIZATION_NVP(item_version);
}
- if(detail::is_default_constructible<U>()){
- t.resize(count);
- typename std::forward_list<U, Allocator>::iterator hint;
- hint = t.begin();
- while(count-- > 0){
- ar >> boost::serialization::make_nvp("item", *hint++);
- }
- }
- else{
- t.clear();
- boost::serialization::detail::stack_construct<Archive, U> u(ar, item_version);
- ar >> boost::serialization::make_nvp("item", u.reference());
- t.push_front(u.reference());
- typename std::forward_list<U, Allocator>::iterator last;
- last = t.begin();
- ar.reset_object_address(&(*t.begin()) , & u.reference());
- while(--count > 0){
- detail::stack_construct<Archive, U> u(ar, item_version);
- ar >> boost::serialization::make_nvp("item", u.reference());
- last = t.insert_after(last, u.reference());
- ar.reset_object_address(&(*last) , & u.reference());
- }
- }
+ stl::collection_load_impl(ar, t, count, item_version);
}
// split non-intrusive serialization function member into separate
diff --git a/boost/serialization/level.hpp b/boost/serialization/level.hpp
index b037f7ebc7..f6a84d1042 100644
--- a/boost/serialization/level.hpp
+++ b/boost/serialization/level.hpp
@@ -63,19 +63,11 @@ struct implementation_level_impl {
//else
typename mpl::eval_if<
is_array< T >,
- #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560))
- mpl::int_<not_serializable>,
- #else
mpl::int_<object_serializable>,
- #endif
//else
typename mpl::eval_if<
is_enum< T >,
- //#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560))
- // mpl::int_<not_serializable>,
- //#else
mpl::int_<primitive_type>,
- //#endif
//else
mpl::int_<not_serializable>
>
diff --git a/boost/serialization/list.hpp b/boost/serialization/list.hpp
index b745d8769d..741dbbe73e 100644
--- a/boost/serialization/list.hpp
+++ b/boost/serialization/list.hpp
@@ -21,6 +21,7 @@
#include <boost/config.hpp>
#include <boost/serialization/collections_save_imp.hpp>
+#include <boost/serialization/collections_load_imp.hpp>
#include <boost/archive/detail/basic_iarchive.hpp>
#include <boost/serialization/access.hpp>
@@ -29,7 +30,6 @@
#include <boost/serialization/item_version_type.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/detail/stack_constructor.hpp>
-#include <boost/serialization/detail/is_default_constructible.hpp>
namespace boost {
namespace serialization {
@@ -62,23 +62,7 @@ inline void load(
if(boost::archive::library_version_type(3) < library_version){
ar >> BOOST_SERIALIZATION_NVP(item_version);
}
- if(detail::is_default_constructible<U>()){
- t.resize(count);
- typename std::list<U, Allocator>::iterator hint;
- hint = t.begin();
- while(count-- > 0){
- ar >> boost::serialization::make_nvp("item", *hint++);
- }
- }
- else{
- t.clear();
- while(count-- > 0){
- detail::stack_construct<Archive, U> u(ar, item_version);
- ar >> boost::serialization::make_nvp("item", u.reference());
- t.push_back(u.reference());
- ar.reset_object_address(& t.back() , & u.reference());
- }
- }
+ stl::collection_load_impl(ar, t, count, item_version);
}
// split non-intrusive serialization function member into separate
diff --git a/boost/serialization/nvp.hpp b/boost/serialization/nvp.hpp
index f33707c305..6a1eb82656 100644
--- a/boost/serialization/nvp.hpp
+++ b/boost/serialization/nvp.hpp
@@ -87,10 +87,7 @@ struct nvp :
template<class T>
inline
-#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-const
-#endif
-nvp< T > make_nvp(const char * name, T & t){
+const nvp< T > make_nvp(const char * name, T & t){
return nvp< T >(name, t);
}
diff --git a/boost/serialization/pfto.hpp b/boost/serialization/pfto.hpp
deleted file mode 100644
index 0370d2831f..0000000000
--- a/boost/serialization/pfto.hpp
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef BOOST_SERIALIZATION_PFTO_HPP
-#define BOOST_SERIALIZATION_PFTO_HPP
-
-// MS compatible compilers support #pragma once
-#if defined(_MSC_VER)
-# pragma once
-#endif
-
-/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
-// pfto.hpp: workarounds for compilers which have problems supporting
-// Partial Function Template Ordering (PFTO).
-
-// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
-// Use, modification and distribution is subject to the Boost Software
-// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-// See http://www.boost.org/libs/serialization for updates, documentation, and revision history.
-// PFTO version is used to specify the last argument of certain functions
-// Function it is used to support compilers that fail to support correct Partial
-// Template Ordering
-#include <boost/config.hpp>
-
-// some compilers can use an exta argument and use function overloading
-// to choose desired function. This extra argument is long in the default
-// function implementation and int for the rest. The function is called
-// with an int argument. This first attempts to match functions with an
-// int argument before the default one (with a long argument). This is
-// known to function with VC 6.0. On other compilers this fails (Borland)
-// or causes other problems (GCC). note: this
-
-#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
- #define BOOST_PFTO long
-#else
- #define BOOST_PFTO
-#endif
-
-// here's another approach. Rather than use a default function - make sure
-// there is no default at all by requiring that all function invocations
-// have a "wrapped" argument type. This solves a problem with VC 6.0
-// (and perhaps others) while implementing templated constructors.
-
-namespace boost {
-namespace serialization {
-
-template<class T>
-struct pfto_wrapper {
- const T & t;
- operator const T & (){
- return t;
- }
- pfto_wrapper (const T & rhs) : t(rhs) {}
-};
-
-template<class T>
-pfto_wrapper< T > make_pfto_wrapper(const T & t, BOOST_PFTO int){
- return pfto_wrapper< T >(t);
-}
-
-template<class T>
-pfto_wrapper< T > make_pfto_wrapper(const pfto_wrapper< T > & t, int){
- return t;
-}
-
-} // namespace serialization
-} // namespace boost
-
-#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
- #define BOOST_PFTO_WRAPPER(T) \
- boost::serialization::pfto_wrapper< T >
- #define BOOST_MAKE_PFTO_WRAPPER(t) \
- boost::serialization::make_pfto_wrapper(t, 0)
-#else
- #define BOOST_PFTO_WRAPPER(T) T
- #define BOOST_MAKE_PFTO_WRAPPER(t) t
-#endif
-
-#endif // BOOST_SERIALIZATION_PFTO_HPP
diff --git a/boost/serialization/serialization.hpp b/boost/serialization/serialization.hpp
index 8462b594c8..a4d04723c7 100644
--- a/boost/serialization/serialization.hpp
+++ b/boost/serialization/serialization.hpp
@@ -12,7 +12,6 @@
#include <boost/config.hpp>
#include <boost/serialization/strong_typedef.hpp>
-#include <boost/serialization/pfto.hpp>
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// serialization.hpp: interface for serialization system.
@@ -64,7 +63,7 @@ BOOST_STRONG_TYPEDEF(unsigned int, version_type)
// default implementation - call the member function "serialize"
template<class Archive, class T>
inline void serialize(
- Archive & ar, T & t, const BOOST_PFTO unsigned int file_version
+ Archive & ar, T & t, const unsigned int file_version
){
access::serialize(ar, t, static_cast<unsigned int>(file_version));
}
@@ -74,7 +73,7 @@ template<class Archive, class T>
inline void save_construct_data(
Archive & /*ar*/,
const T * /*t*/,
- const BOOST_PFTO unsigned int /*file_version */
+ const unsigned int /*file_version */
){
// default is to save no data because default constructor
// requires no arguments.
@@ -85,7 +84,7 @@ template<class Archive, class T>
inline void load_construct_data(
Archive & /*ar*/,
T * t,
- const BOOST_PFTO unsigned int /*file_version*/
+ const unsigned int /*file_version*/
){
// default just uses the default constructor. going
// through access permits usage of otherwise private default
@@ -123,12 +122,8 @@ inline void serialize_adl(
// Note that this trick generates problems for compiles which don't support
// PFTO, suppress it here. As far as we know, there are no compilers
// which fail to support PFTO while supporting two-phase lookup.
- #if ! defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
- const version_type v(file_version);
- serialize(ar, t, v);
- #else
- serialize(ar, t, file_version);
- #endif
+ const version_type v(file_version);
+ serialize(ar, t, v);
}
template<class Archive, class T>
@@ -138,12 +133,8 @@ inline void save_construct_data_adl(
const unsigned int file_version
){
// see above
- #if ! defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
- const version_type v(file_version);
- save_construct_data(ar, t, v);
- #else
- save_construct_data(ar, t, file_version);
- #endif
+ const version_type v(file_version);
+ save_construct_data(ar, t, v);
}
template<class Archive, class T>
@@ -153,12 +144,8 @@ inline void load_construct_data_adl(
const unsigned int file_version
){
// see above comment
- #if ! defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
- const version_type v(file_version);
- load_construct_data(ar, t, v);
- #else
- load_construct_data(ar, t, file_version);
- #endif
+ const version_type v(file_version);
+ load_construct_data(ar, t, v);
}
} // namespace serialization
diff --git a/boost/serialization/shared_ptr.hpp b/boost/serialization/shared_ptr.hpp
index 345aae961c..0d4c5ae605 100644
--- a/boost/serialization/shared_ptr.hpp
+++ b/boost/serialization/shared_ptr.hpp
@@ -48,11 +48,7 @@
#else
typedef mpl::int_<1> type;
#endif
- #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570))
- BOOST_STATIC_CONSTANT(int, value = 1);
- #else
BOOST_STATIC_CONSTANT(int, value = type::value);
- #endif
};
// don't track shared pointers
template<class T>
@@ -63,11 +59,7 @@
#else
typedef mpl::int_< ::boost::serialization::track_never> type;
#endif
- #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570))
- BOOST_STATIC_CONSTANT(int, value = ::boost::serialization::track_never);
- #else
BOOST_STATIC_CONSTANT(int, value = type::value);
- #endif
};
}}
#define BOOST_SERIALIZATION_SHARED_PTR(T)
diff --git a/boost/serialization/shared_ptr_132.hpp b/boost/serialization/shared_ptr_132.hpp
index ea02abdb82..3dfaba4d69 100644
--- a/boost/serialization/shared_ptr_132.hpp
+++ b/boost/serialization/shared_ptr_132.hpp
@@ -78,7 +78,7 @@ inline void save_construct_data(
Archive & ar,
const
boost_132::detail::sp_counted_base_impl<P, D> *t,
- const BOOST_PFTO unsigned int /* file_version */
+ const unsigned int /* file_version */
){
// variables used for construction
ar << boost::serialization::make_nvp("ptr", t->ptr);
diff --git a/boost/serialization/shared_ptr_helper.hpp b/boost/serialization/shared_ptr_helper.hpp
index 64269a955a..189447a804 100644
--- a/boost/serialization/shared_ptr_helper.hpp
+++ b/boost/serialization/shared_ptr_helper.hpp
@@ -57,7 +57,7 @@ template<template<class T> class SPT>
class shared_ptr_helper {
typedef std::map<
const void *, // address of object
- SPT<void> // address shared ptr to single instance
+ SPT<const void> // address shared ptr to single instance
> object_shared_pointer_map;
// list of shared_pointers create accessable by raw pointer. This
@@ -71,7 +71,9 @@ class shared_ptr_helper {
void operator()(void const *) const {}
};
-#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) || defined(BOOST_MSVC)
+#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
+|| defined(BOOST_MSVC) \
+|| defined(__SUNPRO_CC)
public:
#else
template<class Archive, class U>
@@ -92,7 +94,7 @@ public:
// by a change in load_construct_data below. It makes this file suitable
// only for loading pointers into a 1.33 or later boost system.
std::list<boost_132::shared_ptr<const void> > * m_pointers_132;
- BOOST_ARCHIVE_DECL(void)
+ BOOST_ARCHIVE_DECL void
append(const boost_132::shared_ptr<const void> & t){
if(NULL == m_pointers_132)
m_pointers_132 = new std::list<boost_132::shared_ptr<const void> >;
diff --git a/boost/serialization/singleton.hpp b/boost/serialization/singleton.hpp
index 546118c868..a397da5771 100644
--- a/boost/serialization/singleton.hpp
+++ b/boost/serialization/singleton.hpp
@@ -77,7 +77,7 @@ namespace serialization {
// attempt to retieve a mutable instances while locked will
// generate a assertion if compiled for debug.
-class singleton_module :
+class BOOST_SYMBOL_VISIBLE singleton_module :
public boost::noncopyable
{
private:
diff --git a/boost/serialization/slist.hpp b/boost/serialization/slist.hpp
index 424aa51466..af300683e0 100644
--- a/boost/serialization/slist.hpp
+++ b/boost/serialization/slist.hpp
@@ -16,20 +16,17 @@
// See http://www.boost.org for updates, documentation, and revision history.
-#include <cstddef> // size_t
-#include <boost/config.hpp> // msvc 6.0 needs this for warning suppression
-#if defined(BOOST_NO_STDC_NAMESPACE)
-namespace std{
- using ::size_t;
-} // namespace std
-#endif
-
+#include <boost/config.hpp>
#ifdef BOOST_HAS_SLIST
#include BOOST_SLIST_HEADER
#include <boost/serialization/collections_save_imp.hpp>
-#include <boost/serialization/split_free.hpp>
+#include <boost/serialization/collections_load_imp.hpp>
+#include <boost/archive/detail/basic_iarchive.hpp>
#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/collection_size_type.hpp>
+#include <boost/serialization/item_version_type.hpp>
+#include <boost/serialization/split_free.hpp>
#include <boost/serialization/detail/stack_constructor.hpp>
#include <boost/serialization/detail/is_default_constructible.hpp>
@@ -48,6 +45,42 @@ inline void save(
>(ar, t);
}
+namespace stl {
+
+template<
+ class Archive,
+ class T,
+ class Allocator
+>
+typename boost::disable_if<
+ typename detail::is_default_constructible<
+ typename BOOST_STD_EXTENSION_NAMESPACE::slist<T, Allocator>::value_type
+ >,
+ void
+>::type
+collection_load_impl(
+ Archive & ar,
+ BOOST_STD_EXTENSION_NAMESPACE::slist<T, Allocator> &t,
+ collection_size_type count,
+ item_version_type item_version
+){
+ t.clear();
+ boost::serialization::detail::stack_construct<Archive, T> u(ar, item_version);
+ ar >> boost::serialization::make_nvp("item", u.reference());
+ t.push_front(u.reference());
+ typename BOOST_STD_EXTENSION_NAMESPACE::slist<T, Allocator>::iterator last;
+ last = t.begin();
+ ar.reset_object_address(&(*t.begin()) , & u.reference());
+ while(--count > 0){
+ detail::stack_construct<Archive, T> u(ar, item_version);
+ ar >> boost::serialization::make_nvp("item", u.reference());
+ last = t.insert_after(last, u.reference());
+ ar.reset_object_address(&(*last) , & u.reference());
+ }
+}
+
+} // stl
+
template<class Archive, class U, class Allocator>
inline void load(
Archive & ar,
diff --git a/boost/serialization/smart_cast.hpp b/boost/serialization/smart_cast.hpp
index 02edb4be09..563f36aa20 100644
--- a/boost/serialization/smart_cast.hpp
+++ b/boost/serialization/smart_cast.hpp
@@ -85,7 +85,6 @@ namespace smart_cast_impl {
static T cast(U & u){
// if we're in debug mode
#if ! defined(NDEBUG) \
- || defined(__BORLANDC__) && (__BORLANDC__ <= 0x560) \
|| defined(__MWERKS__)
// do a checked dynamic cast
return cross::cast(u);
@@ -124,20 +123,12 @@ namespace smart_cast_impl {
};
template<class U>
static T cast(U & u){
- #if defined(__BORLANDC__)
- return mpl::eval_if<
- boost::is_polymorphic<U>,
- mpl::identity<polymorphic>,
- mpl::identity<non_polymorphic>
- >::type::cast(u);
- #else
- typedef typename mpl::eval_if<
- boost::is_polymorphic<U>,
- mpl::identity<polymorphic>,
- mpl::identity<non_polymorphic>
- >::type typex;
- return typex::cast(u);
- #endif
+ typedef typename mpl::eval_if<
+ boost::is_polymorphic<U>,
+ mpl::identity<polymorphic>,
+ mpl::identity<non_polymorphic>
+ >::type typex;
+ return typex::cast(u);
}
};
@@ -169,34 +160,23 @@ namespace smart_cast_impl {
template<class U>
static T cast(U * u){
- // if we're in debug mode
- #if 0 //! defined(NDEBUG) || defined(__BORLANDC__) && (__BORLANDC__ <= 0x560)
- // do a checked dynamic cast
- return cross::cast(u);
- #else
- // borland 5.51 chokes here so we can't use it
- // note: if remove_pointer isn't function for these types
- // cross casting will be selected this will work but will
- // not be the most efficient method. This will conflict with
- // the original smart_cast motivation.
- typedef
- typename mpl::eval_if<
- typename mpl::and_<
- mpl::not_<is_base_and_derived<
- typename remove_pointer< T >::type,
- U
- > >,
- mpl::not_<is_base_and_derived<
- U,
- typename remove_pointer< T >::type
- > >
- >,
- // borland chokes w/o full qualification here
- mpl::identity<cross>,
- mpl::identity<linear>
- >::type typex;
- return typex::cast(u);
- #endif
+ typedef
+ typename mpl::eval_if<
+ typename mpl::and_<
+ mpl::not_<is_base_and_derived<
+ typename remove_pointer< T >::type,
+ U
+ > >,
+ mpl::not_<is_base_and_derived<
+ U,
+ typename remove_pointer< T >::type
+ > >
+ >,
+ // borland chokes w/o full qualification here
+ mpl::identity<cross>,
+ mpl::identity<linear>
+ >::type typex;
+ return typex::cast(u);
}
#else
template<class U>
@@ -219,20 +199,12 @@ namespace smart_cast_impl {
template<class U>
static T cast(U * u){
- #if defined(__BORLANDC__)
- return mpl::eval_if<
- boost::is_polymorphic<U>,
- mpl::identity<polymorphic>,
- mpl::identity<non_polymorphic>
- >::type::cast(u);
- #else
- typedef typename mpl::eval_if<
- boost::is_polymorphic<U>,
- mpl::identity<polymorphic>,
- mpl::identity<non_polymorphic>
- >::type typex;
- return typex::cast(u);
- #endif
+ typedef typename mpl::eval_if<
+ boost::is_polymorphic<U>,
+ mpl::identity<polymorphic>,
+ mpl::identity<non_polymorphic>
+ >::type typex;
+ return typex::cast(u);
}
};
@@ -251,7 +223,7 @@ namespace smart_cast_impl {
// cast on a system which doesn't support partial template
// specialization
template<class U>
- static T cast(U u){
+ static T cast(U){
BOOST_STATIC_ASSERT(sizeof(T)==0);
return * static_cast<T *>(NULL);
}
diff --git a/boost/serialization/static_warning.hpp b/boost/serialization/static_warning.hpp
index d2f23d36d2..cbbcb826cb 100644
--- a/boost/serialization/static_warning.hpp
+++ b/boost/serialization/static_warning.hpp
@@ -57,13 +57,7 @@
//------------------Enable selected warnings----------------------------------//
-// Enable the warnings relied on by BOOST_STATIC_WARNING, where possible. The
-// only pragma which is absolutely necessary here is for Borland 5.x, since
-// W8073 is disabled by default. If enabling selected warnings is considered
-// unacceptable, this section can be replaced with:
-// #if defined(__BORLANDC__) && (__BORLANDC__ <= 0x600)
-// pragma warn +st
-// #endif
+// Enable the warnings relied on by BOOST_STATIC_WARNING, where possible.
// 6. replaced implementation with one which depends solely on
// mpl::print<>. The previous one was found to fail for functions
diff --git a/boost/serialization/strong_typedef.hpp b/boost/serialization/strong_typedef.hpp
index 54a51626a7..c1bf1844bf 100644
--- a/boost/serialization/strong_typedef.hpp
+++ b/boost/serialization/strong_typedef.hpp
@@ -25,42 +25,22 @@
#include <boost/config.hpp>
#include <boost/operators.hpp>
-#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x590
- #define BOOST_STRONG_TYPEDEF(T, D) \
- struct D \
- : boost::totally_ordered1< D \
- , boost::totally_ordered2< D, T \
- > > \
- { \
- T t; \
- explicit D(const T t_) : t(t_) {}; \
- D(): t() {}; \
- D(const D & t_) : t(t_.t){} \
- D & operator=(const D & rhs) { t = rhs.t; return *this;} \
- D & operator=(const T & rhs) { t = rhs; return *this;} \
- operator const T & () const {return t; } \
- operator T & () { return t; } \
- bool operator==(const D & rhs) const { return t == rhs.t; } \
- bool operator<(const D & rhs) const { return t < rhs.t; } \
- };
-#else
- #define BOOST_STRONG_TYPEDEF(T, D) \
- struct D \
- : boost::totally_ordered1< D \
- , boost::totally_ordered2< D, T \
- > > \
- { \
- T t; \
- explicit D(const T t_) : t(t_) {}; \
- D() : t(){}; \
- D(const D & t_) : t(t_.t){} \
- D & operator=(const D & rhs) { t = rhs.t; return *this;} \
- D & operator=(const T & rhs) { t = rhs; return *this;} \
- /*operator const T & () const {return t; }*/ \
- operator T & () { return t; } \
- bool operator==(const D & rhs) const { return t == rhs.t; } \
- bool operator<(const D & rhs) const { return t < rhs.t; } \
- };
-#endif // !defined(__BORLANDC) || __BORLANDC__ >= 0x590
+#define BOOST_STRONG_TYPEDEF(T, D) \
+struct D \
+ : boost::totally_ordered1< D \
+ , boost::totally_ordered2< D, T \
+ > > \
+{ \
+ T t; \
+ explicit D(const T t_) : t(t_) {}; \
+ D(): t() {}; \
+ D(const D & t_) : t(t_.t){} \
+ D & operator=(const D & rhs) { t = rhs.t; return *this;} \
+ D & operator=(const T & rhs) { t = rhs; return *this;} \
+ operator const T & () const {return t; } \
+ operator T & () { return t; } \
+ bool operator==(const D & rhs) const { return t == rhs.t; } \
+ bool operator<(const D & rhs) const { return t < rhs.t; } \
+};
#endif // BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP
diff --git a/boost/serialization/type_info_implementation.hpp b/boost/serialization/type_info_implementation.hpp
index 2c033fc875..24637a8dbb 100644
--- a/boost/serialization/type_info_implementation.hpp
+++ b/boost/serialization/type_info_implementation.hpp
@@ -55,18 +55,6 @@ struct type_info_implementation {
// define a macro to assign a particular derivation of extended_type_info
// to a specified a class.
-#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560))
-#define BOOST_CLASS_TYPE_INFO(T, ETI) \
-namespace boost { \
-namespace serialization { \
-template<> \
-struct type_info_implementation< T > { \
- typedef const ETI type; \
-}; \
-} \
-} \
-/**/
-#else
#define BOOST_CLASS_TYPE_INFO(T, ETI) \
namespace boost { \
namespace serialization { \
@@ -81,6 +69,5 @@ struct type_info_implementation< const T > { \
} \
} \
/**/
-#endif
#endif /// BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP
diff --git a/boost/serialization/vector.hpp b/boost/serialization/vector.hpp
index aa3aaca21c..6e49bff38a 100644
--- a/boost/serialization/vector.hpp
+++ b/boost/serialization/vector.hpp
@@ -29,12 +29,13 @@
#include <boost/serialization/item_version_type.hpp>
#include <boost/serialization/collections_save_imp.hpp>
+#include <boost/serialization/collections_load_imp.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/detail/get_data.hpp>
#include <boost/serialization/detail/stack_constructor.hpp>
-#include <boost/serialization/detail/is_default_constructible.hpp>
#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
// default is being compatible with version 1.34.1 files, not 1.35 files
#ifndef BOOST_SERIALIZATION_VECTOR_VERSIONED
@@ -86,23 +87,8 @@ inline void load(
if(boost::archive::library_version_type(3) < library_version){
ar >> BOOST_SERIALIZATION_NVP(item_version);
}
- if(detail::is_default_constructible<U>()){
- t.resize(count);
- typename std::vector<U, Allocator>::iterator hint;
- hint = t.begin();
- while(count-- > 0){
- ar >> boost::serialization::make_nvp("item", *hint++);
- }
- }
- else{
- t.reserve(count);
- while(count-- > 0){
- detail::stack_construct<Archive, U> u(ar, item_version);
- ar >> boost::serialization::make_nvp("item", u.reference());
- t.push_back(u.reference());
- ar.reset_object_address(& t.back() , & u.reference());
- }
- }
+ t.reserve(count);
+ stl::collection_load_impl(ar, t, count, item_version);
}
// the optimized versions
@@ -212,8 +198,7 @@ inline void load(
collection_size_type count;
ar >> BOOST_SERIALIZATION_NVP(count);
t.resize(count);
- int i;
- for(i = 0; i < count; ++i){
+ for(collection_size_type i = collection_size_type(0); i < count; ++i){
bool b;
ar >> boost::serialization::make_nvp("item", b);
t[i] = b;
diff --git a/boost/serialization/void_cast.hpp b/boost/serialization/void_cast.hpp
index 61b6449ef1..f1b3828611 100644
--- a/boost/serialization/void_cast.hpp
+++ b/boost/serialization/void_cast.hpp
@@ -47,7 +47,7 @@ class extended_type_info;
// Return the altered pointer. If there exists no sequence of casts that
// can transform from_type to to_type, return a NULL.
-BOOST_SERIALIZATION_DECL(void const *)
+BOOST_SERIALIZATION_DECL void const *
void_upcast(
extended_type_info const & derived,
extended_type_info const & base,
@@ -67,7 +67,7 @@ void_upcast(
));
}
-BOOST_SERIALIZATION_DECL(void const *)
+BOOST_SERIALIZATION_DECL void const *
void_downcast(
extended_type_info const & derived,
extended_type_info const & base,
@@ -89,26 +89,26 @@ void_downcast(
namespace void_cast_detail {
-class BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) void_caster :
+class BOOST_SYMBOL_VISIBLE void_caster :
private boost::noncopyable
{
friend
- BOOST_SERIALIZATION_DECL(void const *)
+ BOOST_SERIALIZATION_DECL void const *
boost::serialization::void_upcast(
extended_type_info const & derived,
extended_type_info const & base,
void const * const
);
friend
- BOOST_SERIALIZATION_DECL(void const *)
+ BOOST_SERIALIZATION_DECL void const *
boost::serialization::void_downcast(
extended_type_info const & derived,
extended_type_info const & base,
void const * const
);
protected:
- void recursive_register(bool includes_virtual_base = false) const;
- void recursive_unregister() const;
+ BOOST_SERIALIZATION_DECL void recursive_register(bool includes_virtual_base = false) const;
+ BOOST_SERIALIZATION_DECL void recursive_unregister() const;
virtual bool has_virtual_base() const = 0;
public:
// Data members
@@ -151,7 +151,7 @@ public:
#endif
template <class Derived, class Base>
-class void_caster_primitive :
+class BOOST_SYMBOL_VISIBLE void_caster_primitive :
public void_caster
{
virtual void const * downcast(void const * const t) const {
@@ -199,7 +199,7 @@ void_caster_primitive<Derived, Base>::~void_caster_primitive(){
}
template <class Derived, class Base>
-class void_caster_virtual_base :
+class BOOST_SYMBOL_VISIBLE void_caster_virtual_base :
public void_caster
{
virtual bool has_virtual_base() const {
@@ -244,7 +244,7 @@ void_caster_virtual_base<Derived,Base>::~void_caster_virtual_base(){
}
template <class Derived, class Base>
-struct void_caster_base :
+struct BOOST_SYMBOL_VISIBLE void_caster_base :
public void_caster
{
typedef
@@ -281,7 +281,7 @@ inline const void_cast_detail::void_caster & void_cast_register(
}
template<class Derived, class Base>
-class void_caster :
+class BOOST_SYMBOL_VISIBLE void_caster :
public void_cast_detail::void_caster_base<Derived, Base>::type
{
};
diff --git a/boost/signals2/connection.hpp b/boost/signals2/connection.hpp
index 0ab4dacbf6..dac806b221 100644
--- a/boost/signals2/connection.hpp
+++ b/boost/signals2/connection.hpp
@@ -18,6 +18,7 @@
#include <boost/mpl/bool.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
+#include <boost/signals2/detail/auto_buffer.hpp>
#include <boost/signals2/detail/null_output_iterator.hpp>
#include <boost/signals2/detail/unique_lock.hpp>
#include <boost/signals2/slot.hpp>
@@ -27,25 +28,53 @@ namespace boost
{
namespace signals2
{
- extern inline void null_deleter(const void*) {}
+ inline void null_deleter(const void*) {}
namespace detail
{
+ // This lock maintains a list of shared_ptr<void>
+ // which will be destroyed only after the lock
+ // has released its mutex. Used to garbage
+ // collect disconnected slots
+ template<typename Mutex>
+ class garbage_collecting_lock: public noncopyable
+ {
+ public:
+ garbage_collecting_lock(Mutex &m):
+ lock(m)
+ {}
+ void add_trash(const shared_ptr<void> &piece_of_trash)
+ {
+ garbage.push_back(piece_of_trash);
+ }
+ private:
+ // garbage must be declared before lock
+ // to insure it is destroyed after lock is
+ // destroyed.
+ auto_buffer<shared_ptr<void>, store_n_objects<10> > garbage;
+ unique_lock<Mutex> lock;
+ };
+
class connection_body_base
{
public:
connection_body_base():
- _connected(true)
+ _connected(true), m_slot_refcount(1)
{
}
virtual ~connection_body_base() {}
void disconnect()
{
- unique_lock<connection_body_base> local_lock(*this);
- nolock_disconnect();
+ garbage_collecting_lock<connection_body_base> local_lock(*this);
+ nolock_disconnect(local_lock);
}
- void nolock_disconnect()
+ template<typename Mutex>
+ void nolock_disconnect(garbage_collecting_lock<Mutex> &lock_arg) const
{
- _connected = false;
+ if(_connected)
+ {
+ _connected = false;
+ dec_slot_refcount(lock_arg);
+ }
}
virtual bool connected() const = 0;
shared_ptr<void> get_blocker()
@@ -72,10 +101,39 @@ namespace boost
virtual void lock() = 0;
virtual void unlock() = 0;
+ // Slot refcount should be incremented while
+ // a signal invocation is using the slot, in order
+ // to prevent slot from being destroyed mid-invocation.
+ // garbage_collecting_lock parameter enforces
+ // the existance of a lock before this
+ // method is called
+ template<typename Mutex>
+ void inc_slot_refcount(const garbage_collecting_lock<Mutex> &)
+ {
+ BOOST_ASSERT(m_slot_refcount != 0);
+ ++m_slot_refcount;
+ }
+ // if slot refcount decrements to zero due to this call,
+ // it puts a
+ // shared_ptr to the slot in the garbage collecting lock,
+ // which will destroy the slot only after it unlocks.
+ template<typename Mutex>
+ void dec_slot_refcount(garbage_collecting_lock<Mutex> &lock_arg) const
+ {
+ BOOST_ASSERT(m_slot_refcount != 0);
+ if(--m_slot_refcount == 0)
+ {
+ lock_arg.add_trash(release_slot());
+ }
+ }
+
protected:
+ virtual shared_ptr<void> release_slot() const = 0;
- mutable bool _connected;
weak_ptr<void> _weak_blocker;
+ private:
+ mutable bool _connected;
+ mutable unsigned m_slot_refcount;
};
template<typename GroupKey, typename SlotType, typename Mutex>
@@ -83,34 +141,37 @@ namespace boost
{
public:
typedef Mutex mutex_type;
- connection_body(const SlotType &slot_in):
- slot(slot_in)
+ connection_body(const SlotType &slot_in, const boost::shared_ptr<mutex_type> &signal_mutex):
+ m_slot(new SlotType(slot_in)), _mutex(signal_mutex)
{
}
virtual ~connection_body() {}
virtual bool connected() const
{
- unique_lock<mutex_type> local_lock(_mutex);
- nolock_grab_tracked_objects(detail::null_output_iterator());
+ garbage_collecting_lock<mutex_type> local_lock(*_mutex);
+ nolock_grab_tracked_objects(local_lock, detail::null_output_iterator());
return nolock_nograb_connected();
}
const GroupKey& group_key() const {return _group_key;}
void set_group_key(const GroupKey &key) {_group_key = key;}
- bool nolock_slot_expired() const
+ template<typename M>
+ void disconnect_expired_slot(garbage_collecting_lock<M> &lock_arg)
{
- bool expired = slot.expired();
+ if(!m_slot) return;
+ bool expired = slot().expired();
if(expired == true)
{
- _connected = false;
+ nolock_disconnect(lock_arg);
}
- return expired;
}
- template<typename OutputIterator>
- void nolock_grab_tracked_objects(OutputIterator inserter) const
+ template<typename M, typename OutputIterator>
+ void nolock_grab_tracked_objects(garbage_collecting_lock<M> &lock_arg,
+ OutputIterator inserter) const
{
+ if(!m_slot) return;
slot_base::tracked_container_type::const_iterator it;
- for(it = slot.tracked_objects().begin();
- it != slot.tracked_objects().end();
+ for(it = slot().tracked_objects().begin();
+ it != slot().tracked_objects().end();
++it)
{
void_shared_ptr_variant locked_object
@@ -123,7 +184,7 @@ namespace boost
);
if(apply_visitor(detail::expired_weak_ptr_visitor(), *it))
{
- _connected = false;
+ nolock_disconnect(lock_arg);
return;
}
*inserter++ = locked_object;
@@ -132,15 +193,31 @@ namespace boost
// expose Lockable concept of mutex
virtual void lock()
{
- _mutex.lock();
+ _mutex->lock();
}
virtual void unlock()
{
- _mutex.unlock();
+ _mutex->unlock();
+ }
+ SlotType &slot()
+ {
+ return *m_slot;
+ }
+ const SlotType &slot() const
+ {
+ return *m_slot;
+ }
+ protected:
+ virtual shared_ptr<void> release_slot() const
+ {
+
+ shared_ptr<void> released_slot = m_slot;
+ m_slot.reset();
+ return released_slot;
}
- SlotType slot;
private:
- mutable mutex_type _mutex;
+ mutable boost::shared_ptr<SlotType> m_slot;
+ const boost::shared_ptr<mutex_type> _mutex;
GroupKey _group_key;
};
}
diff --git a/boost/signals2/deconstruct_ptr.hpp b/boost/signals2/deconstruct_ptr.hpp
index 841b19b2c1..bdc11188ee 100644
--- a/boost/signals2/deconstruct_ptr.hpp
+++ b/boost/signals2/deconstruct_ptr.hpp
@@ -27,18 +27,18 @@ namespace boost
{
namespace detail
{
- extern inline void do_postconstruct(const postconstructible *ptr)
+ inline void do_postconstruct(const postconstructible *ptr)
{
postconstructible *nonconst_ptr = const_cast<postconstructible*>(ptr);
nonconst_ptr->postconstruct();
}
- extern inline void do_postconstruct(...)
+ inline void do_postconstruct(...)
{
}
- extern inline void do_predestruct(...)
+ inline void do_predestruct(...)
{
}
- extern inline void do_predestruct(const predestructible *ptr)
+ inline void do_predestruct(const predestructible *ptr)
{
try
{
diff --git a/boost/signals2/detail/auto_buffer.hpp b/boost/signals2/detail/auto_buffer.hpp
index bf12e698e2..8007b3c6b9 100644
--- a/boost/signals2/detail/auto_buffer.hpp
+++ b/boost/signals2/detail/auto_buffer.hpp
@@ -23,7 +23,6 @@
#include <boost/mpl/if.hpp>
#include <boost/multi_index/detail/scope_guard.hpp>
#include <boost/swap.hpp>
-#include <boost/throw_exception.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/has_nothrow_copy.hpp>
diff --git a/boost/signals2/detail/lwm_win32_cs.hpp b/boost/signals2/detail/lwm_win32_cs.hpp
index d1c1965dea..462da03174 100644
--- a/boost/signals2/detail/lwm_win32_cs.hpp
+++ b/boost/signals2/detail/lwm_win32_cs.hpp
@@ -55,7 +55,7 @@ extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(crit
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *);
#endif
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *);
-extern "C" __declspec(dllimport) bool __stdcall TryEnterCriticalSection(critical_section *);
+extern "C" __declspec(dllimport) int __stdcall TryEnterCriticalSection(critical_section *);
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *);
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *);
diff --git a/boost/signals2/detail/signal_template.hpp b/boost/signals2/detail/signal_template.hpp
index 09d7d8d9f9..d3adcee6bc 100644
--- a/boost/signals2/detail/signal_template.hpp
+++ b/boost/signals2/detail/signal_template.hpp
@@ -154,37 +154,38 @@ namespace boost
BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const combiner_type &combiner_arg,
const group_compare_type &group_compare):
_shared_state(new invocation_state(connection_list_type(group_compare), combiner_arg)),
- _garbage_collector_it(_shared_state->connection_bodies().end())
+ _garbage_collector_it(_shared_state->connection_bodies().end()),
+ _mutex(new mutex_type())
{}
// connect slot
connection connect(const slot_type &slot, connect_position position = at_back)
{
- unique_lock<mutex_type> lock(_mutex);
- return nolock_connect(slot, position);
+ garbage_collecting_lock<mutex_type> lock(*_mutex);
+ return nolock_connect(lock, slot, position);
}
connection connect(const group_type &group,
const slot_type &slot, connect_position position = at_back)
{
- unique_lock<Mutex> lock(_mutex);
- return nolock_connect(group, slot, position);
+ garbage_collecting_lock<mutex_type> lock(*_mutex);
+ return nolock_connect(lock, group, slot, position);
}
// connect extended slot
connection connect_extended(const extended_slot_type &ext_slot, connect_position position = at_back)
{
- unique_lock<mutex_type> lock(_mutex);
+ garbage_collecting_lock<mutex_type> lock(*_mutex);
bound_extended_slot_function_type bound_slot(ext_slot.slot_function());
slot_type slot = replace_slot_function<slot_type>(ext_slot, bound_slot);
- connection conn = nolock_connect(slot, position);
+ connection conn = nolock_connect(lock, slot, position);
bound_slot.set_connection(conn);
return conn;
}
connection connect_extended(const group_type &group,
const extended_slot_type &ext_slot, connect_position position = at_back)
{
- unique_lock<Mutex> lock(_mutex);
+ garbage_collecting_lock<Mutex> lock(*_mutex);
bound_extended_slot_function_type bound_slot(ext_slot.slot_function());
slot_type slot = replace_slot_function<slot_type>(ext_slot, bound_slot);
- connection conn = nolock_connect(group, slot, position);
+ connection conn = nolock_connect(lock, group, slot, position);
bound_slot.set_connection(conn);
return conn;
}
@@ -226,10 +227,10 @@ namespace boost
shared_ptr<invocation_state> local_state;
typename connection_list_type::iterator it;
{
- unique_lock<mutex_type> list_lock(_mutex);
+ garbage_collecting_lock<mutex_type> list_lock(*_mutex);
// only clean up if it is safe to do so
if(_shared_state.unique())
- nolock_cleanup_connections(false, 1);
+ nolock_cleanup_connections(list_lock, false, 1);
/* Make a local copy of _shared_state while holding mutex, so we are
thread safe against the combiner or connection list getting modified
during invocation. */
@@ -250,10 +251,10 @@ namespace boost
shared_ptr<invocation_state> local_state;
typename connection_list_type::iterator it;
{
- unique_lock<mutex_type> list_lock(_mutex);
+ garbage_collecting_lock<mutex_type> list_lock(*_mutex);
// only clean up if it is safe to do so
if(_shared_state.unique())
- nolock_cleanup_connections(false, 1);
+ nolock_cleanup_connections(list_lock, false, 1);
/* Make a local copy of _shared_state while holding mutex, so we are
thread safe against the combiner or connection list getting modified
during invocation. */
@@ -296,12 +297,12 @@ namespace boost
}
combiner_type combiner() const
{
- unique_lock<mutex_type> lock(_mutex);
+ unique_lock<mutex_type> lock(*_mutex);
return _shared_state->combiner();
}
void set_combiner(const combiner_type &combiner_arg)
{
- unique_lock<mutex_type> lock(_mutex);
+ unique_lock<mutex_type> lock(*_mutex);
if(_shared_state.unique())
_shared_state->combiner() = combiner_arg;
else
@@ -340,9 +341,7 @@ namespace boost
{}
result_type operator ()(const connection_body_type &connectionBody) const
{
- result_type *resolver = 0;
- return m_invoke(connectionBody,
- resolver);
+ return m_invoke<typename slot_type::result_type>(connectionBody);
}
private:
// declare assignment operator private since this class might have reference or const members
@@ -357,15 +356,18 @@ namespace boost
// m_arg1, m_arg2, ..., m_argn
#define BOOST_SIGNALS2_M_ARG_NAMES(arity) BOOST_PP_ENUM(arity, BOOST_SIGNALS2_M_ARG_NAME, ~)
+ template<typename SlotResultType>
result_type m_invoke(const connection_body_type &connectionBody,
- const void_type *) const
+ typename boost::enable_if<boost::is_void<SlotResultType> >::type * = 0) const
{
- connectionBody->slot.slot_function()(BOOST_SIGNALS2_M_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ connectionBody->slot().slot_function()(BOOST_SIGNALS2_M_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
return void_type();
}
- result_type m_invoke(const connection_body_type &connectionBody, ...) const
+ template<typename SlotResultType>
+ result_type m_invoke(const connection_body_type &connectionBody,
+ typename boost::disable_if<boost::is_void<SlotResultType> >::type * = 0) const
{
- return connectionBody->slot.slot_function()(BOOST_SIGNALS2_M_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ return connectionBody->slot().slot_function()(BOOST_SIGNALS2_M_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
}
};
#undef BOOST_SIGNALS2_M_ARG_NAMES
@@ -427,7 +429,8 @@ namespace boost
};
// clean up disconnected connections
- void nolock_cleanup_connections_from(bool grab_tracked,
+ void nolock_cleanup_connections_from(garbage_collecting_lock<mutex_type> &lock,
+ bool grab_tracked,
const typename connection_list_type::iterator &begin, unsigned count = 0) const
{
BOOST_ASSERT(_shared_state.unique());
@@ -438,12 +441,9 @@ namespace boost
++i)
{
bool connected;
- {
- unique_lock<connection_body_base> lock(**it);
- if(grab_tracked)
- (*it)->nolock_slot_expired();
- connected = (*it)->nolock_nograb_connected();
- }// scoped lock destructs here, safe to erase now
+ if(grab_tracked)
+ (*it)->disconnect_expired_slot(lock);
+ connected = (*it)->nolock_nograb_connected();
if(connected == false)
{
it = _shared_state->connection_bodies().erase((*it)->group_key(), it);
@@ -455,7 +455,8 @@ namespace boost
_garbage_collector_it = it;
}
// clean up a few connections in constant time
- void nolock_cleanup_connections(bool grab_tracked, unsigned count) const
+ void nolock_cleanup_connections(garbage_collecting_lock<mutex_type> &lock,
+ bool grab_tracked, unsigned count) const
{
BOOST_ASSERT(_shared_state.unique());
typename connection_list_type::iterator begin;
@@ -466,28 +467,28 @@ namespace boost
{
begin = _garbage_collector_it;
}
- nolock_cleanup_connections_from(grab_tracked, begin, count);
+ nolock_cleanup_connections_from(lock, grab_tracked, begin, count);
}
/* Make a new copy of the slot list if it is currently being read somewhere else
*/
- void nolock_force_unique_connection_list()
+ void nolock_force_unique_connection_list(garbage_collecting_lock<mutex_type> &lock)
{
if(_shared_state.unique() == false)
{
_shared_state.reset(new invocation_state(*_shared_state, _shared_state->connection_bodies()));
- nolock_cleanup_connections_from(true, _shared_state->connection_bodies().begin());
+ nolock_cleanup_connections_from(lock, true, _shared_state->connection_bodies().begin());
}else
{
/* We need to try and check more than just 1 connection here to avoid corner
cases where certain repeated connect/disconnect patterns cause the slot
list to grow without limit. */
- nolock_cleanup_connections(true, 2);
+ nolock_cleanup_connections(lock, true, 2);
}
}
// force a full cleanup of the connection list
void force_cleanup_connections(const connection_list_type *connection_bodies) const
{
- unique_lock<mutex_type> list_lock(_mutex);
+ garbage_collecting_lock<mutex_type> list_lock(*_mutex);
// if the connection list passed in as a parameter is no longer in use,
// we don't need to do any cleanup.
if(&_shared_state->connection_bodies() != connection_bodies)
@@ -498,17 +499,18 @@ namespace boost
{
_shared_state.reset(new invocation_state(*_shared_state, _shared_state->connection_bodies()));
}
- nolock_cleanup_connections_from(false, _shared_state->connection_bodies().begin());
+ nolock_cleanup_connections_from(list_lock, false, _shared_state->connection_bodies().begin());
}
shared_ptr<invocation_state> get_readable_state() const
{
- unique_lock<mutex_type> list_lock(_mutex);
+ unique_lock<mutex_type> list_lock(*_mutex);
return _shared_state;
}
- connection_body_type create_new_connection(const slot_type &slot)
+ connection_body_type create_new_connection(garbage_collecting_lock<mutex_type> &lock,
+ const slot_type &slot)
{
- nolock_force_unique_connection_list();
- return connection_body_type(new connection_body<group_key_type, slot_type, Mutex>(slot));
+ nolock_force_unique_connection_list(lock);
+ return connection_body_type(new connection_body<group_key_type, slot_type, Mutex>(slot, _mutex));
}
void do_disconnect(const group_type &group, mpl::bool_<true> /* is_group */)
{
@@ -523,27 +525,29 @@ namespace boost
for(it = local_state->connection_bodies().begin();
it != local_state->connection_bodies().end(); ++it)
{
- unique_lock<connection_body_base> lock(**it);
- if((*it)->slot.slot_function() == slot)
+ garbage_collecting_lock<connection_body_base> lock(**it);
+ if((*it)->nolock_nograb_connected() == false) continue;
+ if((*it)->slot().slot_function() == slot)
{
- (*it)->nolock_disconnect();
+ (*it)->nolock_disconnect(lock);
}else
{
// check for wrapped extended slot
bound_extended_slot_function_type *fp;
- fp = (*it)->slot.slot_function().template target<bound_extended_slot_function_type>();
+ fp = (*it)->slot().slot_function().template target<bound_extended_slot_function_type>();
if(fp && *fp == slot)
{
- (*it)->nolock_disconnect();
+ (*it)->nolock_disconnect(lock);
}
}
}
}
// connect slot
- connection nolock_connect(const slot_type &slot, connect_position position)
+ connection nolock_connect(garbage_collecting_lock<mutex_type> &lock,
+ const slot_type &slot, connect_position position)
{
connection_body_type newConnectionBody =
- create_new_connection(slot);
+ create_new_connection(lock, slot);
group_key_type group_key;
if(position == at_back)
{
@@ -557,11 +561,12 @@ namespace boost
newConnectionBody->set_group_key(group_key);
return connection(newConnectionBody);
}
- connection nolock_connect(const group_type &group,
+ connection nolock_connect(garbage_collecting_lock<mutex_type> &lock,
+ const group_type &group,
const slot_type &slot, connect_position position)
{
connection_body_type newConnectionBody =
- create_new_connection(slot);
+ create_new_connection(lock, slot);
// update map to first connection body in group if needed
group_key_type group_key(grouped_slots, group);
newConnectionBody->set_group_key(group_key);
@@ -580,7 +585,7 @@ namespace boost
mutable typename connection_list_type::iterator _garbage_collector_it;
// connection list mutex must never be locked when attempting a blocking lock on a slot,
// or you could deadlock.
- mutable mutex_type _mutex;
+ const boost::shared_ptr<mutex_type> _mutex;
};
template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
@@ -789,7 +794,7 @@ namespace boost
shared_ptr<detail::BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
<BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> >
shared_pimpl(_weak_pimpl.lock());
- if(shared_pimpl == 0) boost::throw_exception(expired_slot());
+ if(shared_pimpl == 0) throw expired_slot();
return (*shared_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
}
result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
@@ -797,7 +802,7 @@ namespace boost
shared_ptr<detail::BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
<BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> >
shared_pimpl(_weak_pimpl.lock());
- if(shared_pimpl == 0) boost::throw_exception(expired_slot());
+ if(shared_pimpl == 0) throw expired_slot();
return (*shared_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
}
private:
diff --git a/boost/signals2/detail/slot_call_iterator.hpp b/boost/signals2/detail/slot_call_iterator.hpp
index 9dbbb3c9b5..ee8426f474 100644
--- a/boost/signals2/detail/slot_call_iterator.hpp
+++ b/boost/signals2/detail/slot_call_iterator.hpp
@@ -21,6 +21,8 @@
#include <boost/signals2/slot_base.hpp>
#include <boost/signals2/detail/auto_buffer.hpp>
#include <boost/signals2/detail/unique_lock.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
#include <boost/weak_ptr.hpp>
namespace boost {
@@ -33,14 +35,37 @@ namespace boost {
slot_call_iterator_cache(const Function &f_arg):
f(f_arg),
connected_slot_count(0),
- disconnected_slot_count(0)
+ disconnected_slot_count(0),
+ m_active_slot(0)
{}
+
+ ~slot_call_iterator_cache()
+ {
+ if(m_active_slot)
+ {
+ garbage_collecting_lock<connection_body_base> lock(*m_active_slot);
+ m_active_slot->dec_slot_refcount(lock);
+ }
+ }
+
+ template<typename M>
+ void set_active_slot(garbage_collecting_lock<M> &lock,
+ connection_body_base *active_slot)
+ {
+ if(m_active_slot)
+ m_active_slot->dec_slot_refcount(lock);
+ m_active_slot = active_slot;
+ if(m_active_slot)
+ m_active_slot->inc_slot_refcount(lock);
+ }
+
optional<ResultType> result;
typedef auto_buffer<void_shared_ptr_variant, store_n_objects<10> > tracked_ptrs_type;
tracked_ptrs_type tracked_ptrs;
Function f;
unsigned connected_slot_count;
unsigned disconnected_slot_count;
+ connection_body_base *m_active_slot;
};
// Generates a slot call iterator. Essentially, this is an iterator that:
@@ -52,21 +77,23 @@ namespace boost {
: public boost::iterator_facade<slot_call_iterator_t<Function, Iterator, ConnectionBody>,
typename Function::result_type,
boost::single_pass_traversal_tag,
- typename Function::result_type const&>
+ typename boost::add_const<typename boost::add_reference<typename Function::result_type>::type>::type >
{
typedef boost::iterator_facade<slot_call_iterator_t<Function, Iterator, ConnectionBody>,
typename Function::result_type,
boost::single_pass_traversal_tag,
- typename Function::result_type const&>
+ typename boost::add_const<typename boost::add_reference<typename Function::result_type>::type>::type >
inherited;
typedef typename Function::result_type result_type;
+ typedef slot_call_iterator_cache<result_type, Function> cache_type;
+
friend class boost::iterator_core_access;
public:
slot_call_iterator_t(Iterator iter_in, Iterator end_in,
- slot_call_iterator_cache<result_type, Function> &c):
+ cache_type &c):
iter(iter_in), end(end_in),
cache(&c), callable_iter(end_in)
{
@@ -103,19 +130,39 @@ namespace boost {
}
private:
- typedef unique_lock<connection_body_base> lock_type;
+ typedef garbage_collecting_lock<connection_body_base> lock_type;
+ void set_callable_iter(lock_type &lock, Iterator newValue) const
+ {
+ callable_iter = newValue;
+ if(callable_iter == end)
+ cache->set_active_slot(lock, 0);
+ else
+ cache->set_active_slot(lock, (*callable_iter).get());
+ }
+
void lock_next_callable() const
{
if(iter == callable_iter)
{
return;
}
+ if(iter == end)
+ {
+ if(callable_iter != end)
+ {
+ lock_type lock(**callable_iter);
+ set_callable_iter(lock, end);
+ return;
+ }
+ }
+ // we're only locking the first connection body,
+ // but it doesn't matter they all use the same mutex
+ lock_type lock(**iter);
for(;iter != end; ++iter)
{
cache->tracked_ptrs.clear();
- lock_type lock(**iter);
- (*iter)->nolock_grab_tracked_objects(std::back_inserter(cache->tracked_ptrs));
+ (*iter)->nolock_grab_tracked_objects(lock, std::back_inserter(cache->tracked_ptrs));
if((*iter)->nolock_nograb_connected())
{
++cache->connected_slot_count;
@@ -125,19 +172,19 @@ namespace boost {
}
if((*iter)->nolock_nograb_blocked() == false)
{
- callable_iter = iter;
+ set_callable_iter(lock, iter);
break;
}
}
if(iter == end)
{
- callable_iter = end;
+ set_callable_iter(lock, end);
}
}
mutable Iterator iter;
Iterator end;
- slot_call_iterator_cache<result_type, Function> *cache;
+ cache_type *cache;
mutable Iterator callable_iter;
};
} // end namespace detail
diff --git a/boost/signals2/detail/variadic_slot_invoker.hpp b/boost/signals2/detail/variadic_slot_invoker.hpp
index cab331eb1c..c115a63df5 100644
--- a/boost/signals2/detail/variadic_slot_invoker.hpp
+++ b/boost/signals2/detail/variadic_slot_invoker.hpp
@@ -77,17 +77,20 @@ namespace boost
R operator()(Func &func, BOOST_SIGNALS2_TUPLE<Args...> args, mpl::size_t<N>) const
{
typedef typename make_unsigned_meta_array<N>::type indices_type;
- typename Func::result_type *resolver = 0;
- return m_invoke(resolver, func, indices_type(), args);
+ return m_invoke<Func>(func, indices_type(), args);
}
private:
- template<typename T, typename Func, unsigned ... indices, typename ... Args>
- R m_invoke(T *, Func &func, unsigned_meta_array<indices...>, BOOST_SIGNALS2_TUPLE<Args...> args) const
+ template<typename Func, unsigned ... indices, typename ... Args>
+ R m_invoke(Func &func, unsigned_meta_array<indices...>, BOOST_SIGNALS2_TUPLE<Args...> args,
+ typename boost::disable_if<boost::is_void<typename Func::result_type> >::type * = 0
+ ) const
{
return func(BOOST_SIGNALS2_GET<indices>(args)...);
}
template<typename Func, unsigned ... indices, typename ... Args>
- R m_invoke(void *, Func &func, unsigned_meta_array<indices...>, BOOST_SIGNALS2_TUPLE<Args...> args) const
+ R m_invoke(Func &func, unsigned_meta_array<indices...>, BOOST_SIGNALS2_TUPLE<Args...> args,
+ typename boost::enable_if<boost::is_void<typename Func::result_type> >::type * = 0
+ ) const
{
func(BOOST_SIGNALS2_GET<indices>(args)...);
return R();
@@ -97,7 +100,9 @@ namespace boost
// only exists to quiet some unused parameter warnings
// on certain compilers (some versions of gcc and msvc)
template<typename Func>
- R m_invoke(void *, Func &func, unsigned_meta_array<>, BOOST_SIGNALS2_TUPLE<>) const
+ R m_invoke(Func &func, unsigned_meta_array<>, BOOST_SIGNALS2_TUPLE<>,
+ typename boost::enable_if<boost::is_void<typename Func::result_type> >::type * = 0
+ ) const
{
func();
return R();
@@ -115,22 +120,10 @@ namespace boost
template<typename ConnectionBodyType>
result_type operator ()(const ConnectionBodyType &connectionBody) const
{
- result_type *resolver = 0;
- return m_invoke(connectionBody,
- resolver);
+ return call_with_tuple_args<result_type>()(connectionBody->slot().slot_function(),
+ _args, mpl::size_t<sizeof...(Args)>());
}
private:
- template<typename ConnectionBodyType>
- result_type m_invoke(const ConnectionBodyType &connectionBody,
- const void_type *) const
- {
- return call_with_tuple_args<result_type>()(connectionBody->slot.slot_function(), _args, mpl::size_t<sizeof...(Args)>());
- }
- template<typename ConnectionBodyType>
- result_type m_invoke(const ConnectionBodyType &connectionBody, ...) const
- {
- return call_with_tuple_args<result_type>()(connectionBody->slot.slot_function(), _args, mpl::size_t<sizeof...(Args)>());
- }
BOOST_SIGNALS2_TUPLE<Args& ...> _args;
};
} // namespace detail
diff --git a/boost/signals2/last_value.hpp b/boost/signals2/last_value.hpp
index 51cc541a4e..c5d5f33b21 100644
--- a/boost/signals2/last_value.hpp
+++ b/boost/signals2/last_value.hpp
@@ -13,7 +13,6 @@
#include <boost/optional.hpp>
#include <boost/signals2/expired_slot.hpp>
-#include <boost/throw_exception.hpp>
#include <stdexcept>
namespace boost {
@@ -37,7 +36,7 @@ namespace boost {
{
if(first == last)
{
- boost::throw_exception(no_slots_error());
+ throw no_slots_error();
}
optional<T> value;
while (first != last)
@@ -50,7 +49,7 @@ namespace boost {
++first;
}
if(value) return value.get();
- boost::throw_exception(no_slots_error());
+ throw no_slots_error();
}
};
diff --git a/boost/signals2/preprocessed_signal.hpp b/boost/signals2/preprocessed_signal.hpp
index 28471ba4ae..794c1be67e 100644
--- a/boost/signals2/preprocessed_signal.hpp
+++ b/boost/signals2/preprocessed_signal.hpp
@@ -22,6 +22,8 @@
#include <boost/preprocessor/repetition.hpp>
#include <boost/signals2/detail/preprocessed_arg_type.hpp>
#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/utility/enable_if.hpp>
#define BOOST_PP_ITERATION_LIMITS (0, BOOST_SIGNALS2_MAX_ARGS)
#define BOOST_PP_FILENAME_1 <boost/signals2/detail/signal_template.hpp>
diff --git a/boost/signals2/signal.hpp b/boost/signals2/signal.hpp
index 7abcea6241..afdfa66343 100644
--- a/boost/signals2/signal.hpp
+++ b/boost/signals2/signal.hpp
@@ -30,7 +30,6 @@
#include <boost/signals2/optional_last_value.hpp>
#include <boost/signals2/mutex.hpp>
#include <boost/signals2/slot.hpp>
-#include <boost/throw_exception.hpp>
#include <functional>
#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
diff --git a/boost/signals2/slot_base.hpp b/boost/signals2/slot_base.hpp
index e297180e49..0dd80db146 100644
--- a/boost/signals2/slot_base.hpp
+++ b/boost/signals2/slot_base.hpp
@@ -17,7 +17,6 @@
#include <boost/signals2/detail/foreign_ptr.hpp>
#include <boost/signals2/expired_slot.hpp>
#include <boost/signals2/signal_base.hpp>
-#include <boost/throw_exception.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/variant.hpp>
#include <vector>
@@ -77,7 +76,7 @@ namespace boost
locked_objects.push_back(apply_visitor(detail::lock_weak_ptr_visitor(), *it));
if(apply_visitor(detail::expired_weak_ptr_visitor(), *it))
{
- boost::throw_exception(expired_slot());
+ throw expired_slot();
}
}
return locked_objects;
diff --git a/boost/signals2/variadic_signal.hpp b/boost/signals2/variadic_signal.hpp
index d7d26193a6..8cd81f7a59 100644
--- a/boost/signals2/variadic_signal.hpp
+++ b/boost/signals2/variadic_signal.hpp
@@ -20,6 +20,8 @@
#include <boost/signals2/detail/variadic_arg_type.hpp>
#include <boost/signals2/detail/variadic_slot_invoker.hpp>
#include <boost/type_traits/function_traits.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/utility/enable_if.hpp>
namespace boost
{
diff --git a/boost/smart_ptr/detail/shared_count.hpp b/boost/smart_ptr/detail/shared_count.hpp
index 1e7d688c1a..cd07ed65fc 100644
--- a/boost/smart_ptr/detail/shared_count.hpp
+++ b/boost/smart_ptr/detail/shared_count.hpp
@@ -40,13 +40,18 @@
# include <new> // std::bad_alloc
#endif
-#if !defined( BOOST_NO_CXX11_SMART_PTR )
-# include <boost/utility/addressof.hpp>
-#endif
+#include <boost/core/addressof.hpp>
namespace boost
{
+namespace movelib
+{
+
+ template< class T, class D > class unique_ptr;
+
+} // namespace movelib
+
namespace detail
{
@@ -63,8 +68,6 @@ template< class D > struct sp_inplace_tag
{
};
-#if !defined( BOOST_NO_CXX11_SMART_PTR )
-
template< class T > class sp_reference_wrapper
{
public:
@@ -93,8 +96,6 @@ template< class D > struct sp_convert_reference< D& >
typedef sp_reference_wrapper< D > type;
};
-#endif
-
class weak_count;
class shared_count
@@ -438,6 +439,29 @@ public:
#endif
+ template<class Y, class D>
+ explicit shared_count( boost::movelib::unique_ptr<Y, D> & r ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ typedef typename sp_convert_reference<D>::type D2;
+
+ D2 d2( r.get_deleter() );
+ pi_ = new sp_counted_impl_pd< typename boost::movelib::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
+
+#ifdef BOOST_NO_EXCEPTIONS
+
+ if( pi_ == 0 )
+ {
+ boost::throw_exception( std::bad_alloc() );
+ }
+
+#endif
+
+ r.release();
+ }
+
~shared_count() // nothrow
{
if( pi_ != 0 ) pi_->release();
diff --git a/boost/smart_ptr/detail/spinlock_gcc_arm.hpp b/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
index 016796a91d..24d08a8815 100644
--- a/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
+++ b/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
@@ -82,6 +82,7 @@ public:
{
__asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
*const_cast< int volatile* >( &v_ ) = 0;
+ __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
}
public:
diff --git a/boost/smart_ptr/shared_ptr.hpp b/boost/smart_ptr/shared_ptr.hpp
index 8be92abb5d..991ca3dad3 100644
--- a/boost/smart_ptr/shared_ptr.hpp
+++ b/boost/smart_ptr/shared_ptr.hpp
@@ -55,6 +55,13 @@ template<class T> class weak_ptr;
template<class T> class enable_shared_from_this;
class enable_shared_from_raw;
+namespace movelib
+{
+
+ template< class T, class D > class unique_ptr;
+
+} // namespace movelib
+
namespace detail
{
@@ -495,6 +502,17 @@ public:
#endif
+ template< class Y, class D >
+ shared_ptr( boost::movelib::unique_ptr< Y, D > r ): px( r.get() ), pn()
+ {
+ boost::detail::sp_assert_convertible< Y, T >();
+
+ typename boost::movelib::unique_ptr< Y, D >::pointer tmp = r.get();
+ pn = boost::detail::shared_count( r );
+
+ boost::detail::sp_deleter_construct( this, tmp );
+ }
+
// assignment
shared_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT
@@ -556,6 +574,27 @@ public:
#endif
+ template<class Y, class D>
+ shared_ptr & operator=( boost::movelib::unique_ptr<Y, D> r )
+ {
+ // this_type( static_cast< unique_ptr<Y, D> && >( r ) ).swap( *this );
+
+ boost::detail::sp_assert_convertible< Y, T >();
+
+ typename boost::movelib::unique_ptr< Y, D >::pointer p = r.get();
+
+ shared_ptr tmp;
+
+ tmp.px = p;
+ tmp.pn = boost::detail::shared_count( r );
+
+ boost::detail::sp_deleter_construct( &tmp, p );
+
+ tmp.swap( *this );
+
+ return *this;
+ }
+
// Move support
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
diff --git a/boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp b/boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp
index b26f534751..1f18b3255c 100644
--- a/boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp
+++ b/boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp
@@ -23,6 +23,7 @@
#include <boost/spirit/home/classic/core/non_terminal/impl/static.hpp>
#include <boost/thread/tss.hpp>
#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_types.hpp>
#endif
///////////////////////////////////////////////////////////////////////////////
@@ -159,7 +160,7 @@ struct grammar_definition
result(new definition_t(target_grammar->derived()));
#ifdef BOOST_SPIRIT_THREADSAFE
- boost::mutex::scoped_lock lock(helpers.mutex());
+ boost::unique_lock<boost::mutex> lock(helpers.mutex());
#endif
helpers.push_back(this);
diff --git a/boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp b/boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp
index 822180a977..c39d359cbd 100644
--- a/boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp
+++ b/boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp
@@ -15,6 +15,7 @@
#ifdef BOOST_SPIRIT_THREADSAFE
#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_types.hpp>
#include <boost/thread/once.hpp>
#endif
@@ -99,7 +100,7 @@ BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
object_with_id_base_supply<IdT>::acquire()
{
#ifdef BOOST_SPIRIT_THREADSAFE
- boost::mutex::scoped_lock lock(mutex);
+ boost::unique_lock<boost::mutex> lock(mutex);
#endif
if (free_ids.size())
{
@@ -121,7 +122,7 @@ BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
object_with_id_base_supply<IdT>::release(IdT id)
{
#ifdef BOOST_SPIRIT_THREADSAFE
- boost::mutex::scoped_lock lock(mutex);
+ boost::unique_lock<boost::mutex> lock(mutex);
#endif
if (max_id == id)
max_id--;
@@ -136,10 +137,14 @@ BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
{
{
#ifdef BOOST_SPIRIT_THREADSAFE
+#ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11
static boost::once_flag been_here = BOOST_ONCE_INIT;
+#else
+ static boost::once_flag been_here;
+#endif
boost::call_once(been_here, mutex_init);
boost::mutex &mutex = mutex_instance();
- boost::mutex::scoped_lock lock(mutex);
+ boost::unique_lock<boost::mutex> lock(mutex);
#endif
static boost::shared_ptr<object_with_id_base_supply<IdT> >
static_supply;
diff --git a/boost/spirit/home/classic/core/non_terminal/impl/static.hpp b/boost/spirit/home/classic/core/non_terminal/impl/static.hpp
index 89c6d29c3c..ae2a66c506 100644
--- a/boost/spirit/home/classic/core/non_terminal/impl/static.hpp
+++ b/boost/spirit/home/classic/core/non_terminal/impl/static.hpp
@@ -111,7 +111,11 @@ BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
typename static_<T, Tag>::storage_type static_<T, Tag>::data_;
template <class T, class Tag>
+#ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11
once_flag static_<T, Tag>::constructed_ = BOOST_ONCE_INIT;
+#else
+ once_flag static_<T, Tag>::constructed_;
+#endif
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
diff --git a/boost/spirit/home/classic/core/primitives/primitives.hpp b/boost/spirit/home/classic/core/primitives/primitives.hpp
index d89585b102..cd87c3dda8 100644
--- a/boost/spirit/home/classic/core/primitives/primitives.hpp
+++ b/boost/spirit/home/classic/core/primitives/primitives.hpp
@@ -47,7 +47,6 @@ BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
- typedef typename parser_result<self_t, ScannerT>::type result_t;
typedef typename ScannerT::value_t value_t;
typedef typename ScannerT::iterator_t iterator_t;
diff --git a/boost/spirit/home/classic/meta/refactoring.hpp b/boost/spirit/home/classic/meta/refactoring.hpp
index e5d45f9297..fa45b01548 100644
--- a/boost/spirit/home/classic/meta/refactoring.hpp
+++ b/boost/spirit/home/classic/meta/refactoring.hpp
@@ -197,7 +197,7 @@ const refactor_action_gen<> refactor_action_d = refactor_action_gen<>();
// attach_action_parser class
//
// This helper template allows to attach an action given separately
-// to to all parsers, out of which the given parser is constructed and
+// to all parsers, out of which the given parser is constructed and
// reconstructs a new parser having the same structure.
//
// For instance the parser:
@@ -208,7 +208,7 @@ const refactor_action_gen<> refactor_action_d = refactor_action_gen<>();
// >> another_parser[some_attached_functor]
//
// The original parser should be a action_parser_category parser,
-// else the compilation will fail
+// else the compilation will fail.
//
// If the parser, to which the action is attached is not an binary parser,
// no refactoring is done at all.
diff --git a/boost/spirit/home/classic/phoenix/closures.hpp b/boost/spirit/home/classic/phoenix/closures.hpp
index 6493e387a3..f833b4ef59 100644
--- a/boost/spirit/home/classic/phoenix/closures.hpp
+++ b/boost/spirit/home/classic/phoenix/closures.hpp
@@ -419,7 +419,11 @@ private:
closure_frame_holder_ref(holder_t* holder_ = 0)
{
#ifdef PHOENIX_THREADSAFE
+#ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11
static boost::once_flag been_here = BOOST_ONCE_INIT;
+#else
+ static boost::once_flag been_here;
+#endif
boost::call_once(been_here, tsp_frame_instance_init);
boost::thread_specific_ptr<holder_t*> &tsp_frame = tsp_frame_instance();
if (!tsp_frame.get())
diff --git a/boost/spirit/home/classic/phoenix/statements.hpp b/boost/spirit/home/classic/phoenix/statements.hpp
index 7726a99d4b..dd62cb2ebb 100644
--- a/boost/spirit/home/classic/phoenix/statements.hpp
+++ b/boost/spirit/home/classic/phoenix/statements.hpp
@@ -285,7 +285,7 @@ while_(CondT const& cond)
// While the condition (an actor) evaluates to true, statement
// (another actor) is executed. The statement is executed at least
// once. The result type of this is void. Note the trailing
-// underscore after do_ and the the leading dot and the trailing
+// underscore after do_ and the leading dot and the trailing
// underscore before and after .while_.
//
///////////////////////////////////////////////////////////////////////////////
diff --git a/boost/spirit/home/classic/utility/functor_parser.hpp b/boost/spirit/home/classic/utility/functor_parser.hpp
index ac53751bcc..e991eaf7d7 100644
--- a/boost/spirit/home/classic/utility/functor_parser.hpp
+++ b/boost/spirit/home/classic/utility/functor_parser.hpp
@@ -49,8 +49,6 @@ BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
- typedef typename parser_result<self_t, ScannerT>::type result_t;
- typedef typename ScannerT::value_t value_t;
typedef typename ScannerT::iterator_t iterator_t;
iterator_t const s(scan.first);
diff --git a/boost/spirit/home/classic/utility/impl/chset.ipp b/boost/spirit/home/classic/utility/impl/chset.ipp
index 6e2130b222..f6da6f2f3f 100644
--- a/boost/spirit/home/classic/utility/impl/chset.ipp
+++ b/boost/spirit/home/classic/utility/impl/chset.ipp
@@ -97,7 +97,7 @@ inline chset<CharT>::chset(anychar_parser /*arg*/)
}
template <typename CharT>
-inline chset<CharT>::chset(nothing_parser arg_)
+inline chset<CharT>::chset(nothing_parser /*arg_*/)
: ptr(new basic_chset<CharT>()) {}
template <typename CharT>
@@ -146,7 +146,7 @@ chset<CharT>::operator=(CharT rhs)
template <typename CharT>
inline chset<CharT>&
-chset<CharT>::operator=(anychar_parser rhs)
+chset<CharT>::operator=(anychar_parser /*rhs*/)
{
utility::impl::detach_clear(ptr);
ptr->set(
@@ -158,7 +158,7 @@ chset<CharT>::operator=(anychar_parser rhs)
template <typename CharT>
inline chset<CharT>&
-chset<CharT>::operator=(nothing_parser rhs)
+chset<CharT>::operator=(nothing_parser /*rhs*/)
{
utility::impl::detach_clear(ptr);
return *this;
diff --git a/boost/spirit/home/classic/utility/scoped_lock.hpp b/boost/spirit/home/classic/utility/scoped_lock.hpp
index 952fd8785e..6e521692ae 100644
--- a/boost/spirit/home/classic/utility/scoped_lock.hpp
+++ b/boost/spirit/home/classic/utility/scoped_lock.hpp
@@ -10,6 +10,7 @@
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/namespace.hpp>
+#include <boost/thread/lock_types.hpp>
#if !defined(BOOST_SPIRIT_COMPOSITE_HPP)
#include <boost/spirit/home/classic/core/composite.hpp>
#endif
@@ -51,7 +52,7 @@ BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const &scan) const
{
- typedef typename mutex_t::scoped_lock scoped_lock_t;
+ typedef boost::unique_lock<mutex_t> scoped_lock_t;
scoped_lock_t lock(mutex);
return this->subject().parse(scan);
}
diff --git a/boost/spirit/home/karma/detail/output_iterator.hpp b/boost/spirit/home/karma/detail/output_iterator.hpp
index f49c8a0407..87980b7690 100644
--- a/boost/spirit/home/karma/detail/output_iterator.hpp
+++ b/boost/spirit/home/karma/detail/output_iterator.hpp
@@ -79,6 +79,18 @@ namespace boost { namespace spirit { namespace karma { namespace detail
return track_position_data.get_count();
}
+ // return the current line in the output
+ std::size_t get_line() const
+ {
+ return track_position_data.get_line();
+ }
+
+ // return the current column in the output
+ std::size_t get_column() const
+ {
+ return track_position_data.get_column();
+ }
+
private:
position_sink track_position_data; // for position tracking
};
diff --git a/boost/spirit/home/karma/detail/string_generate.hpp b/boost/spirit/home/karma/detail/string_generate.hpp
index d0f8a73fee..7acfbe1a1f 100644
--- a/boost/spirit/home/karma/detail/string_generate.hpp
+++ b/boost/spirit/home/karma/detail/string_generate.hpp
@@ -59,7 +59,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail
typedef typename traits::container_iterator<Container const>::type
iterator;
- iterator end = boost::end(c);
+ const iterator end = boost::end(c);
for (iterator it = boost::begin(c); it != end; ++it)
{
*sink = filter(*it);
@@ -76,14 +76,6 @@ namespace boost { namespace spirit { namespace karma { namespace detail
return string_generate(sink, str, pass_through_filter());
}
- template <typename OutputIterator, typename Char, typename Traits
- , typename Allocator>
- inline bool string_generate(OutputIterator& sink
- , std::basic_string<Char, Traits, Allocator> const& str)
- {
- return string_generate(sink, str.c_str(), pass_through_filter());
- }
-
template <typename OutputIterator, typename Container>
inline bool string_generate(OutputIterator& sink
, Container const& c)
@@ -103,17 +95,6 @@ namespace boost { namespace spirit { namespace karma { namespace detail
return string_generate(sink, str, encoding_filter<CharEncoding, Tag>());
}
- template <typename OutputIterator, typename Char
- , typename CharEncoding, typename Tag
- , typename Traits, typename Allocator>
- inline bool string_generate(OutputIterator& sink
- , std::basic_string<Char, Traits, Allocator> const& str
- , CharEncoding, Tag)
- {
- return string_generate(sink, str.c_str()
- , encoding_filter<CharEncoding, Tag>());
- }
-
template <typename OutputIterator, typename Container
, typename CharEncoding, typename Tag>
inline bool
@@ -130,16 +111,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail
, Char const* str
, unused_type, unused_type)
{
- return string_generate(sink, str, pass_through_filter());
- }
-
- template <typename OutputIterator, typename Char, typename Traits
- , typename Allocator>
- inline bool string_generate(OutputIterator& sink
- , std::basic_string<Char, Traits, Allocator> const& str
- , unused_type, unused_type)
- {
- return string_generate(sink, str.c_str(), pass_through_filter());
+ return string_generate(sink, str);
}
template <typename OutputIterator, typename Container>
@@ -147,7 +119,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail
, Container const& c
, unused_type, unused_type)
{
- return string_generate(sink, c, pass_through_filter());
+ return string_generate(sink, c);
}
}}}}
diff --git a/boost/spirit/home/karma/nonterminal/rule.hpp b/boost/spirit/home/karma/nonterminal/rule.hpp
index 8660f442a8..99d195fa5f 100644
--- a/boost/spirit/home/karma/nonterminal/rule.hpp
+++ b/boost/spirit/home/karma/nonterminal/rule.hpp
@@ -42,6 +42,7 @@
#if defined(BOOST_MSVC)
# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
#endif
@@ -118,16 +119,16 @@ namespace boost { namespace spirit { namespace karma
karma::domain, template_params>::type
delimiter_type;
- // The rule's signature
- typedef typename
- spirit::detail::extract_sig<template_params>::type
- sig_type;
-
// The rule's encoding type
typedef typename
spirit::detail::extract_encoding<template_params>::type
encoding_type;
+ // The rule's signature
+ typedef typename
+ spirit::detail::extract_sig<template_params, encoding_type, karma::domain>::type
+ sig_type;
+
// This is the rule's attribute type
typedef typename
spirit::detail::attr_from_sig<sig_type>::type
diff --git a/boost/spirit/home/karma/numeric/detail/real_utils.hpp b/boost/spirit/home/karma/numeric/detail/real_utils.hpp
index 6acaf87707..526985d280 100644
--- a/boost/spirit/home/karma/numeric/detail/real_utils.hpp
+++ b/boost/spirit/home/karma/numeric/detail/real_utils.hpp
@@ -104,7 +104,7 @@ namespace boost { namespace spirit { namespace karma
long exp = traits::truncate_to_long::call(-dim);
if (exp != -dim)
++exp;
- dim = -exp;
+ dim = static_cast<U>(-exp);
n *= spirit::traits::pow10<U>(exp);
}
}
diff --git a/boost/spirit/home/lex/argument.hpp b/boost/spirit/home/lex/argument.hpp
index fbac3c1da5..072f596b08 100644
--- a/boost/spirit/home/lex/argument.hpp
+++ b/boost/spirit/home/lex/argument.hpp
@@ -93,16 +93,6 @@ namespace boost { namespace spirit { namespace lex
template <typename Env>
void eval(Env const& env) const
{
- typedef
- typename remove_reference<
- typename remove_const<
- typename mpl::at_c<typename Env::args_type, 4>::type
- >::type
- >::type
- context_type;
-
- typedef typename context_type::state_name_type string;
-
fusion::at_c<4>(env.args()).set_state_name(
traits::get_c_string(actor_.eval(env)));
}
diff --git a/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp b/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp
index dfad49b67a..6b36cc6942 100644
--- a/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp
+++ b/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp
@@ -168,7 +168,7 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl
std::size_t get_state() const { return 0; }
void set_state(std::size_t) {}
- void set_end(Iterator const& it) {}
+ void set_end(Iterator const& /*it*/) {}
Iterator& get_first() { return first_; }
Iterator const& get_first() const { return first_; }
diff --git a/boost/spirit/home/lex/lexer/string_token_def.hpp b/boost/spirit/home/lex/lexer/string_token_def.hpp
index 9eb987020c..47bd9a332c 100644
--- a/boost/spirit/home/lex/lexer/string_token_def.hpp
+++ b/boost/spirit/home/lex/lexer/string_token_def.hpp
@@ -101,7 +101,6 @@ namespace boost { namespace spirit { namespace lex
token_state_ = state_id;
- typedef typename LexerDef::id_type id_type;
if (IdType(~0) == id_)
id_ = IdType(lexdef.get_next_id());
diff --git a/boost/spirit/home/qi/nonterminal/rule.hpp b/boost/spirit/home/qi/nonterminal/rule.hpp
index 8dd42373b0..0901420312 100644
--- a/boost/spirit/home/qi/nonterminal/rule.hpp
+++ b/boost/spirit/home/qi/nonterminal/rule.hpp
@@ -111,16 +111,16 @@ namespace boost { namespace spirit { namespace qi
qi::domain, template_params>::type
skipper_type;
- // The rule's signature
- typedef typename
- spirit::detail::extract_sig<template_params>::type
- sig_type;
-
// The rule's encoding type
typedef typename
spirit::detail::extract_encoding<template_params>::type
encoding_type;
+ // The rule's signature
+ typedef typename
+ spirit::detail::extract_sig<template_params, encoding_type, qi::domain>::type
+ sig_type;
+
// This is the rule's attribute type
typedef typename
spirit::detail::attr_from_sig<sig_type>::type
diff --git a/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp b/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp
index 5137f87f10..7e96a3757f 100644
--- a/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp
+++ b/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp
@@ -2,7 +2,7 @@
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2011 Jan Frederick Eick
- Copyright (c) 2011 Christopher Jefferson
+ Copyright (c) 2011 Christopher Jefferson
Copyright (c) 2006 Stephen Nutt
Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -32,6 +32,11 @@
#include <boost/mpl/and.hpp>
#include <boost/limits.hpp>
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
#if !defined(SPIRIT_NUMERICS_LOOP_UNROLL)
# define SPIRIT_NUMERICS_LOOP_UNROLL 3
#endif
@@ -132,6 +137,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail
// Ensure n *= Radix will not overflow
static T const max = (std::numeric_limits<T>::max)();
static T const val = max / Radix;
+
if (n > val)
return false;
@@ -181,7 +187,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail
///////////////////////////////////////////////////////////////////////////
// Common code for extract_int::parse specializations
///////////////////////////////////////////////////////////////////////////
- template <unsigned Radix, typename Accumulator, int MaxDigits>
+ template <unsigned Radix, typename Accumulator, int MaxDigits, bool AlwaysCheckOverflow>
struct int_extractor
{
template <typename Char, typename T>
@@ -191,7 +197,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail
static std::size_t const
overflow_free = digits_traits<T, Radix>::value - 1;
- if (count < overflow_free)
+ if (!AlwaysCheckOverflow && (count < overflow_free))
{
Accumulator::add(n, ch, mpl::false_());
}
@@ -267,8 +273,15 @@ namespace boost { namespace spirit { namespace qi { namespace detail
|| it == last) \
break; \
ch = *it; \
- if (!radix_check::is_valid(ch) || !extractor::call(ch, count, val)) \
+ if (!radix_check::is_valid(ch)) \
break; \
+ if (!extractor::call(ch, count, val)) \
+ { \
+ if (IgnoreOverflowDigits) \
+ first = it; \
+ traits::assign_to(val, attr); \
+ return IgnoreOverflowDigits; \
+ } \
++it; \
++count; \
/**/
@@ -277,6 +290,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail
typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
, typename Accumulator = positive_accumulator<Radix>
, bool Accumulate = false
+ , bool IgnoreOverflowDigits = false
>
struct extract_int
{
@@ -292,7 +306,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail
, Attribute& attr)
{
typedef radix_traits<Radix> radix_check;
- typedef int_extractor<Radix, Accumulator, MaxDigits> extractor;
+ typedef int_extractor<Radix, Accumulator, MaxDigits, Accumulate> extractor;
typedef typename
boost::detail::iterator_traits<Iterator>::value_type
char_type;
@@ -370,7 +384,10 @@ namespace boost { namespace spirit { namespace qi { namespace detail
if (!radix_check::is_valid(ch)) \
break; \
if (!extractor::call(ch, count, val)) \
+ { \
+ traits::assign_to(val, attr); \
return false; \
+ } \
++it; \
++count; \
/**/
@@ -390,7 +407,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail
, Attribute& attr)
{
typedef radix_traits<Radix> radix_check;
- typedef int_extractor<Radix, Accumulator, -1> extractor;
+ typedef int_extractor<Radix, Accumulator, -1, Accumulate> extractor;
typedef typename
boost::detail::iterator_traits<Iterator>::value_type
char_type;
@@ -432,7 +449,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail
return true;
}
- count = 0;
+ // count = 0; $$$ verify: I think this is wrong $$$
++it;
while (true)
{
@@ -503,4 +520,8 @@ namespace boost { namespace spirit { namespace qi { namespace detail
};
}}}}
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
#endif
diff --git a/boost/spirit/home/qi/numeric/detail/real_impl.hpp b/boost/spirit/home/qi/numeric/detail/real_impl.hpp
index a4bd8789b6..cf92712a24 100644
--- a/boost/spirit/home/qi/numeric/detail/real_impl.hpp
+++ b/boost/spirit/home/qi/numeric/detail/real_impl.hpp
@@ -20,6 +20,7 @@
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/detail/pow10.hpp>
#include <boost/spirit/home/support/detail/sign.hpp>
+#include <boost/integer.hpp>
#include <boost/assert.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
@@ -31,49 +32,89 @@
namespace boost { namespace spirit { namespace traits
{
using spirit::traits::pow10;
+
+ namespace detail
+ {
+ template <typename T, typename AccT>
+ void compensate_roundoff(T& n, AccT acc_n, mpl::true_)
+ {
+ // at the lowest extremes, we compensate for floating point
+ // roundoff errors by doing imprecise computation using T
+ int const comp = 10;
+ n = T((acc_n / comp) * comp);
+ n += T(acc_n % comp);
+ }
+
+ template <typename T, typename AccT>
+ void compensate_roundoff(T& n, AccT acc_n, mpl::false_)
+ {
+ // no need to compensate
+ n = acc_n;
+ }
+
+ template <typename T, typename AccT>
+ void compensate_roundoff(T& n, AccT acc_n)
+ {
+ compensate_roundoff(n, acc_n, is_integral<AccT>());
+ }
+ }
- template <typename T>
- inline void
- scale(int exp, T& n)
+ template <typename T, typename AccT>
+ inline bool
+ scale(int exp, T& n, AccT acc_n)
{
if (exp >= 0)
{
- // $$$ Why is this failing for boost.math.concepts ? $$$
- //~ int nn = std::numeric_limits<T>::max_exponent10;
- //~ BOOST_ASSERT(exp <= std::numeric_limits<T>::max_exponent10);
- n *= pow10<T>(exp);
+ std::size_t max_exp = std::numeric_limits<T>::max_exponent10;
+
+ // return false if exp exceeds the max_exp
+ // do this check only for primitive types!
+ if (is_floating_point<T>() && exp > max_exp)
+ return false;
+ n = acc_n * pow10<T>(exp);
}
else
{
if (exp < std::numeric_limits<T>::min_exponent10)
{
- n /= pow10<T>(-std::numeric_limits<T>::min_exponent10);
- n /= pow10<T>(-exp + std::numeric_limits<T>::min_exponent10);
+ int min_exp = std::numeric_limits<T>::min_exponent10;
+ detail::compensate_roundoff(n, acc_n);
+ n /= pow10<T>(-min_exp);
+
+ // return false if (-exp + min_exp) exceeds the -min_exp
+ // do this check only for primitive types!
+ if (is_floating_point<T>() && (-exp + min_exp) > -min_exp)
+ return false;
+
+ n /= pow10<T>(-exp + min_exp);
}
else
{
- n /= pow10<T>(-exp);
+ n = T(acc_n) / pow10<T>(-exp);
}
}
+ return true;
}
- inline void
- scale(int /*exp*/, unused_type /*n*/)
+ inline bool
+ scale(int /*exp*/, unused_type /*n*/, unused_type /*acc_n*/)
{
// no-op for unused_type
+ return true;
}
- template <typename T>
- inline void
- scale(int exp, int frac, T& n)
+ template <typename T, typename AccT>
+ inline bool
+ scale(int exp, int frac, T& n, AccT acc_n)
{
- scale(exp - frac, n);
+ return scale(exp - frac, n, acc_n);
}
- inline void
+ inline bool
scale(int /*exp*/, int /*frac*/, unused_type /*n*/)
{
// no-op for unused_type
+ return true;
}
inline float
@@ -121,6 +162,17 @@ namespace boost { namespace spirit { namespace traits
// no-op for unused_type
return false;
}
+
+ template <typename T>
+ struct real_accumulator : mpl::identity<T> {};
+
+ template <>
+ struct real_accumulator<float>
+ : mpl::identity<uint_t<(sizeof(float)*CHAR_BIT)>::least> {};
+
+ template <>
+ struct real_accumulator<double>
+ : mpl::identity<uint_t<(sizeof(double)*CHAR_BIT)>::least> {};
}}}
namespace boost { namespace spirit { namespace qi { namespace detail
@@ -142,8 +194,10 @@ namespace boost { namespace spirit { namespace qi { namespace detail
bool neg = p.parse_sign(first, last);
// Now attempt to parse an integer
- T n = 0;
- bool got_a_number = p.parse_n(first, last, n);
+ T n;
+
+ typename traits::real_accumulator<T>::type acc_n = 0;
+ bool got_a_number = p.parse_n(first, last, acc_n);
// If we did not get a number it might be a NaN, Inf or a leading
// dot.
@@ -168,6 +222,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail
}
bool e_hit = false;
+ Iterator e_pos;
int frac_digits = 0;
// Try to parse the dot ('.' decimal point)
@@ -176,14 +231,8 @@ namespace boost { namespace spirit { namespace qi { namespace detail
// We got the decimal point. Now we will try to parse
// the fraction if it is there. If not, it defaults
// to zero (0) only if we already got a number.
- Iterator savef = first;
- if (p.parse_frac_n(first, last, n))
+ if (p.parse_frac_n(first, last, acc_n, frac_digits))
{
- // Optimization note: don't compute frac_digits if T is
- // an unused_type. This should be optimized away by the compiler.
- if (!is_same<T, unused_type>::value)
- frac_digits =
- static_cast<int>(std::distance(savef, first));
}
else if (!got_a_number || !p.allow_trailing_dot)
{
@@ -195,6 +244,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail
}
// Now, let's see if we can parse the exponent prefix
+ e_pos = first;
e_hit = p.parse_exp(first, last);
}
else
@@ -208,6 +258,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail
// If we must expect a dot and we didn't see an exponent
// prefix, return no-match.
+ e_pos = first;
e_hit = p.parse_exp(first, last);
if (p.expect_dot && !e_hit)
{
@@ -219,27 +270,29 @@ namespace boost { namespace spirit { namespace qi { namespace detail
if (e_hit)
{
// We got the exponent prefix. Now we will try to parse the
- // actual exponent. It is an error if it is not there.
+ // actual exponent.
int exp = 0;
if (p.parse_exp_n(first, last, exp))
{
// Got the exponent value. Scale the number by
// exp-frac_digits.
- traits::scale(exp, frac_digits, n);
+ if (!traits::scale(exp, frac_digits, n, acc_n))
+ return false;
}
else
{
- // Oops, no exponent, return no-match.
- first = save;
- return false;
+ // If there is no number, disregard the exponent altogether.
+ // by resetting 'first' prior to the exponent prefix (e|E)
+ first = e_pos;
+ n = acc_n;
}
}
else if (frac_digits)
{
// No exponent found. Scale the number by -frac_digits.
- traits::scale(-frac_digits, n);
+ traits::scale(-frac_digits, n, acc_n);
}
- else if (traits::is_equal_to_one(n))
+ else if (traits::is_equal_to_one(acc_n))
{
// There is a chance of having to parse one of the 1.0#...
// styles some implementations use for representing NaN or Inf.
@@ -252,6 +305,12 @@ namespace boost { namespace spirit { namespace qi { namespace detail
traits::assign_to(traits::negate(neg, n), attr);
return true; // got a NaN or Inf, return immediately
}
+
+ n = acc_n;
+ }
+ else
+ {
+ n = acc_n;
}
// If we got a negative sign, negate the number
diff --git a/boost/spirit/home/qi/numeric/numeric_utils.hpp b/boost/spirit/home/qi/numeric/numeric_utils.hpp
index eebf40a0fa..c37044a3b6 100644
--- a/boost/spirit/home/qi/numeric/numeric_utils.hpp
+++ b/boost/spirit/home/qi/numeric/numeric_utils.hpp
@@ -44,7 +44,7 @@ namespace boost { namespace spirit { namespace qi
// Low level unsigned integer parser
///////////////////////////////////////////////////////////////////////////
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
- , bool Accumulate = false>
+ , bool Accumulate = false, bool IgnoreOverflowDigits = false>
struct extract_uint
{
// check template parameter 'Radix' for validity
@@ -64,7 +64,8 @@ namespace boost { namespace spirit { namespace qi
, MinDigits
, MaxDigits
, detail::positive_accumulator<Radix>
- , Accumulate>
+ , Accumulate
+ , IgnoreOverflowDigits>
extract_type;
Iterator save = first;
diff --git a/boost/spirit/home/qi/numeric/real_policies.hpp b/boost/spirit/home/qi/numeric/real_policies.hpp
index d4f5654b5b..d73a9dce8a 100644
--- a/boost/spirit/home/qi/numeric/real_policies.hpp
+++ b/boost/spirit/home/qi/numeric/real_policies.hpp
@@ -39,7 +39,7 @@ namespace boost { namespace spirit { namespace qi
static bool
parse_n(Iterator& first, Iterator const& last, Attribute& attr_)
{
- return extract_uint<T, 10, 1, -1>::call(first, last, attr_);
+ return extract_uint<Attribute, 10, 1, -1>::call(first, last, attr_);
}
template <typename Iterator>
@@ -54,9 +54,21 @@ namespace boost { namespace spirit { namespace qi
template <typename Iterator, typename Attribute>
static bool
- parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr_)
+ parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr_, int& frac_digits)
{
- return extract_uint<T, 10, 1, -1, true>::call(first, last, attr_);
+ Iterator savef = first;
+ bool r = extract_uint<Attribute, 10, 1, -1, true, true>::call(first, last, attr_);
+ if (r)
+ {
+ // Optimization note: don't compute frac_digits if T is
+ // an unused_type. This should be optimized away by the compiler.
+ if (!is_same<T, unused_type>::value)
+ frac_digits =
+ static_cast<int>(std::distance(savef, first));
+ // ignore extra (non-significant digits)
+ extract_uint<unused_type, 10, 1, -1>::call(first, last, unused);
+ }
+ return r;
}
template <typename Iterator>
diff --git a/boost/spirit/home/support/char_class.hpp b/boost/spirit/home/support/char_class.hpp
index 574a25e7c7..c9c6e51c27 100644
--- a/boost/spirit/home/support/char_class.hpp
+++ b/boost/spirit/home/support/char_class.hpp
@@ -26,6 +26,7 @@
#if defined(BOOST_MSVC)
# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
# pragma warning(disable: 4800) // 'int' : forcing value to bool 'true' or 'false' warning
#endif
diff --git a/boost/spirit/home/support/detail/lexer/parser/parser.hpp b/boost/spirit/home/support/detail/lexer/parser/parser.hpp
index 9000e5e36e..5c3c650f71 100644
--- a/boost/spirit/home/support/detail/lexer/parser/parser.hpp
+++ b/boost/spirit/home/support/detail/lexer/parser/parser.hpp
@@ -87,7 +87,7 @@ Grammar:
default:
std::ostringstream ss_;
- ss_ << "A syntax error occured: '" <<
+ ss_ << "A syntax error occurred: '" <<
lhs_token_.precedence_string () <<
"' against '" << rhs_token_.precedence_string () <<
"' at index " << state_.index () << ".";
diff --git a/boost/spirit/home/support/detail/lexer/state_machine.hpp b/boost/spirit/home/support/detail/lexer/state_machine.hpp
index 46e50c9a0a..b96615e49a 100644
--- a/boost/spirit/home/support/detail/lexer/state_machine.hpp
+++ b/boost/spirit/home/support/detail/lexer/state_machine.hpp
@@ -82,7 +82,7 @@ public:
bol_index == rhs_.bol_index &&
eol_index == rhs_.eol_index &&
token == rhs_.token &&
- transition == rhs_.transition;
+ goto_state == rhs_.goto_state;
}
};
diff --git a/boost/spirit/home/support/extended_variant.hpp b/boost/spirit/home/support/extended_variant.hpp
index d23ca3d8b2..4d3ae599d6 100644
--- a/boost/spirit/home/support/extended_variant.hpp
+++ b/boost/spirit/home/support/extended_variant.hpp
@@ -29,19 +29,24 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
+#if defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
template <
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
- BOOST_VARIANT_LIMIT_TYPES,
+ BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES,
typename T, boost::detail::variant::void_)
// We should not be depending on detail::variant::void_
// but I'm not sure if this can fixed. Any other way is
// clumsy at best.
>
+#else
+ template <typename... Types>
+#endif
struct extended_variant
{
// tell spirit that this is an adapted variant
struct adapted_variant_tag;
+#if defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
typedef boost::variant<
BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)>
variant_type;
@@ -50,6 +55,11 @@ namespace boost { namespace spirit
typedef extended_variant<
BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)
> base_type;
+#else
+ typedef boost::variant<Types...> variant_type;
+ typedef typename variant_type::types types;
+ typedef extended_variant<Types...> base_type;
+#endif
extended_variant() : var() {}
@@ -101,6 +111,7 @@ namespace boost { namespace spirit
namespace boost
{
+#if defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
inline T const&
get(boost::spirit::extended_variant<
@@ -132,6 +143,35 @@ namespace boost
{
return boost::get<T>(&x->get());
}
+#else
+ template <typename T, typename... Types>
+ inline T const&
+ get(boost::spirit::extended_variant<Types...> const& x)
+ {
+ return boost::get<T>(x.get());
+ }
+
+ template <typename T, typename... Types>
+ inline T&
+ get(boost::spirit::extended_variant<Types...>& x)
+ {
+ return boost::get<T>(x.get());
+ }
+
+ template <typename T, typename... Types>
+ inline T const*
+ get(boost::spirit::extended_variant<Types...> const* x)
+ {
+ return boost::get<T>(&x->get());
+ }
+
+ template <typename T, typename... Types>
+ inline T*
+ get(boost::spirit::extended_variant<Types...>* x)
+ {
+ return boost::get<T>(&x->get());
+ }
+#endif
}
#undef BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS
diff --git a/boost/spirit/home/support/nonterminal/extract_param.hpp b/boost/spirit/home/support/nonterminal/extract_param.hpp
index 61499327a0..eeab61f3d1 100644
--- a/boost/spirit/home/support/nonterminal/extract_param.hpp
+++ b/boost/spirit/home/support/nonterminal/extract_param.hpp
@@ -29,6 +29,8 @@
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/and.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/is_same.hpp>
@@ -78,14 +80,37 @@ namespace boost { namespace spirit { namespace detail
{};
///////////////////////////////////////////////////////////////////////////
- template <typename Types>
+ template <typename T>
+ struct make_function_type : mpl::identity<T()> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Types, typename Encoding, typename Domain>
struct extract_sig
- : extract_param<
- Types
- , function_types::is_function<mpl::_>
- , void()
- >
- {};
+ {
+ typedef typename
+ extract_param<
+ Types
+ , mpl::or_<
+ function_types::is_function<mpl::_>
+ , mpl::and_<
+ mpl::not_<is_locals<mpl::_> >
+ , mpl::not_<is_same<mpl::_, Encoding> >
+ , mpl::not_<traits::matches<Domain, mpl::_> >
+ , mpl::not_<is_same<mpl::_, unused_type> >
+ >
+ >
+ , void()
+ >::type
+ attr_of_ftype;
+
+ typedef typename
+ mpl::eval_if<
+ function_types::is_function<attr_of_ftype>
+ , mpl::identity<attr_of_ftype>
+ , make_function_type<attr_of_ftype>
+ >::type
+ type;
+ };
template <typename Sig>
struct attr_from_sig
diff --git a/boost/spirit/home/x3.hpp b/boost/spirit/home/x3.hpp
index 9da6057b96..09dd2d9a4d 100644
--- a/boost/spirit/home/x3.hpp
+++ b/boost/spirit/home/x3.hpp
@@ -11,17 +11,13 @@
#pragma once
#endif
-//~ #include <boost/spirit/home/x3/action.hpp>
-//~ #include <boost/spirit/home/x3/auto.hpp>
#include <boost/spirit/home/x3/auxiliary.hpp>
#include <boost/spirit/home/x3/char.hpp>
-//~ #include <boost/spirit/home/x3/binary.hpp>
#include <boost/spirit/home/x3/directive.hpp>
#include <boost/spirit/home/x3/nonterminal.hpp>
#include <boost/spirit/home/x3/numeric.hpp>
#include <boost/spirit/home/x3/operator.hpp>
#include <boost/spirit/home/x3/core.hpp>
#include <boost/spirit/home/x3/string.hpp>
-//~ #include <boost/spirit/home/x3/stream.hpp>
#endif
diff --git a/boost/spirit/home/x3/auxiliary.hpp b/boost/spirit/home/x3/auxiliary.hpp
index afa89b2883..baa8a94c8b 100644
--- a/boost/spirit/home/x3/auxiliary.hpp
+++ b/boost/spirit/home/x3/auxiliary.hpp
@@ -8,17 +8,11 @@
#if !defined(BOOST_SPIRIT_X3_AUXILIARY_FEBRUARY_03_2007_0355PM)
#define BOOST_SPIRIT_X3_AUXILIARY_FEBRUARY_03_2007_0355PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/auxiliary/any_parser.hpp>
#include <boost/spirit/home/x3/auxiliary/eps.hpp>
#include <boost/spirit/home/x3/auxiliary/guard.hpp>
-//~ #include <boost/spirit/home/x3/auxiliary/lazy.hpp>
#include <boost/spirit/home/x3/auxiliary/eol.hpp>
#include <boost/spirit/home/x3/auxiliary/eoi.hpp>
#include <boost/spirit/home/x3/auxiliary/attr.hpp>
-//~ #include <boost/spirit/home/x3/auxiliary/attr_cast.hpp>
#endif
diff --git a/boost/spirit/home/x3/auxiliary/any_parser.hpp b/boost/spirit/home/x3/auxiliary/any_parser.hpp
index 0e257c04b1..2f97d26da7 100644
--- a/boost/spirit/home/x3/auxiliary/any_parser.hpp
+++ b/boost/spirit/home/x3/auxiliary/any_parser.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_AUXILIARY_ANY_PARSER_APR_09_2014_1145PM)
#define BOOST_SPIRIT_X3_AUXILIARY_ANY_PARSER_APR_09_2014_1145PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/subcontext.hpp>
diff --git a/boost/spirit/home/x3/auxiliary/attr.hpp b/boost/spirit/home/x3/auxiliary/attr.hpp
index 364cca0bee..5b3c7a5d85 100644
--- a/boost/spirit/home/x3/auxiliary/attr.hpp
+++ b/boost/spirit/home/x3/auxiliary/attr.hpp
@@ -9,10 +9,6 @@
#ifndef BOOST_SPIRIT_X3_ATTR_JUL_23_2008_0956AM
#define BOOST_SPIRIT_X3_ATTR_JUL_23_2008_0956AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
@@ -112,24 +108,24 @@ namespace boost { namespace spirit { namespace x3
typename remove_reference<Value>::type>::type>
operator()(Value&& value) const
{
- return {std::forward<Value>(value)};
+ return { std::forward<Value>(value) };
}
template <typename Value, std::size_t N>
attr_parser<typename remove_cv<Value>::type[N]>
operator()(Value (&value)[N]) const
{
- return {value};
+ return { value };
}
template <typename Value, std::size_t N>
attr_parser<typename remove_cv<Value>::type[N]>
operator()(Value (&&value)[N]) const
{
- return {value};
+ return { value };
}
};
- attr_gen const attr = attr_gen();
+ auto const attr = attr_gen{};
}}}
#endif
diff --git a/boost/spirit/home/x3/auxiliary/eoi.hpp b/boost/spirit/home/x3/auxiliary/eoi.hpp
index 55bd51cfc4..778a20ba78 100644
--- a/boost/spirit/home/x3/auxiliary/eoi.hpp
+++ b/boost/spirit/home/x3/auxiliary/eoi.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_EOI_MARCH_23_2007_0454PM)
#define BOOST_SPIRIT_X3_EOI_MARCH_23_2007_0454PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
@@ -39,7 +35,7 @@ namespace boost { namespace spirit { namespace x3
result_type operator()(eoi_parser const &) const { return "eoi"; }
};
- eoi_parser const eoi = eoi_parser();
+ auto const eoi = eoi_parser{};
}}}
#endif
diff --git a/boost/spirit/home/x3/auxiliary/eol.hpp b/boost/spirit/home/x3/auxiliary/eol.hpp
index 3d191b4269..00e4488937 100644
--- a/boost/spirit/home/x3/auxiliary/eol.hpp
+++ b/boost/spirit/home/x3/auxiliary/eol.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_EOL_MARCH_23_2007_0454PM)
#define BOOST_SPIRIT_X3_EOL_MARCH_23_2007_0454PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
@@ -53,7 +49,7 @@ namespace boost { namespace spirit { namespace x3
result_type operator()(eol_parser const &) const { return "eol"; }
};
- eol_parser const eol = eol_parser();
+ auto const eol = eol_parser{};
}}}
#endif
diff --git a/boost/spirit/home/x3/auxiliary/eps.hpp b/boost/spirit/home/x3/auxiliary/eps.hpp
index ab4d307931..816eea7b0f 100644
--- a/boost/spirit/home/x3/auxiliary/eps.hpp
+++ b/boost/spirit/home/x3/auxiliary/eps.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_EPS_MARCH_23_2007_0454PM)
#define BOOST_SPIRIT_X3_EPS_MARCH_23_2007_0454PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
@@ -72,21 +68,19 @@ namespace boost { namespace spirit { namespace x3
return true;
}
- semantic_predicate
- operator()(bool predicate) const
+ inline semantic_predicate operator()(bool predicate) const
{
- return semantic_predicate(predicate);
+ return { predicate };
}
template <typename F>
- lazy_semantic_predicate<F>
- operator()(F f) const
+ lazy_semantic_predicate<F> operator()(F f) const
{
- return lazy_semantic_predicate<F>(f);
+ return { f };
}
};
- eps_parser const eps = eps_parser();
+ auto const eps = eps_parser{};
}}}
#endif
diff --git a/boost/spirit/home/x3/auxiliary/guard.hpp b/boost/spirit/home/x3/auxiliary/guard.hpp
index 6fd63c822c..b2f1695fbc 100644
--- a/boost/spirit/home/x3/auxiliary/guard.hpp
+++ b/boost/spirit/home/x3/auxiliary/guard.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_GUARD_FERBRUARY_02_2013_0649PM)
#define BOOST_SPIRIT_X3_GUARD_FERBRUARY_02_2013_0649PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/directive/expect.hpp>
diff --git a/boost/spirit/home/x3/support/utility/detail/testing.hpp b/boost/spirit/home/x3/binary.hpp
index 1423d9fc7b..a5010db8ff 100644
--- a/boost/spirit/home/x3/support/utility/detail/testing.hpp
+++ b/boost/spirit/home/x3/binary.hpp
@@ -1,16 +1,16 @@
/*=============================================================================
- Copyright (c) 2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the 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_SPIRIT_X3_DETAIL_TESTING_JUNE_05_2014_00422PM)
-#define BOOST_SPIRIT_X3_DETAIL_TESTING_JUNE_05_2014_00422PM
-
-namespace boost { namespace spirit { namespace x3 { namespace testing
-{
+#if !defined(BOOST_SPIRIT_X3_BINARY_MAY_08_2007_0906AM)
+#define BOOST_SPIRIT_X3_BINARY_MAY_08_2007_0906AM
+#if defined(_MSC_VER)
+#pragma once
+#endif
-}}}}
+#include <boost/spirit/home/x3/binary/binary.hpp>
#endif
diff --git a/boost/spirit/home/x3/binary/binary.hpp b/boost/spirit/home/x3/binary/binary.hpp
new file mode 100644
index 0000000000..b3d3a79473
--- /dev/null
+++ b/boost/spirit/home/x3/binary/binary.hpp
@@ -0,0 +1,175 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the 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_SPIRIT_X3_BINARY_MAY_08_2007_0808AM)
+#define BOOST_SPIRIT_X3_BINARY_MAY_08_2007_0808AM
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <cstdint>
+
+#include <boost/endian/conversion.hpp>
+#include <boost/endian/arithmetic.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_enum.hpp>
+#include <boost/type_traits/is_floating_point.hpp>
+#include <boost/config.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename V, typename T
+ , boost::endian::order endian, std::size_t bits>
+ struct binary_lit_parser
+ : parser<binary_lit_parser<V, T, endian, bits> >
+ {
+ static bool const has_attribute = false;
+
+ binary_lit_parser(V n_)
+ : n(n_) {}
+
+ template <typename Iterator, typename Context, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, unused_type, Attribute& attr_param) const
+ {
+ x3::skip_over(first, last, context);
+
+ auto bytes = reinterpret_cast<const unsigned char*>(&n);
+
+ Iterator it = first;
+ for (unsigned int i = 0; i < sizeof(n); ++i)
+ {
+ if (it == last || *bytes++ != static_cast<unsigned char>(*it++))
+ return false;
+ }
+
+ first = it;
+ x3::traits::move_to(n, attr_param);
+ return true;
+ }
+
+ boost::endian::endian_arithmetic<endian, T, bits> n;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, boost::endian::order endian, std::size_t bits>
+ struct any_binary_parser : parser<any_binary_parser<T, endian, bits > >
+ {
+
+ typedef T attribute_type;
+ static bool const has_attribute =
+ !is_same<unused_type, attribute_type>::value;
+
+ template <typename Iterator, typename Context, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, unused_type, Attribute& attr_param) const
+ {
+ x3::skip_over(first, last, context);
+
+ attribute_type attr_;
+ auto bytes = reinterpret_cast<unsigned char*>(&attr_);
+
+ Iterator it = first;
+ for (unsigned int i = 0; i < sizeof(attr_); ++i)
+ {
+ if (it == last)
+ return false;
+ *bytes++ = *it++;
+ }
+
+ first = it;
+ x3::traits::move_to(
+ endian::conditional_reverse<endian, endian::order::native>(attr_)
+ , attr_param );
+ return true;
+ }
+
+ template <typename V>
+ binary_lit_parser< V, T, endian, bits> operator()(V n) const
+ {
+ return {n};
+ }
+ };
+
+#define BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(name, endiantype, attrtype, bits) \
+ typedef any_binary_parser< attrtype, boost::endian::order::endiantype, bits > name##type; \
+ name##type const name = name##type();
+
+
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(byte_, native, uint_least8_t, 8)
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(word, native, uint_least16_t, 16)
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_word, big, uint_least16_t, 16)
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_word, little, uint_least16_t, 16)
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(dword, native, uint_least32_t, 32)
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_dword, big, uint_least32_t, 32)
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_dword, little, uint_least32_t, 32)
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(qword, native, uint_least64_t, 64)
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_qword, big, uint_least64_t, 64)
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_qword, little, uint_least64_t, 64)
+#endif
+
+ // Use a pseudo configuration macro to make clear that endian libray support
+ // for floating point types is required. Must be removed as soon as the endian library
+ // properly supports floating point types.
+#ifdef BOOST_ENDIAN_HAS_FLOATING_POINT
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(bin_float, native, float, 32)
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_bin_float, big, float, 32)
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_bin_float, little, float, 32)
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(bin_double, native, double, 64)
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_bin_double, big, double, 64)
+ BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_bin_double, little, double, 64)
+#endif
+
+#undef BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, std::size_t bits>
+ struct get_info<any_binary_parser<T, endian::order::little, bits>>
+ {
+ typedef std::string result_type;
+ std::string operator()(any_binary_parser<T, endian::order::little, bits> const& p) const
+ {
+ return "little-endian binary";
+ }
+ };
+
+ template <typename T, std::size_t bits>
+ struct get_info<any_binary_parser<T, endian::order::big, bits>>
+ {
+ typedef std::string result_type;
+ std::string operator()(any_binary_parser<T, endian::order::big, bits> const& p) const
+ {
+ return "big-endian binary";
+ }
+ };
+
+ template <typename V, typename T, std::size_t bits>
+ struct get_info<binary_lit_parser<V, T, endian::order::little, bits>>
+ {
+ typedef std::string result_type;
+ std::string operator()(binary_lit_parser<V, T, endian::order::little, bits> const& p) const
+ {
+ return "little-endian binary";
+ }
+ };
+
+ template <typename V, typename T, std::size_t bits>
+ struct get_info<binary_lit_parser<V, T, endian::order::big, bits>>
+ {
+ typedef std::string result_type;
+ std::string operator()(binary_lit_parser<V, T, endian::order::big, bits> const& p) const
+ {
+ return "big-endian binary";
+ }
+ };
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/char.hpp b/boost/spirit/home/x3/char.hpp
index 19d26de3a2..da8155b6b0 100644
--- a/boost/spirit/home/x3/char.hpp
+++ b/boost/spirit/home/x3/char.hpp
@@ -7,14 +7,11 @@
#if !defined(BOOST_SPIRIT_X3_CHAR_FEBRUARY_02_2007_0921AM)
#define BOOST_SPIRIT_X3_CHAR_FEBRUARY_02_2007_0921AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/char/negated_char_parser.hpp>
#include <boost/spirit/home/x3/char/char.hpp>
#include <boost/spirit/home/x3/char/char_class.hpp>
+#include <boost/spirit/home/x3/char/char_set.hpp>
#if defined(BOOST_SPIRIT_X3_UNICODE)
#include <boost/spirit/home/x3/char/unicode.hpp>
diff --git a/boost/spirit/home/x3/char/any_char.hpp b/boost/spirit/home/x3/char/any_char.hpp
index 7ff769b8b2..380645d2ff 100644
--- a/boost/spirit/home/x3/char/any_char.hpp
+++ b/boost/spirit/home/x3/char/any_char.hpp
@@ -7,11 +7,9 @@
#if !defined(BOOST_SPIRIT_X3_ANY_CHAR_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_X3_ANY_CHAR_APRIL_16_2006_1051AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
+#include <boost/type_traits/extent.hpp>
#include <boost/spirit/home/x3/char/literal_char.hpp>
+#include <boost/spirit/home/x3/char/char_set.hpp>
namespace boost { namespace spirit { namespace x3
{
@@ -30,10 +28,39 @@ namespace boost { namespace spirit { namespace x3
}
template <typename Char>
- literal_char<Encoding>
- operator()(Char ch) const
+ literal_char<Encoding> operator()(Char ch) const
+ {
+ return { ch };
+ }
+
+ template <typename Char>
+ literal_char<Encoding> operator()(const Char (&ch)[2]) const
+ {
+ return { ch[0] };
+ }
+
+ template <typename Char, std::size_t N>
+ char_set<Encoding> operator()(const Char (&ch)[N]) const
+ {
+ return { ch };
+ }
+
+ template <typename Char>
+ char_range<Encoding> operator()(Char from, Char to) const
+ {
+ return { from, to };
+ }
+
+ template <typename Char>
+ char_range<Encoding> operator()(Char (&from)[2], Char (&to)[2]) const
+ {
+ return { from[0], to[0] };
+ }
+
+ template <typename Char>
+ char_set<Encoding> operator()(std::basic_string<Char> const& s) const
{
- return literal_char<Encoding>(ch);
+ return { s };
}
};
}}}
diff --git a/boost/spirit/home/x3/char/char.hpp b/boost/spirit/home/x3/char/char.hpp
index 9452dcd86d..5cfd720152 100644
--- a/boost/spirit/home/x3/char/char.hpp
+++ b/boost/spirit/home/x3/char/char.hpp
@@ -7,12 +7,9 @@
#if !defined(BOOST_SPIRIT_X3_CHAR_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_X3_CHAR_APRIL_16_2006_1051AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/char/any_char.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
+#include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
#include <boost/spirit/home/support/char_encoding/standard.hpp>
#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
@@ -21,22 +18,72 @@ namespace boost { namespace spirit { namespace x3
namespace standard
{
typedef any_char<char_encoding::standard> char_type;
- char_type const char_ = char_type();
+ auto const char_ = char_type{};
+
+ inline literal_char<char_encoding::standard, unused_type>
+ lit(char ch)
+ {
+ return { ch };
+ }
+
+ inline literal_char<char_encoding::standard, unused_type>
+ lit(wchar_t ch)
+ {
+ return { ch };
+ }
+
}
using standard::char_type;
using standard::char_;
+ using standard::lit;
namespace standard_wide
{
typedef any_char<char_encoding::standard_wide> char_type;
- char_type const char_ = char_type();
+ auto const char_ = char_type{};
+
+ inline literal_char<char_encoding::standard_wide, unused_type>
+ lit(wchar_t ch)
+ {
+ return { ch };
+ }
}
namespace ascii
{
typedef any_char<char_encoding::ascii> char_type;
- char_type const char_ = char_type();
+ auto const char_ = char_type{};
+
+ inline literal_char<char_encoding::ascii, unused_type>
+ lit(char ch)
+ {
+ return { ch };
+ }
+
+ inline literal_char<char_encoding::ascii, unused_type>
+ lit(wchar_t ch)
+ {
+ return { ch };
+ }
+ }
+
+ namespace iso8859_1
+ {
+ typedef any_char<char_encoding::iso8859_1> char_type;
+ auto const char_ = char_type{};
+
+ inline literal_char<char_encoding::iso8859_1, unused_type>
+ lit(char ch)
+ {
+ return { ch };
+ }
+
+ inline literal_char<char_encoding::iso8859_1, unused_type>
+ lit(wchar_t ch)
+ {
+ return { ch };
+ }
}
namespace extension
@@ -52,7 +99,7 @@ namespace boost { namespace spirit { namespace x3
static type call(char ch)
{
- return type(ch);
+ return { ch };
}
};
@@ -67,22 +114,42 @@ namespace boost { namespace spirit { namespace x3
static type call(wchar_t ch)
{
- return type(ch);
+ return { ch };
}
};
- }
- inline literal_char<char_encoding::standard, unused_type>
- lit(char ch)
- {
- return literal_char<char_encoding::standard, unused_type>(ch);
- }
+ template <>
+ struct as_parser<char [2]>
+ {
+ typedef literal_char<
+ char_encoding::standard, unused_type>
+ type;
+
+ typedef type value_type;
+
+ static type call(char const ch[])
+ {
+ return { ch[0] };
+ }
+ };
+
+ template <>
+ struct as_parser<wchar_t [2]>
+ {
+ typedef literal_char<
+ char_encoding::standard_wide, unused_type>
+ type;
+
+ typedef type value_type;
+
+ static type call(wchar_t const ch[] )
+ {
+ return { ch[0] };
+ }
+ };
- inline literal_char<char_encoding::standard_wide, unused_type>
- lit(wchar_t ch)
- {
- return literal_char<char_encoding::standard_wide, unused_type>(ch);
}
+
}}}
#endif
diff --git a/boost/spirit/home/x3/char/char_class.hpp b/boost/spirit/home/x3/char/char_class.hpp
index 18b7131c0f..7fae90fdcd 100644
--- a/boost/spirit/home/x3/char/char_class.hpp
+++ b/boost/spirit/home/x3/char/char_class.hpp
@@ -7,35 +7,16 @@
#if !defined(BOOST_SPIRIT_X3_CHAR_CLASS_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_X3_CHAR_CLASS_APRIL_16_2006_1051AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/char/detail/cast_char.hpp>
#include <boost/spirit/home/support/char_encoding/standard.hpp>
#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
-
+#include <boost/spirit/home/x3/char/char_class_tags.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
- struct char_tag {};
- struct alnum_tag {};
- struct alpha_tag {};
- struct blank_tag {};
- struct cntrl_tag {};
- struct digit_tag {};
- struct graph_tag {};
- struct print_tag {};
- struct punct_tag {};
- struct space_tag {};
- struct xdigit_tag {};
- struct lower_tag {};
- struct upper_tag {};
-
- ///////////////////////////////////////////////////////////////////////////
template <typename Encoding>
struct char_class_base
{
@@ -80,10 +61,11 @@ namespace boost { namespace spirit { namespace x3
static bool const has_attribute = true;
template <typename Char, typename Context>
- bool test(Char ch, Context const&) const
+ bool test(Char ch, Context const& context) const
{
return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch))
- && char_class_base<Encoding>::is(tag(), ch);
+ && char_class_base<Encoding>::is(
+ get_case_compare<Encoding>(context).get_char_class_tag(tag()), ch);
}
};
diff --git a/boost/spirit/home/x3/char/char_class_tags.hpp b/boost/spirit/home/x3/char/char_class_tags.hpp
new file mode 100644
index 0000000000..0f3f61aae6
--- /dev/null
+++ b/boost/spirit/home/x3/char/char_class_tags.hpp
@@ -0,0 +1,29 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+
+ Distributed under the 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_SPIRIT_X3_CHAR_CLASS_TAGS_APRIL_16_2006_1051AM)
+#define BOOST_SPIRIT_X3_CHAR_CLASS_TAGS_APRIL_16_2006_1051AM
+
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ struct char_tag {};
+ struct alnum_tag {};
+ struct alpha_tag {};
+ struct blank_tag {};
+ struct cntrl_tag {};
+ struct digit_tag {};
+ struct graph_tag {};
+ struct print_tag {};
+ struct punct_tag {};
+ struct space_tag {};
+ struct xdigit_tag {};
+ struct lower_tag {};
+ struct upper_tag {};
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/char/char_parser.hpp b/boost/spirit/home/x3/char/char_parser.hpp
index 6943804369..973d493721 100644
--- a/boost/spirit/home/x3/char/char_parser.hpp
+++ b/boost/spirit/home/x3/char/char_parser.hpp
@@ -7,13 +7,10 @@
#if !defined(BOOST_SPIRIT_X3_CHAR_PARSER_APR_16_2006_0906AM)
#define BOOST_SPIRIT_X3_CHAR_PARSER_APR_16_2006_0906AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/spirit/home/x3/support/no_case.hpp>
namespace boost { namespace spirit { namespace x3
{
@@ -29,7 +26,6 @@ namespace boost { namespace spirit { namespace x3
, Context const& context, unused_type, Attribute& attr) const
{
x3::skip_over(first, last, context);
-
if (first != last && this->derived().test(*first, context))
{
x3::traits::move_to(*first, attr);
diff --git a/boost/spirit/home/x3/char/char_set.hpp b/boost/spirit/home/x3/char/char_set.hpp
new file mode 100644
index 0000000000..5a37ff6bea
--- /dev/null
+++ b/boost/spirit/home/x3/char/char_set.hpp
@@ -0,0 +1,136 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+
+ Distributed under the 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_SPIRIT_X3_CHAR_SET_OCT_12_2014_1051AM)
+#define BOOST_SPIRIT_X3_CHAR_SET_OCT_12_2014_1051AM
+
+#include <boost/spirit/home/x3/char/char_parser.hpp>
+#include <boost/spirit/home/x3/char/detail/cast_char.hpp>
+#include <boost/spirit/home/x3/support/traits/string_traits.hpp>
+#include <boost/spirit/home/x3/support/utility/utf8.hpp>
+#include <boost/spirit/home/x3/support/no_case.hpp>
+#include <boost/spirit/home/support/char_set/basic_chset.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Parser for a character range
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Encoding, typename Attribute = typename Encoding::char_type>
+ struct char_range
+ : char_parser< char_range<Encoding, Attribute> >
+ {
+
+ typedef typename Encoding::char_type char_type;
+ typedef Encoding encoding;
+ typedef Attribute attribute_type;
+ static bool const has_attribute =
+ !is_same<unused_type, attribute_type>::value;
+
+
+ char_range(char_type from_, char_type to_)
+ : from(from_), to(to_) {}
+
+ template <typename Char, typename Context>
+ bool test(Char ch_, Context& context) const
+ {
+
+ char_type ch = char_type(ch_); // optimize for token based parsing
+ return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_))
+ && (get_case_compare<encoding>(context)(ch, from) > 0 )
+ && (get_case_compare<encoding>(context)(ch , to) < 0 );
+ }
+
+ char_type from, to;
+ };
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Parser for a character set
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Encoding, typename Attribute = typename Encoding::char_type>
+ struct char_set : char_parser<char_set<Encoding, Attribute>>
+ {
+ typedef typename Encoding::char_type char_type;
+ typedef Encoding encoding;
+ typedef Attribute attribute_type;
+ static bool const has_attribute =
+ !is_same<unused_type, attribute_type>::value;
+
+ template <typename String>
+ char_set(String const& str)
+ {
+ using spirit::x3::detail::cast_char;
+
+ typedef typename
+ remove_const<
+ typename traits::char_type_of<String>::type
+ >::type
+ in_type;
+
+ in_type const* definition =
+ (in_type const*)traits::get_c_string(str);
+ in_type ch = *definition++;
+ while (ch)
+ {
+ in_type next = *definition++;
+ if (next == '-')
+ {
+ next = *definition++;
+ if (next == 0)
+ {
+ chset.set(cast_char<char_type>(ch));
+ chset.set('-');
+ break;
+ }
+ chset.set(
+ cast_char<char_type>(ch),
+ cast_char<char_type>(next)
+ );
+ }
+ else
+ {
+ chset.set(cast_char<char_type>(ch));
+ }
+ ch = next;
+ }
+ }
+
+ template <typename Char, typename Context>
+ bool test(Char ch_, Context const& context) const
+ {
+ return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_))
+ && get_case_compare<encoding>(context).in_set(ch_,chset);
+ }
+
+ support::detail::basic_chset<char_type> chset;
+ };
+
+ template <typename Encoding, typename Attribute>
+ struct get_info<char_set<Encoding, Attribute>>
+ {
+ typedef std::string result_type;
+ std::string operator()(char_set<Encoding, Attribute> const& p) const
+ {
+ return "char-set";
+ }
+ };
+
+ template <typename Encoding, typename Attribute>
+ struct get_info<char_range<Encoding, Attribute>>
+ {
+ typedef std::string result_type;
+ std::string operator()(char_range<Encoding, Attribute> const& p) const
+ {
+ return "char_range \"" + to_utf8(Encoding::toucs4(p.from)) + '-' + to_utf8(Encoding::toucs4(p.to))+ '"';
+ }
+ };
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/char/detail/cast_char.hpp b/boost/spirit/home/x3/char/detail/cast_char.hpp
index 03bda27a29..2b802c641d 100644
--- a/boost/spirit/home/x3/char/detail/cast_char.hpp
+++ b/boost/spirit/home/x3/char/detail/cast_char.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_CAST_CHAR_NOVEMBER_10_2006_0907AM)
#define BOOST_SPIRIT_X3_CAST_CHAR_NOVEMBER_10_2006_0907AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/make_signed.hpp>
diff --git a/boost/spirit/home/x3/char/literal_char.hpp b/boost/spirit/home/x3/char/literal_char.hpp
index 94b2a239a6..ebeceee4df 100644
--- a/boost/spirit/home/x3/char/literal_char.hpp
+++ b/boost/spirit/home/x3/char/literal_char.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_LITERAL_CHAR_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_X3_LITERAL_CHAR_APRIL_16_2006_1051AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/support/utility/utf8.hpp>
#include <boost/type_traits/is_same.hpp>
@@ -31,12 +27,12 @@ namespace boost { namespace spirit { namespace x3
: ch(static_cast<char_type>(ch)) {}
template <typename Char, typename Context>
- bool test(Char ch_, Context const&) const
+ bool test(Char ch_, Context const& context) const
{
return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_))
- && ch == char_type(ch_);
+ && (get_case_compare<encoding>(context)(ch, char_type(ch_)) == 0);
}
-
+
char_type ch;
};
diff --git a/boost/spirit/home/x3/char/negated_char_parser.hpp b/boost/spirit/home/x3/char/negated_char_parser.hpp
index 392d712759..66692dc7a2 100644
--- a/boost/spirit/home/x3/char/negated_char_parser.hpp
+++ b/boost/spirit/home/x3/char/negated_char_parser.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_NEGATED_CHAR_PARSER_APR_16_2006_0906AM)
#define BOOST_SPIRIT_X3_NEGATED_CHAR_PARSER_APR_16_2006_0906AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/char/char_parser.hpp>
@@ -40,7 +36,7 @@ namespace boost { namespace spirit { namespace x3
inline negated_char_parser<Positive>
operator~(char_parser<Positive> const& cp)
{
- return negated_char_parser<Positive>(cp.derived());
+ return { cp.derived() };
}
template <typename Positive>
diff --git a/boost/spirit/home/x3/char/unicode.hpp b/boost/spirit/home/x3/char/unicode.hpp
index 6954c40e40..290c7a4adc 100644
--- a/boost/spirit/home/x3/char/unicode.hpp
+++ b/boost/spirit/home/x3/char/unicode.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_UNICODE_JAN_20_2012_1218AM)
#define BOOST_SPIRIT_X3_UNICODE_JAN_20_2012_1218AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/char/char.hpp>
#include <boost/spirit/home/x3/char/detail/cast_char.hpp>
@@ -431,7 +427,7 @@ namespace boost { namespace spirit { namespace x3
namespace unicode
{
typedef any_char<char_encoding::unicode> char_type;
- char_type const char_ = char_type();
+ auto const char_ = char_type{};
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
diff --git a/boost/spirit/home/x3/core.hpp b/boost/spirit/home/x3/core.hpp
index a4f875e38a..b732c408e0 100644
--- a/boost/spirit/home/x3/core.hpp
+++ b/boost/spirit/home/x3/core.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_CORE_APRIL_04_2012_0318PM)
#define BOOST_SPIRIT_X3_CORE_APRIL_04_2012_0318PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/parse.hpp>
//~ #include <boost/spirit/home/x3/core/parse_attr.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
diff --git a/boost/spirit/home/x3/core/action.hpp b/boost/spirit/home/x3/core/action.hpp
index 890933fff1..7c34ac0ece 100644
--- a/boost/spirit/home/x3/core/action.hpp
+++ b/boost/spirit/home/x3/core/action.hpp
@@ -7,10 +7,6 @@
#if !defined(SPIRIT_ACTION_JANUARY_07_2007_1128AM)
#define SPIRIT_ACTION_JANUARY_07_2007_1128AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/make_attribute.hpp>
@@ -113,7 +109,7 @@ namespace boost { namespace spirit { namespace x3
inline action<typename extension::as_parser<P>::value_type, Action>
operator/(P const& p, Action f)
{
- return {as_parser(p), f};
+ return { as_parser(p), f };
}
}}}
diff --git a/boost/spirit/home/x3/core/call.hpp b/boost/spirit/home/x3/core/call.hpp
index a4139751df..9674c93efe 100644
--- a/boost/spirit/home/x3/core/call.hpp
+++ b/boost/spirit/home/x3/core/call.hpp
@@ -19,8 +19,7 @@ namespace boost { namespace spirit { namespace x3
struct rule_val_context_tag;
template <typename Context>
- inline auto _val(Context const& context)
- -> decltype(x3::get<rule_val_context_tag>(context))
+ inline decltype(auto) _val(Context const& context)
{
return x3::get<rule_val_context_tag>(context);
}
@@ -29,8 +28,7 @@ namespace boost { namespace spirit { namespace x3
struct where_context_tag;
template <typename Context>
- inline auto _where(Context const& context)
- -> decltype(x3::get<where_context_tag>(context))
+ inline decltype(auto) _where(Context const& context)
{
return x3::get<where_context_tag>(context);
}
@@ -39,8 +37,7 @@ namespace boost { namespace spirit { namespace x3
struct attr_context_tag;
template <typename Context>
- inline auto _attr(Context const& context)
- -> decltype(x3::get<attr_context_tag>(context))
+ inline decltype(auto) _attr(Context const& context)
{
return x3::get<attr_context_tag>(context);
}
diff --git a/boost/spirit/home/x3/core/detail/parse_into_container.hpp b/boost/spirit/home/x3/core/detail/parse_into_container.hpp
index 4b19115a67..96424a4278 100644
--- a/boost/spirit/home/x3/core/detail/parse_into_container.hpp
+++ b/boost/spirit/home/x3/core/detail/parse_into_container.hpp
@@ -7,10 +7,6 @@
#if !defined(SPIRIT_PARSE_INTO_CONTAINER_JAN_15_2013_0957PM)
#define SPIRIT_PARSE_INTO_CONTAINER_JAN_15_2013_0957PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <type_traits>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
@@ -41,21 +37,24 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
}
};
-
+/* $$$ clang reports: warning: class template partial specialization contains
+ * a template parameter that can not be deduced; this partial specialization
+ * will never be used $$$
+ *
// save to associative fusion container where Key
// is variant over possible keys
template <typename ...T>
struct save_to_assoc_attr<variant<T...> >
{
typedef variant<T...> variant_t;
-
+
template <typename Value, typename Attribute>
static void call(const variant_t key, Value& value, Attribute& attr)
{
apply_visitor(saver_visitor<Attribute, Value>(attr, value), key);
}
};
-
+*/
template <typename Attribute, typename Value>
struct saver_visitor : boost::static_visitor<void>
{
@@ -64,7 +63,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
Attribute& attr;
Value& value;
-
+
template <typename Key>
void operator()(Key) const
{
@@ -72,6 +71,13 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
}
};
+ template <typename Parser, typename Container, typename Context>
+ struct parser_accepts_container
+ : traits::is_substitute<
+ typename traits::attribute_of<Parser, Context>::type
+ , Container
+ >
+ {};
template <typename Parser>
struct parse_into_container_base_impl
@@ -81,10 +87,10 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
// Parser has attribute (synthesize; Attribute is a container)
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
- static bool call_synthesize(
+ static bool call_synthesize_x(
Parser const& parser
, Iterator& first, Iterator const& last
- , Context const& context, RContext& rcontext, Attribute& attr)
+ , Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)
{
// synthesized attribute needs to be value initialized
typedef typename
@@ -100,6 +106,33 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
return true;
}
+ // Parser has attribute (synthesize; Attribute is a container)
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ static bool call_synthesize_x(
+ Parser const& parser
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)
+ {
+ return parser.parse(first, last, context, rcontext, attr);
+ }
+
+ // Parser has attribute (synthesize; Attribute is a container)
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ static bool call_synthesize(
+ Parser const& parser
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr)
+ {
+ typedef
+ parser_accepts_container<Parser, Attribute, Context>
+ parser_accepts_container;
+
+ return call_synthesize_x(parser, first, last, context, rcontext, attr
+ , parser_accepts_container());
+ }
+
// Parser has attribute (synthesize; Attribute is a single element fusion sequence)
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
@@ -173,7 +206,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
{
return parser.parse(first, last, context, rcontext, unused);
}
-
+
public:
@@ -190,7 +223,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
template <typename Parser, typename Context, typename RContext, typename Enable = void>
struct parse_into_container_impl : parse_into_container_base_impl<Parser> {};
- template <typename Parser, typename Container, typename RContext, typename Context>
+ template <typename Parser, typename Container, typename Context>
struct parser_attr_is_substitute_for_container_value
: traits::is_substitute<
typename traits::attribute_of<Parser, Context>::type
@@ -206,7 +239,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
static bool call(
Parser const& parser
, Iterator& first, Iterator const& last
- , Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)
+ , Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)
{
return parse_into_container_base_impl<Parser>::call(
parser, first, last, context, rcontext, attr);
@@ -216,7 +249,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
static bool call(
Parser const& parser
, Iterator& first, Iterator const& last
- , Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)
+ , Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)
{
return parser.parse(first, last, context, rcontext, attr);
}
@@ -226,9 +259,21 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr)
{
+ typedef parser_accepts_container<
+ Parser, Attribute, Context>
+ parser_accepts_container;
+
+ typedef parser_attr_is_substitute_for_container_value<
+ Parser, Attribute, Context>
+ parser_attr_is_substitute_for_container_value;
+
+ typedef mpl::or_<
+ parser_accepts_container
+ , mpl::not_<parser_attr_is_substitute_for_container_value>>
+ pass_attibute_as_is;
+
return call(parser, first, last, context, rcontext, attr,
- parser_attr_is_substitute_for_container_value<
- Parser, Attribute, Context, RContext>());
+ pass_attibute_as_is());
}
};
diff --git a/boost/spirit/home/x3/core/parse.hpp b/boost/spirit/home/x3/core/parse.hpp
index ac36e3c7ea..234903037f 100644
--- a/boost/spirit/home/x3/core/parse.hpp
+++ b/boost/spirit/home/x3/core/parse.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM)
#define BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
diff --git a/boost/spirit/home/x3/core/parser.hpp b/boost/spirit/home/x3/core/parser.hpp
index bc63a7438b..0df69304e0 100644
--- a/boost/spirit/home/x3/core/parser.hpp
+++ b/boost/spirit/home/x3/core/parser.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM)
#define BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/remove_cv.hpp>
@@ -30,10 +26,6 @@
namespace boost { namespace spirit { namespace x3
{
- using x3::unused_type;
- using x3::unused;
- using x3::get;
-
template <typename Subject, typename Action>
struct action;
@@ -81,7 +73,7 @@ namespace boost { namespace spirit { namespace x3
typedef Subject subject_type;
static bool const has_action = Subject::has_action;
- unary_parser(Subject subject)
+ unary_parser(Subject const& subject)
: subject(subject) {}
unary_parser const& get_unary() const { return *this; }
@@ -98,7 +90,7 @@ namespace boost { namespace spirit { namespace x3
static bool const has_action =
left_type::has_action || right_type::has_action;
- binary_parser(Left left, Right right)
+ binary_parser(Left const& left, Right const& right)
: left(left), right(right) {}
binary_parser const& get_binary() const { return *this; }
diff --git a/boost/spirit/home/x3/core/proxy.hpp b/boost/spirit/home/x3/core/proxy.hpp
index 1a0ade59a8..6fe818d8b2 100644
--- a/boost/spirit/home/x3/core/proxy.hpp
+++ b/boost/spirit/home/x3/core/proxy.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_PROXY_FEBRUARY_1_2013_0211PM)
#define BOOST_SPIRIT_X3_PROXY_FEBRUARY_1_2013_0211PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
diff --git a/boost/spirit/home/x3/core/skip_over.hpp b/boost/spirit/home/x3/core/skip_over.hpp
index 643ddb1f5b..ef7982a8cd 100644
--- a/boost/spirit/home/x3/core/skip_over.hpp
+++ b/boost/spirit/home/x3/core/skip_over.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_SKIP_APRIL_16_2006_0625PM)
#define BOOST_SPIRIT_X3_SKIP_APRIL_16_2006_0625PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
diff --git a/boost/spirit/home/x3/directive.hpp b/boost/spirit/home/x3/directive.hpp
index 81f7a8536a..0ff683f930 100644
--- a/boost/spirit/home/x3/directive.hpp
+++ b/boost/spirit/home/x3/directive.hpp
@@ -1,5 +1,5 @@
/*=============================================================================
- Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2015 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,21 +7,19 @@
#if !defined(BOOST_SPIRIT_X3_DIRECTIVE_FEBRUARY_05_2007_0313PM)
#define BOOST_SPIRIT_X3_DIRECTIVE_FEBRUARY_05_2007_0313PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
//~ #include <boost/spirit/home/x3/directive/as.hpp>
+#include <boost/spirit/home/x3/directive/confix.hpp>
//~ #include <boost/spirit/home/x3/directive/encoding.hpp>
//~ #include <boost/spirit/home/x3/directive/hold.hpp>
#include <boost/spirit/home/x3/directive/expect.hpp>
#include <boost/spirit/home/x3/directive/lexeme.hpp>
+#include <boost/spirit/home/x3/directive/matches.hpp>
+#include <boost/spirit/home/x3/directive/no_case.hpp>
#include <boost/spirit/home/x3/directive/no_skip.hpp>
-//~ #include <boost/spirit/home/x3/directive/matches.hpp>
-//~ #include <boost/spirit/home/x3/directive/no_case.hpp>
#include <boost/spirit/home/x3/directive/omit.hpp>
#include <boost/spirit/home/x3/directive/raw.hpp>
-//~ #include <boost/spirit/home/x3/directive/repeat.hpp>
+#include <boost/spirit/home/x3/directive/repeat.hpp>
+#include <boost/spirit/home/x3/directive/seek.hpp>
#include <boost/spirit/home/x3/directive/skip.hpp>
#include <boost/spirit/home/x3/directive/with.hpp>
diff --git a/boost/spirit/home/x3/directive/confix.hpp b/boost/spirit/home/x3/directive/confix.hpp
new file mode 100644
index 0000000000..0d99e58f4e
--- /dev/null
+++ b/boost/spirit/home/x3/directive/confix.hpp
@@ -0,0 +1,83 @@
+/*=============================================================================
+ Copyright (c) 2009 Chris Hoeppler
+ Copyright (c) 2014 Lee Clagett
+
+ Distributed under the 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_SPIRIT_X3_CONFIX_MAY_30_2014_1819PM)
+#define BOOST_SPIRIT_X3_CONFIX_MAY_30_2014_1819PM
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template<typename Prefix, typename Subject, typename Postfix>
+ struct confix_directive :
+ unary_parser<Subject, confix_directive<Prefix, Subject, Postfix>>
+ {
+ typedef unary_parser<
+ Subject, confix_directive<Prefix, Subject, Postfix>> base_type;
+ static bool const is_pass_through_unary = true;
+ static bool const handles_container = Subject::handles_container;
+
+ confix_directive(Prefix const& prefix
+ , Subject const& subject
+ , Postfix const& postfix) :
+ base_type(subject),
+ prefix(prefix),
+ postfix(postfix)
+ {
+ }
+
+ template<typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse(
+ Iterator& first, Iterator const& last
+ , Context& context, RContext& rcontext, Attribute& attr) const
+ {
+ Iterator save = first;
+
+ if (!(prefix.parse(first, last, context, rcontext, unused) &&
+ this->subject.parse(first, last, context, rcontext, attr) &&
+ postfix.parse(first, last, context, rcontext, unused)))
+ {
+ first = save;
+ return false;
+ }
+
+ return true;
+ }
+
+ Prefix prefix;
+ Postfix postfix;
+ };
+
+ template<typename Prefix, typename Postfix>
+ struct confix_gen
+ {
+ template<typename Subject>
+ confix_directive<
+ Prefix, typename extension::as_parser<Subject>::value_type, Postfix>
+ operator[](Subject const& subject) const
+ {
+ return { prefix, as_parser(subject), postfix };
+ }
+
+ Prefix prefix;
+ Postfix postfix;
+ };
+
+
+ template<typename Prefix, typename Postfix>
+ confix_gen<typename extension::as_parser<Prefix>::value_type,
+ typename extension::as_parser<Postfix>::value_type>
+ confix(Prefix const& prefix, Postfix const& postfix)
+ {
+ return { as_parser(prefix), as_parser(postfix) };
+ }
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/directive/expect.hpp b/boost/spirit/home/x3/directive/expect.hpp
index 4e59ce5dca..879d92c2df 100644
--- a/boost/spirit/home/x3/directive/expect.hpp
+++ b/boost/spirit/home/x3/directive/expect.hpp
@@ -7,10 +7,6 @@
#if !defined(SPIRIT_EXPECT_MARCH_16_2012_1024PM)
#define SPIRIT_EXPECT_MARCH_16_2012_1024PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/throw_exception.hpp>
@@ -70,11 +66,11 @@ namespace boost { namespace spirit { namespace x3
expect_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
- return {as_parser(subject)};
+ return { as_parser(subject) };
}
};
- expect_gen const expect = expect_gen();
+ auto const expect = expect_gen{};
}}}
#endif
diff --git a/boost/spirit/home/x3/directive/lexeme.hpp b/boost/spirit/home/x3/directive/lexeme.hpp
index e5104272f9..ce3a6def80 100644
--- a/boost/spirit/home/x3/directive/lexeme.hpp
+++ b/boost/spirit/home/x3/directive/lexeme.hpp
@@ -7,10 +7,6 @@
#if !defined(SPIRIT_LEXEME_MARCH_24_2007_0802AM)
#define SPIRIT_LEXEME_MARCH_24_2007_0802AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
@@ -29,7 +25,7 @@ namespace boost { namespace spirit { namespace x3
lexeme_directive(Subject const& subject)
: base_type(subject) {}
-
+
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
typename enable_if<has_skipper<Context>, bool>::type
@@ -58,8 +54,6 @@ namespace boost { namespace spirit { namespace x3
, Context const& context, RContext& rcontext, Attribute& attr) const
{
// no need to pre-skip if skipper is unused
- //- x3::skip_over(first, last, context);
-
return this->subject.parse(
first, last
, context
@@ -74,11 +68,11 @@ namespace boost { namespace spirit { namespace x3
lexeme_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
- return {as_parser(subject)};
+ return { as_parser(subject) };
}
};
- lexeme_gen const lexeme = lexeme_gen();
+ auto const lexeme = lexeme_gen{};
}}}
#endif
diff --git a/boost/spirit/home/x3/directive/matches.hpp b/boost/spirit/home/x3/directive/matches.hpp
new file mode 100644
index 0000000000..2aae43b50d
--- /dev/null
+++ b/boost/spirit/home/x3/directive/matches.hpp
@@ -0,0 +1,51 @@
+/*=============================================================================
+ Copyright (c) 2015 Mario Lang
+ Copyright (c) 2001-2011 Hartmut Kaiser
+
+ Distributed under the 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_SPIRIT_HOME_X3_EXTENSIONS_MATCHES_HPP)
+#define BOOST_SPIRIT_HOME_X3_EXTENSIONS_MATCHES_HPP
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Subject>
+ struct matches_directive : unary_parser<Subject, matches_directive<Subject>>
+ {
+ using base_type = unary_parser<Subject, matches_directive<Subject>>;
+ static bool const has_attribute = true;
+ using attribute_type = bool;
+
+ matches_directive(Subject const& subject) : base_type(subject) {}
+
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ bool const result = this->subject.parse(
+ first, last, context, rcontext, unused);
+ traits::move_to(result, attr);
+ return true;
+ }
+ };
+
+ struct matches_gen
+ {
+ template <typename Subject>
+ matches_directive<typename extension::as_parser<Subject>::value_type>
+ operator[](Subject const& subject) const
+ {
+ return { as_parser(subject) };
+ }
+ };
+
+ auto const matches = matches_gen{};
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/directive/no_case.hpp b/boost/spirit/home/x3/directive/no_case.hpp
new file mode 100644
index 0000000000..b00315614a
--- /dev/null
+++ b/boost/spirit/home/x3/directive/no_case.hpp
@@ -0,0 +1,54 @@
+/*=============================================================================
+ Copyright (c) 2014 Thomas Bernard
+
+ Distributed under the 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(SPIRIT_NO_CASE_SEPT_16_2014_0912PM)
+#define SPIRIT_NO_CASE_SEPT_16_2014_0912PM
+
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/no_case.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ // propagate no_case information through the context
+ template <typename Subject>
+ struct no_case_directive : unary_parser<Subject, no_case_directive<Subject>>
+ {
+ typedef unary_parser<Subject, no_case_directive<Subject> > base_type;
+ static bool const is_pass_through_unary = true;
+ static bool const handles_container = Subject::handles_container;
+
+ no_case_directive(Subject const& subject)
+ : base_type(subject) {}
+
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ return this->subject.parse(
+ first, last
+ , make_context<no_case_tag>(no_case_compare_, context)
+ , rcontext
+ , attr);
+ }
+ };
+
+ struct no_case_gen
+ {
+ template <typename Subject>
+ no_case_directive<typename extension::as_parser<Subject>::value_type>
+ operator[](Subject const& subject) const
+ {
+ return { as_parser(subject) };
+ }
+ };
+
+ auto const no_case = no_case_gen{};
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/directive/no_skip.hpp b/boost/spirit/home/x3/directive/no_skip.hpp
index 14dee4d85c..c6245f577a 100644
--- a/boost/spirit/home/x3/directive/no_skip.hpp
+++ b/boost/spirit/home/x3/directive/no_skip.hpp
@@ -9,10 +9,6 @@
#if !defined(SPIRIT_NO_SKIP_JAN_16_2010_0802PM)
#define SPIRIT_NO_SKIP_JAN_16_2010_0802PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
@@ -72,11 +68,11 @@ namespace boost { namespace spirit { namespace x3
no_skip_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
- return {as_parser(subject)};
+ return { as_parser(subject) };
}
};
- no_skip_gen const no_skip = no_skip_gen();
+ auto const no_skip = no_skip_gen{};
}}}
#endif
diff --git a/boost/spirit/home/x3/directive/omit.hpp b/boost/spirit/home/x3/directive/omit.hpp
index 43ebd49aaf..3053676983 100644
--- a/boost/spirit/home/x3/directive/omit.hpp
+++ b/boost/spirit/home/x3/directive/omit.hpp
@@ -7,10 +7,6 @@
#if !defined(SPIRIT_OMIT_MARCH_24_2007_0802AM)
#define SPIRIT_OMIT_MARCH_24_2007_0802AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
@@ -45,11 +41,11 @@ namespace boost { namespace spirit { namespace x3
omit_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
- return {as_parser(subject)};
+ return { as_parser(subject) };
}
};
- omit_gen const omit = omit_gen();
+ auto const omit = omit_gen{};
}}}
#endif
diff --git a/boost/spirit/home/x3/directive/raw.hpp b/boost/spirit/home/x3/directive/raw.hpp
index e6bcd9a3a1..8432e13888 100644
--- a/boost/spirit/home/x3/directive/raw.hpp
+++ b/boost/spirit/home/x3/directive/raw.hpp
@@ -60,11 +60,11 @@ namespace boost { namespace spirit { namespace x3
raw_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
- return {as_parser(subject)};
+ return { as_parser(subject) };
}
};
- raw_gen const raw = raw_gen();
+ auto const raw = raw_gen{};
}}}
#endif
diff --git a/boost/spirit/home/x3/directive/repeat.hpp b/boost/spirit/home/x3/directive/repeat.hpp
new file mode 100644
index 0000000000..1cdee97fb9
--- /dev/null
+++ b/boost/spirit/home/x3/directive/repeat.hpp
@@ -0,0 +1,157 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2014 Thomas Bernard
+
+ Distributed under the 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(SPIRIT_X3_REPEAT_APRIL_16_2014_0848AM)
+#define SPIRIT_X3_REPEAT_APRIL_16_2014_0848AM
+
+#include <boost/function_types/function_type.hpp>
+#include <boost/function_types/parameter_types.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/operator/kleene.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ template <typename T>
+ struct exact_count // handles repeat(exact)[p]
+ {
+ typedef T type;
+ bool got_max(T i) const { return i >= exact_value; }
+ bool got_min(T i) const { return i >= exact_value; }
+
+ T const exact_value;
+ };
+
+ template <typename T>
+ struct finite_count // handles repeat(min, max)[p]
+ {
+ typedef T type;
+ bool got_max(T i) const { return i >= max_value; }
+ bool got_min(T i) const { return i >= min_value; }
+
+ T const min_value;
+ T const max_value;
+ };
+
+ template <typename T>
+ struct infinite_count // handles repeat(min, inf)[p]
+ {
+ typedef T type;
+ bool got_max(T /*i*/) const { return false; }
+ bool got_min(T i) const { return i >= min_value; }
+
+ T const min_value;
+ };
+}}}}
+
+namespace boost { namespace spirit { namespace x3
+{
+ template<typename Subject, typename RepeatCountLimit>
+ struct repeat_directive : unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>>
+ {
+ typedef unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>> base_type;
+ static bool const is_pass_through_unary = true;
+ static bool const handles_container = true;
+
+ repeat_directive(Subject const& subject, RepeatCountLimit const& repeat_limit_)
+ : base_type(subject)
+ , repeat_limit(repeat_limit_)
+ {}
+
+ template<typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse(
+ Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ Iterator local_iterator = first;
+ typename RepeatCountLimit::type i{};
+ for (/**/; !repeat_limit.got_min(i); ++i)
+ {
+ if (!detail::parse_into_container(
+ this->subject, local_iterator, last, context, rcontext, attr))
+ return false;
+ }
+
+ first = local_iterator;
+ // parse some more up to the maximum specified
+ for (/**/; !repeat_limit.got_max(i); ++i)
+ {
+ if (!detail::parse_into_container(
+ this->subject, first, last, context, rcontext, attr))
+ break;
+ }
+ return true;
+ }
+
+ RepeatCountLimit repeat_limit;
+ };
+
+ // Infinite loop tag type
+ struct inf_type {};
+ const inf_type inf = inf_type();
+
+ struct repeat_gen
+ {
+ template<typename Subject>
+ kleene<typename extension::as_parser<Subject>::value_type>
+ operator[](Subject const& subject) const
+ {
+ return { as_parser(subject) };
+ }
+
+ template <typename T>
+ struct repeat_gen_lvl1
+ {
+ repeat_gen_lvl1(T&& repeat_limit_)
+ : repeat_limit(repeat_limit_)
+ {}
+
+ template<typename Subject>
+ repeat_directive< typename extension::as_parser<Subject>::value_type, T>
+ operator[](Subject const& subject) const
+ {
+ return { as_parser(subject),repeat_limit };
+ }
+
+ T repeat_limit;
+ };
+
+ template <typename T>
+ repeat_gen_lvl1<detail::exact_count<T>>
+ operator()(T const exact) const
+ {
+ return { detail::exact_count<T>{exact} };
+ }
+
+ template <typename T>
+ repeat_gen_lvl1<detail::finite_count<T>>
+ operator()(T const min_val, T const max_val) const
+ {
+ return { detail::finite_count<T>{min_val,max_val} };
+ }
+
+ template <typename T>
+ repeat_gen_lvl1<detail::infinite_count<T>>
+ operator()(T const min_val, inf_type const &) const
+ {
+ return { detail::infinite_count<T>{min_val} };
+ }
+ };
+
+ auto const repeat = repeat_gen{};
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Subject, typename RepeatCountLimit, typename Context>
+ struct attribute_of<x3::repeat_directive<Subject,RepeatCountLimit>, Context>
+ : build_container<typename attribute_of<Subject, Context>::type> {};
+}}}}
+
+
+#endif
diff --git a/boost/spirit/home/x3/extensions/seek.hpp b/boost/spirit/home/x3/directive/seek.hpp
index bcd9544794..e56a37b5c3 100644
--- a/boost/spirit/home/x3/extensions/seek.hpp
+++ b/boost/spirit/home/x3/directive/seek.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_SEEK_APRIL_13_2014_1920PM)
#define BOOST_SPIRIT_X3_SEEK_APRIL_13_2014_1920PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
@@ -60,11 +56,11 @@ namespace boost { namespace spirit { namespace x3
seek_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
- return {as_parser(subject)};
+ return { as_parser(subject) };
}
};
- seek_gen const seek = seek_gen();
+ auto const seek = seek_gen{};
}}}
#endif
diff --git a/boost/spirit/home/x3/directive/skip.hpp b/boost/spirit/home/x3/directive/skip.hpp
index c880720791..8d8bc78aca 100644
--- a/boost/spirit/home/x3/directive/skip.hpp
+++ b/boost/spirit/home/x3/directive/skip.hpp
@@ -8,10 +8,6 @@
#if !defined(SPIRIT_SKIP_JANUARY_26_2008_0422PM)
#define SPIRIT_SKIP_JANUARY_26_2008_0422PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
@@ -91,34 +87,34 @@ namespace boost { namespace spirit { namespace x3
template <typename Skipper>
struct skip_gen
{
- explicit skip_gen(Skipper const& skipper)
+ skip_gen(Skipper const& skipper)
: skipper_(skipper) {}
template <typename Subject>
skip_directive<typename extension::as_parser<Subject>::value_type, Skipper>
operator[](Subject const& subject) const
{
- return {as_parser(subject), skipper_};
+ return { as_parser(subject), skipper_ };
}
Skipper skipper_;
};
-
+
template <typename Skipper>
skip_gen<Skipper> const operator()(Skipper const& skipper) const
{
- return skip_gen<Skipper>(skipper);
+ return { skipper };
}
template <typename Subject>
reskip_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
- return {as_parser(subject)};
+ return { as_parser(subject) };
}
};
- reskip_gen const skip = reskip_gen();
+ auto const skip = reskip_gen{};
}}}
#endif
diff --git a/boost/spirit/home/x3/directive/with.hpp b/boost/spirit/home/x3/directive/with.hpp
index cc6c442a34..359f5adf1c 100644
--- a/boost/spirit/home/x3/directive/with.hpp
+++ b/boost/spirit/home/x3/directive/with.hpp
@@ -87,20 +87,20 @@ namespace boost { namespace spirit { namespace x3
with_directive<typename extension::as_parser<Subject>::value_type, ID, T>
operator[](Subject const& subject) const
{
- return {as_parser(subject), val};
+ return { as_parser(subject), val };
}
};
template <typename ID, typename T>
inline with_gen<ID, T> with(T& val)
{
- return with_gen<ID, T>{val};
+ return { val };
}
template <typename ID, typename T>
inline with_gen<ID, T const> with(T const& val)
{
- return with_gen<ID, T const>{val};
+ return { val };
}
}}}
diff --git a/boost/spirit/home/x3/extensions.hpp b/boost/spirit/home/x3/extensions.hpp
deleted file mode 100644
index a40b719c35..0000000000
--- a/boost/spirit/home/x3/extensions.hpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2014 Joel de Guzman
- Copyright (c) 2014 Thomas Bernard
- Copyright (c) 2014 Lee Clagett
-
- Distributed under the 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_SPIRIT_X3_EXTENSIONS_APRIL_6_2014_1421PM)
-#define BOOST_SPIRIT_X3_EXTENSIONS_APRIL_6_2014_1421PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/x3/extensions/seek.hpp>
-
-#endif
diff --git a/boost/spirit/home/x3/nonterminal.hpp b/boost/spirit/home/x3/nonterminal.hpp
index 1e589bd903..b26fda8680 100644
--- a/boost/spirit/home/x3/nonterminal.hpp
+++ b/boost/spirit/home/x3/nonterminal.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_NONTERMINAL_FEBRUARY_12_2007_1018AM)
#define BOOST_SPIRIT_X3_NONTERMINAL_FEBRUARY_12_2007_1018AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/nonterminal/rule.hpp>
//~ #include <boost/spirit/home/x3/nonterminal/error_handler.hpp>
//~ #include <boost/spirit/home/x3/nonterminal/debug_handler.hpp>
diff --git a/boost/spirit/home/x3/nonterminal/debug_handler_state.hpp b/boost/spirit/home/x3/nonterminal/debug_handler_state.hpp
index 800023f013..9ece9b7a74 100644
--- a/boost/spirit/home/x3/nonterminal/debug_handler_state.hpp
+++ b/boost/spirit/home/x3/nonterminal/debug_handler_state.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_DEBUG_HANDLER_STATE_APR_21_2010_0733PM)
#define BOOST_SPIRIT_X3_DEBUG_HANDLER_STATE_APR_21_2010_0733PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
namespace boost { namespace spirit { namespace x3
{
enum debug_handler_state
diff --git a/boost/spirit/home/x3/nonterminal/detail/rule.hpp b/boost/spirit/home/x3/nonterminal/detail/rule.hpp
index 54e2eef234..71dc4c549f 100644
--- a/boost/spirit/home/x3/nonterminal/detail/rule.hpp
+++ b/boost/spirit/home/x3/nonterminal/detail/rule.hpp
@@ -7,11 +7,10 @@
#if !defined(BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM)
#define BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
+#include <boost/spirit/home/x3/auxiliary/guard.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/directive/expect.hpp>
#include <boost/spirit/home/x3/support/traits/make_attribute.hpp>
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
#include <boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp>
@@ -25,8 +24,8 @@ namespace boost { namespace spirit { namespace x3
{
template <typename ID>
struct identity;
-
- template <typename ID, typename Attribute = unused_type>
+
+ template <typename ID, typename Attribute = unused_type, bool force_attribute = false>
struct rule;
struct parse_pass_context_tag;
@@ -43,7 +42,7 @@ namespace boost { namespace spirit { namespace x3
bool r;
};
}
-
+
// default parse_rule implementation
template <typename ID, typename Attribute, typename Iterator
, typename Context, typename ActualAttribute>
@@ -88,7 +87,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
detail::simple_trace_type& f;
};
#endif
-
+
template <typename ID, typename Iterator, typename Context, typename Enable = void>
struct has_on_error : mpl::false_ {};
@@ -106,7 +105,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
>
: mpl::true_
{};
-
+
template <typename ID, typename Iterator, typename Attribute, typename Context, typename Enable = void>
struct has_on_success : mpl::false_ {};
@@ -136,7 +135,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
{
typedef identity<ID> type;
};
-
+
template <typename ID, typename RHS, typename Context>
Context const&
make_rule_context(RHS const& rhs, Context const& context
@@ -144,7 +143,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
{
return context;
}
-
+
template <typename ID, typename RHS, typename Context>
auto make_rule_context(RHS const& rhs, Context const& context
, mpl::true_ /* is_default_parse_rule */ )
@@ -163,7 +162,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
{
return true;
}
-
+
template <typename Iterator, typename Context, typename ActualAttribute>
static bool call_on_success(
Iterator& first, Iterator const& last
@@ -179,7 +178,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
);
return pass;
}
-
+
template <typename RHS, typename Iterator, typename Context
, typename RContext, typename ActualAttribute>
static bool parse_rhs_main(
@@ -219,7 +218,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
r = call_on_success(first_, i, context, attr
, has_on_success<ID, Iterator, Context, ActualAttribute>());
}
-
+
if (r)
first = i;
return r;
@@ -331,7 +330,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
#endif
ok_parse=parse_rhs(rhs, first, last, context, attr_, attr_
, mpl::bool_
- < ( RHS::has_action
+ < ( RHS::has_action
&& !ExplicitAttrPropagation::value
)
>()
@@ -345,40 +344,6 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
}
return ok_parse;
}
-
-// template <typename RuleDef, typename Iterator, typename Context
-// , typename ActualAttribute, typename AttributeContext>
-// static bool call_from_rule(
-// RuleDef const& rule_def
-// , char const* rule_name
-// , Iterator& first, Iterator const& last
-// , Context const& context, ActualAttribute& attr, AttributeContext& attr_ctx)
-// {
-// // This is called when a rule-body has already been established.
-// // The rule body is already established by the rule_definition class,
-// // we will not do it again. We'll simply call the RHS by calling
-// // call_rule_definition.
-//
-// return call_rule_definition(
-// rule_def.rhs, rule_name, first, last
-// , context, attr, attr_ctx.attr_ptr
-// , mpl::bool_<(RuleDef::explicit_attribute_propagation)>());
-// }
-//
-// template <typename RuleDef, typename Iterator, typename Context
-// , typename ActualAttribute>
-// static bool call_from_rule(
-// RuleDef const& rule_def
-// , char const* rule_name
-// , Iterator& first, Iterator const& last
-// , Context const& context, ActualAttribute& attr, unused_type)
-// {
-// // This is called when a rule-body has *not yet* been established.
-// // The rule body is established by the rule_definition class, so
-// // we call it to parse and establish the rule-body.
-//
-// return rule_def.parse(first, last, context, unused, attr); // $$$ fix unused param $$$
-// }
};
}}}}
diff --git a/boost/spirit/home/x3/nonterminal/rule.hpp b/boost/spirit/home/x3/nonterminal/rule.hpp
index 049c6be57b..56075f34d7 100644
--- a/boost/spirit/home/x3/nonterminal/rule.hpp
+++ b/boost/spirit/home/x3/nonterminal/rule.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM)
#define BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/nonterminal/detail/rule.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
@@ -26,7 +22,7 @@ namespace boost { namespace spirit { namespace x3
{
template <typename ID>
struct identity {};
-
+
// default parse_rule implementation
template <typename ID, typename Attribute, typename Iterator
, typename Context, typename ActualAttribute>
@@ -57,7 +53,7 @@ namespace boost { namespace spirit { namespace x3
static bool const force_attribute =
force_attribute_;
- rule_definition(RHS rhs, char const* name)
+ rule_definition(RHS const& rhs, char const* name)
: rhs(rhs), name(name) {}
template <typename Iterator, typename Context, typename Attribute_>
@@ -76,7 +72,7 @@ namespace boost { namespace spirit { namespace x3
char const* name;
};
- template <typename ID, typename Attribute>
+ template <typename ID, typename Attribute, bool force_attribute_>
struct rule : parser<rule<ID, Attribute>>
{
typedef ID id;
@@ -85,6 +81,7 @@ namespace boost { namespace spirit { namespace x3
!is_same<Attribute, unused_type>::value;
static bool const handles_container =
traits::is_container<Attribute>::value;
+ static bool const force_attribute = force_attribute_;
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
rule() : name(typeid(rule).name()) {}
@@ -97,10 +94,10 @@ namespace boost { namespace spirit { namespace x3
template <typename RHS>
rule_definition<
- ID, typename extension::as_parser<RHS>::value_type, Attribute, false>
+ ID, typename extension::as_parser<RHS>::value_type, Attribute, force_attribute_>
operator=(RHS const& rhs) const
{
- return {as_parser(rhs), name};
+ return { as_parser(rhs), name };
}
template <typename RHS>
@@ -108,7 +105,7 @@ namespace boost { namespace spirit { namespace x3
ID, typename extension::as_parser<RHS>::value_type, Attribute, true>
operator%=(RHS const& rhs) const
{
- return {as_parser(rhs), name};
+ return { as_parser(rhs), name };
}
@@ -121,15 +118,15 @@ namespace boost { namespace spirit { namespace x3
char const* name;
};
-
+
namespace traits
{
template <typename T, typename Enable = void>
struct is_rule : mpl::false_ {};
-
+
template <typename ID, typename Attribute>
struct is_rule<rule<ID, Attribute>> : mpl::true_ {};
-
+
template <typename ID, typename Attribute, typename RHS, bool force_attribute>
struct is_rule<rule_definition<ID, RHS, Attribute, force_attribute>> : mpl::true_ {};
}
@@ -143,7 +140,7 @@ namespace boost { namespace spirit { namespace x3
return r.name;
}
};
-
+
#define BOOST_SPIRIT_DECLARE_(r, data, rule_type) \
template <typename Iterator, typename Context, typename Attribute> \
bool parse_rule( \
@@ -155,16 +152,16 @@ namespace boost { namespace spirit { namespace x3
#define BOOST_SPIRIT_DECLARE(...) BOOST_PP_SEQ_FOR_EACH( \
BOOST_SPIRIT_DECLARE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
/***/
-
-#define BOOST_SPIRIT_DEFINE_(r, data, def) \
+
+#define BOOST_SPIRIT_DEFINE_(r, data, rule_name) \
template <typename Iterator, typename Context, typename Attribute> \
inline bool parse_rule( \
- decltype(def)::lhs_type rule_ \
+ decltype(rule_name) rule_ \
, Iterator& first, Iterator const& last \
, Context const& context, Attribute& attr) \
{ \
using boost::spirit::x3::unused; \
- auto const& def_ = (def); \
+ static auto const def_ = (rule_name = BOOST_PP_CAT(rule_name, _def)); \
return def_.parse(first, last, context, unused, attr); \
} \
/***/
@@ -180,7 +177,7 @@ namespace boost { namespace spirit { namespace x3
, Context const& context, rule_type::attribute_type& attr); \
/***/
-
+
}}}
#endif
diff --git a/boost/spirit/home/x3/nonterminal/simple_trace.hpp b/boost/spirit/home/x3/nonterminal/simple_trace.hpp
index b049b4ec3c..dd369c811b 100644
--- a/boost/spirit/home/x3/nonterminal/simple_trace.hpp
+++ b/boost/spirit/home/x3/nonterminal/simple_trace.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM)
#define BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/print_token.hpp>
#include <boost/spirit/home/x3/support/traits/print_attribute.hpp>
diff --git a/boost/spirit/home/x3/numeric.hpp b/boost/spirit/home/x3/numeric.hpp
index c44d668569..ae4d9caa26 100644
--- a/boost/spirit/home/x3/numeric.hpp
+++ b/boost/spirit/home/x3/numeric.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_NUMERIC_FEBRUARY_05_2007_1231PM)
#define BOOST_SPIRIT_X3_NUMERIC_FEBRUARY_05_2007_1231PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/numeric/bool.hpp>
#include <boost/spirit/home/x3/numeric/int.hpp>
#include <boost/spirit/home/x3/numeric/uint.hpp>
diff --git a/boost/spirit/home/x3/numeric/bool.hpp b/boost/spirit/home/x3/numeric/bool.hpp
index 1fb21c16fe..1fd7018b0f 100644
--- a/boost/spirit/home/x3/numeric/bool.hpp
+++ b/boost/spirit/home/x3/numeric/bool.hpp
@@ -14,9 +14,10 @@
namespace boost { namespace spirit { namespace x3
{
- template <typename T, typename BoolPolicies = bool_policies<T>>
- struct bool_parser : parser<bool_parser<T, BoolPolicies>>
+ template <typename T, typename Encoding, typename BoolPolicies = bool_policies<T>>
+ struct bool_parser : parser<bool_parser<T, Encoding, BoolPolicies>>
{
+ typedef Encoding encoding;
typedef T attribute_type;
static bool const has_attribute = true;
@@ -28,16 +29,16 @@ namespace boost { namespace spirit { namespace x3
template <typename Iterator, typename Context>
bool parse(Iterator& first, Iterator const& last
- , Context& context, unused_type, T& attr) const
+ , Context const& context, unused_type, T& attr) const
{
x3::skip_over(first, last, context);
- return policies.parse_true(first, last, attr)
- || policies.parse_false(first, last, attr);
+ return policies.parse_true(first, last, attr, get_case_compare<encoding>(context))
+ || policies.parse_false(first, last, attr, get_case_compare<encoding>(context));
}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
- , Context& context, unused_type, Attribute& attr_param) const
+ , Context const& context, unused_type, Attribute& attr_param) const
{
// this case is called when Attribute is not T
T attr_;
@@ -52,9 +53,10 @@ namespace boost { namespace spirit { namespace x3
BoolPolicies policies;
};
- template <typename T, typename BoolPolicies = bool_policies<T>>
- struct literal_bool_parser : parser<bool_parser<T, BoolPolicies>>
+ template <typename T, typename Encoding, typename BoolPolicies = bool_policies<T>>
+ struct literal_bool_parser : parser<bool_parser<T, Encoding, BoolPolicies>>
{
+ typedef Encoding encoding;
typedef T attribute_type;
static bool const has_attribute = true;
@@ -67,21 +69,28 @@ namespace boost { namespace spirit { namespace x3
: policies(policies), n_(n) {}
template <typename Iterator, typename Context>
+ bool parse_main(Iterator& first, Iterator const& last
+ , Context& context, T& attr) const
+ {
+ x3::skip_over(first, last, context);
+ return (n_ && policies.parse_true(first, last, attr, get_case_compare<encoding>(context)))
+ || (!n_ && policies.parse_false(first, last, attr, get_case_compare<encoding>(context)));
+ }
+
+ template <typename Iterator, typename Context>
bool parse(Iterator& first, Iterator const& last
, Context& context, unused_type, T& attr) const
{
- x3::skip_over(first, last, context);
- return (n_ && policies.parse_true(first, last, attr))
- || (!n_ && policies.parse_false(first, last, attr));
+ return parse_main(first, last, context, attr);
}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
- , Context& context, unused_type, Attribute& attr_param) const
+ , Context const& context, unused_type, Attribute& attr_param) const
{
// this case is called when Attribute is not T
T attr_;
- if (parse(first, last, context, unused, attr_))
+ if (parse_main(first, last, context, attr_))
{
traits::move_to(attr_, attr_param);
return true;
@@ -93,14 +102,58 @@ namespace boost { namespace spirit { namespace x3
T n_;
};
- typedef bool_parser<bool> bool_type;
- bool_type const bool_ = {};
+ namespace standard
+ {
+ typedef bool_parser<bool, char_encoding::standard> bool_type;
+ bool_type const bool_ = {};
+
+ typedef literal_bool_parser<bool, char_encoding::standard> true_type;
+ true_type const true_ = { true };
+
+ typedef literal_bool_parser<bool, char_encoding::standard> false_type;
+ false_type const false_ = { false };
+ }
+
+ namespace standard_wide
+ {
+ typedef bool_parser<bool, char_encoding::standard_wide> bool_type;
+ bool_type const bool_ = {};
+
+ typedef literal_bool_parser<bool, char_encoding::standard_wide> true_type;
+ true_type const true_ = { true };
+
+ typedef literal_bool_parser<bool, char_encoding::standard_wide> false_type;
+ false_type const false_ = { false };
+ }
+
+ namespace ascii
+ {
+ typedef bool_parser<bool, char_encoding::ascii> bool_type;
+ bool_type const bool_ = {};
+
+ typedef literal_bool_parser<bool, char_encoding::ascii> true_type;
+ true_type const true_ = { true };
+
+ typedef literal_bool_parser<bool, char_encoding::ascii> false_type;
+ false_type const false_ = { false };
+ }
+
+ namespace iso8859_1
+ {
+ typedef bool_parser<bool, char_encoding::iso8859_1> bool_type;
+ bool_type const bool_ = {};
+
+ typedef literal_bool_parser<bool, char_encoding::iso8859_1> true_type;
+ true_type const true_ = { true };
+
+ typedef literal_bool_parser<bool, char_encoding::iso8859_1> false_type;
+ false_type const false_ = { false };
+ }
- typedef literal_bool_parser<bool> true_type;
- true_type const true_ = { true };
+ using standard::bool_;
+ using standard::true_;
+ using standard::false_;
- typedef literal_bool_parser<bool> false_type;
- false_type const false_ = { false };
-}}}
+ }}}
#endif
diff --git a/boost/spirit/home/x3/numeric/bool_policies.hpp b/boost/spirit/home/x3/numeric/bool_policies.hpp
index bafc5b5294..7e5227e2a1 100644
--- a/boost/spirit/home/x3/numeric/bool_policies.hpp
+++ b/boost/spirit/home/x3/numeric/bool_policies.hpp
@@ -8,10 +8,6 @@
#if !defined(SPIRIT_QI_BOOL_POLICIES_SEP_29_2009_0710AM)
#define SPIRIT_QI_BOOL_POLICIES_SEP_29_2009_0710AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/string/detail/string_parse.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
@@ -23,11 +19,11 @@ namespace boost { namespace spirit { namespace x3
template <typename T = bool>
struct bool_policies
{
- template <typename Iterator, typename Attribute>
+ template <typename Iterator, typename Attribute, typename CaseCompare>
static bool
- parse_true(Iterator& first, Iterator const& last, Attribute& attr_)
+ parse_true(Iterator& first, Iterator const& last, Attribute& attr_, CaseCompare const& case_compare)
{
- if (detail::string_parse("true", first, last, unused))
+ if (detail::string_parse("true", first, last, unused, case_compare))
{
traits::move_to(T(true), attr_); // result is true
return true;
@@ -35,11 +31,11 @@ namespace boost { namespace spirit { namespace x3
return false;
}
- template <typename Iterator, typename Attribute>
+ template <typename Iterator, typename Attribute, typename CaseCompare>
static bool
- parse_false(Iterator& first, Iterator const& last, Attribute& attr_)
+ parse_false(Iterator& first, Iterator const& last, Attribute& attr_, CaseCompare const& case_compare)
{
- if (detail::string_parse("false", first, last, unused))
+ if (detail::string_parse("false", first, last, unused, case_compare))
{
traits::move_to(T(false), attr_); // result is false
return true;
diff --git a/boost/spirit/home/x3/numeric/int.hpp b/boost/spirit/home/x3/numeric/int.hpp
index ba9ceb8243..2c1832686e 100644
--- a/boost/spirit/home/x3/numeric/int.hpp
+++ b/boost/spirit/home/x3/numeric/int.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_INT_APR_17_2006_0830AM)
#define BOOST_SPIRIT_X3_INT_APR_17_2006_0830AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
diff --git a/boost/spirit/home/x3/numeric/real_policies.hpp b/boost/spirit/home/x3/numeric/real_policies.hpp
index 4e02b266c5..b8fb38c387 100644
--- a/boost/spirit/home/x3/numeric/real_policies.hpp
+++ b/boost/spirit/home/x3/numeric/real_policies.hpp
@@ -8,10 +8,6 @@
#if !defined(SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM)
#define SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/string/detail/string_parse.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
diff --git a/boost/spirit/home/x3/numeric/uint.hpp b/boost/spirit/home/x3/numeric/uint.hpp
index 624bae52de..172c108705 100644
--- a/boost/spirit/home/x3/numeric/uint.hpp
+++ b/boost/spirit/home/x3/numeric/uint.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_UINT_APR_17_2006_0901AM)
#define BOOST_SPIRIT_X3_UINT_APR_17_2006_0901AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
diff --git a/boost/spirit/home/x3/operator.hpp b/boost/spirit/home/x3/operator.hpp
index 1244e2f04d..c67f18c4cc 100644
--- a/boost/spirit/home/x3/operator.hpp
+++ b/boost/spirit/home/x3/operator.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_OPERATOR_FEBRUARY_02_2007_0558PM)
#define BOOST_SPIRIT_X3_OPERATOR_FEBRUARY_02_2007_0558PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/operator/sequence.hpp>
#include <boost/spirit/home/x3/operator/alternative.hpp>
//~ #include <boost/spirit/home/x3/operator/sequential_or.hpp>
diff --git a/boost/spirit/home/x3/operator/alternative.hpp b/boost/spirit/home/x3/operator/alternative.hpp
index 1566780bc6..c3a1e40f3f 100644
--- a/boost/spirit/home/x3/operator/alternative.hpp
+++ b/boost/spirit/home/x3/operator/alternative.hpp
@@ -7,10 +7,6 @@
#if !defined(SPIRIT_ALTERNATIVE_JAN_07_2013_1131AM)
#define SPIRIT_ALTERNATIVE_JAN_07_2013_1131AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/operator/detail/alternative.hpp>
@@ -22,7 +18,7 @@ namespace boost { namespace spirit { namespace x3
{
typedef binary_parser<Left, Right, alternative<Left, Right>> base_type;
- alternative(Left left, Right right)
+ alternative(Left const& left, Right const& right)
: base_type(left, right) {}
template <typename Iterator, typename Context, typename RContext>
@@ -40,11 +36,8 @@ namespace boost { namespace spirit { namespace x3
Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
- if (detail::parse_alternative(this->left, first, last, context, rcontext, attr))
- return true;
- if (detail::parse_alternative(this->right, first, last, context, rcontext, attr))
- return true;
- return false;
+ return detail::parse_alternative(this->left, first, last, context, rcontext, attr)
+ || detail::parse_alternative(this->right, first, last, context, rcontext, attr);
}
};
@@ -54,7 +47,7 @@ namespace boost { namespace spirit { namespace x3
, typename extension::as_parser<Right>::value_type>
operator|(Left const& left, Right const& right)
{
- return {as_parser(left), as_parser(right)};
+ return { as_parser(left), as_parser(right) };
}
}}}
diff --git a/boost/spirit/home/x3/operator/and_predicate.hpp b/boost/spirit/home/x3/operator/and_predicate.hpp
index e0892cd8cf..1d650f7521 100644
--- a/boost/spirit/home/x3/operator/and_predicate.hpp
+++ b/boost/spirit/home/x3/operator/and_predicate.hpp
@@ -7,10 +7,6 @@
#if !defined(SPIRIT_AND_PREDICATE_MARCH_23_2007_0617PM)
#define SPIRIT_AND_PREDICATE_MARCH_23_2007_0617PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
@@ -40,7 +36,7 @@ namespace boost { namespace spirit { namespace x3
inline and_predicate<typename extension::as_parser<Subject>::value_type>
operator&(Subject const& subject)
{
- return {as_parser(subject)};
+ return { as_parser(subject) };
}
}}}
diff --git a/boost/spirit/home/x3/operator/detail/alternative.hpp b/boost/spirit/home/x3/operator/detail/alternative.hpp
index 54f86e00df..9fbc4f4dc4 100644
--- a/boost/spirit/home/x3/operator/detail/alternative.hpp
+++ b/boost/spirit/home/x3/operator/detail/alternative.hpp
@@ -7,10 +7,6 @@
#if !defined(SPIRIT_ALTERNATIVE_DETAIL_JAN_07_2013_1245PM)
#define SPIRIT_ALTERNATIVE_DETAIL_JAN_07_2013_1245PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
#include <boost/spirit/home/x3/support/traits/tuple_traits.hpp>
@@ -23,9 +19,9 @@
#include <boost/mpl/copy_if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/if.hpp>
+#include <boost/mpl/insert_range.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/vector.hpp>
-#include <boost/mpl/joint_view.hpp>
#include <boost/fusion/include/front.hpp>
@@ -182,34 +178,21 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
template <typename LL, typename LR, typename R, typename C>
struct get_alternative_types<alternative<LL, LR>, R, C>
- {
- typedef typename
- mpl::push_back<
- typename get_alternative_types<LL, LR, C>::type
- , typename traits::attribute_of<R, C>::type
- >::type
- type;
- };
+ : mpl::push_back< typename get_alternative_types<LL, LR, C>::type
+ , typename traits::attribute_of<R, C>::type> {};
template <typename L, typename RL, typename RR, typename C>
struct get_alternative_types<L, alternative<RL, RR>, C>
- {
- typedef typename
- mpl::push_front<
- typename get_alternative_types<RL, RR, C>::type
- , typename traits::attribute_of<L, C>::type
- >::type
- type;
- };
+ : mpl::push_front< typename get_alternative_types<RL, RR, C>::type
+ , typename traits::attribute_of<L, C>::type> {};
template <typename LL, typename LR, typename RL, typename RR, typename C>
struct get_alternative_types<alternative<LL, LR>, alternative<RL, RR>, C>
{
- typedef
- mpl::joint_view<
- typename get_alternative_types<LL, LR, C>::type
- , typename get_alternative_types<RL, RR, C>::type
- >
+ typedef typename get_alternative_types<LL, LR, C>::type left;
+ typedef typename get_alternative_types<RL, RR, C>::type right;
+ typedef typename
+ mpl::insert_range<left, typename mpl::end<left>::type, right>::type
type;
};
diff --git a/boost/spirit/home/x3/operator/detail/sequence.hpp b/boost/spirit/home/x3/operator/detail/sequence.hpp
index 1163707128..e54a8f6a9e 100644
--- a/boost/spirit/home/x3/operator/detail/sequence.hpp
+++ b/boost/spirit/home/x3/operator/detail/sequence.hpp
@@ -7,10 +7,6 @@
#if !defined(SPIRIT_SEQUENCE_DETAIL_JAN_06_2013_1015AM)
#define SPIRIT_SEQUENCE_DETAIL_JAN_06_2013_1015AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
#include <boost/spirit/home/x3/support/traits/make_attribute.hpp>
@@ -31,9 +27,9 @@
#include <boost/mpl/copy_if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/if.hpp>
+#include <boost/mpl/insert_range.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/vector.hpp>
-#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/type_traits/add_reference.hpp>
@@ -247,34 +243,21 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
template <typename LL, typename LR, typename R, typename C>
struct get_sequence_types<sequence<LL, LR>, R, C>
- {
- typedef typename
- mpl::push_back<
- typename get_sequence_types<LL, LR, C>::type
- , typename traits::attribute_of<R, C>::type
- >::type
- type;
- };
+ : mpl::push_back< typename get_sequence_types<LL, LR, C>::type
+ , typename traits::attribute_of<R, C>::type> {};
template <typename L, typename RL, typename RR, typename C>
struct get_sequence_types<L, sequence<RL, RR>, C>
- {
- typedef typename
- mpl::push_front<
- typename get_sequence_types<RL, RR, C>::type
- , typename traits::attribute_of<L, C>::type
- >::type
- type;
- };
+ : mpl::push_front< typename get_sequence_types<RL, RR, C>::type
+ , typename traits::attribute_of<L, C>::type> {};
template <typename LL, typename LR, typename RL, typename RR, typename C>
struct get_sequence_types<sequence<LL, LR>, sequence<RL, RR>, C>
{
- typedef
- mpl::joint_view<
- typename get_sequence_types<LL, LR, C>::type
- , typename get_sequence_types<RL, RR, C>::type
- >
+ typedef typename get_sequence_types<LL, LR, C>::type left;
+ typedef typename get_sequence_types<RL, RR, C>::type right;
+ typedef typename
+ mpl::insert_range<left, typename mpl::end<left>::type, right>::type
type;
};
@@ -334,10 +317,9 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
template <typename Parser, typename Iterator, typename Context
, typename RContext, typename Attribute>
- bool parse_sequence(
- Parser const& parser , Iterator& first, Iterator const& last
- , Context const& context, RContext& rcontext, Attribute& attr
- , traits::plain_attribute)
+ bool parse_sequence_plain(
+ Parser const& parser, Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr)
{
typedef typename Parser::left_type Left;
typedef typename Parser::right_type Right;
@@ -357,6 +339,26 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
return false;
}
+ template <typename Parser, typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse_sequence(
+ Parser const& parser, Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr
+ , traits::plain_attribute)
+ {
+ return parse_sequence_plain(parser, first, last, context, rcontext, attr);
+ }
+
+ template <typename Parser, typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse_sequence(
+ Parser const& parser, Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr
+ , traits::variant_attribute)
+ {
+ return parse_sequence_plain(parser, first, last, context, rcontext, attr);
+ }
+
template <typename Left, typename Right, typename Iterator
, typename Context, typename RContext, typename Attribute>
bool parse_sequence(
diff --git a/boost/spirit/home/x3/operator/difference.hpp b/boost/spirit/home/x3/operator/difference.hpp
index 13a9274de0..a75e713821 100644
--- a/boost/spirit/home/x3/operator/difference.hpp
+++ b/boost/spirit/home/x3/operator/difference.hpp
@@ -7,10 +7,6 @@
#if !defined(SPIRIT_DIFFERENCE_FEBRUARY_11_2007_1250PM)
#define SPIRIT_DIFFERENCE_FEBRUARY_11_2007_1250PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
@@ -47,7 +43,7 @@ namespace boost { namespace spirit { namespace x3
difference<Left_, Right_>
make(Left_ const& left, Right_ const& right) const
{
- return difference<Left_, Right_>(left, right);
+ return { left, right };
}
};
@@ -57,7 +53,7 @@ namespace boost { namespace spirit { namespace x3
, typename extension::as_parser<Right>::value_type>
operator-(Left const& left, Right const& right)
{
- return {as_parser(left), as_parser(right)};
+ return { as_parser(left), as_parser(right) };
}
}}}
diff --git a/boost/spirit/home/x3/operator/kleene.hpp b/boost/spirit/home/x3/operator/kleene.hpp
index 7e02bf4a02..b0fb5a1df1 100644
--- a/boost/spirit/home/x3/operator/kleene.hpp
+++ b/boost/spirit/home/x3/operator/kleene.hpp
@@ -8,10 +8,6 @@
#if !defined(SPIRIT_KLEENE_JANUARY_07_2007_0818AM)
#define SPIRIT_KLEENE_JANUARY_07_2007_0818AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
@@ -44,7 +40,7 @@ namespace boost { namespace spirit { namespace x3
inline kleene<typename extension::as_parser<Subject>::value_type>
operator*(Subject const& subject)
{
- return {as_parser(subject)};
+ return { as_parser(subject) };
}
}}}
diff --git a/boost/spirit/home/x3/operator/list.hpp b/boost/spirit/home/x3/operator/list.hpp
index a463a7f9e0..23b398b128 100644
--- a/boost/spirit/home/x3/operator/list.hpp
+++ b/boost/spirit/home/x3/operator/list.hpp
@@ -8,10 +8,6 @@
#if !defined(SPIRIT_LIST_MARCH_24_2007_1031AM)
#define SPIRIT_LIST_MARCH_24_2007_1031AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
@@ -58,7 +54,7 @@ namespace boost { namespace spirit { namespace x3
, typename extension::as_parser<Right>::value_type>
operator%(Left const& left, Right const& right)
{
- return {as_parser(left), as_parser(right)};
+ return { as_parser(left), as_parser(right) };
}
}}}
diff --git a/boost/spirit/home/x3/operator/not_predicate.hpp b/boost/spirit/home/x3/operator/not_predicate.hpp
index 38b24bd2e2..d0302e6142 100644
--- a/boost/spirit/home/x3/operator/not_predicate.hpp
+++ b/boost/spirit/home/x3/operator/not_predicate.hpp
@@ -7,10 +7,6 @@
#if !defined(SPIRIT_NOT_PREDICATE_MARCH_23_2007_0618PM)
#define SPIRIT_NOT_PREDICATE_MARCH_23_2007_0618PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
@@ -40,7 +36,7 @@ namespace boost { namespace spirit { namespace x3
inline not_predicate<typename extension::as_parser<Subject>::value_type>
operator!(Subject const& subject)
{
- return {as_parser(subject)};
+ return { as_parser(subject) };
}
}}}
diff --git a/boost/spirit/home/x3/operator/optional.hpp b/boost/spirit/home/x3/operator/optional.hpp
index 16432f89d1..a40228849a 100644
--- a/boost/spirit/home/x3/operator/optional.hpp
+++ b/boost/spirit/home/x3/operator/optional.hpp
@@ -8,10 +8,6 @@
#if !defined(SPIRIT_OPTIONAL_MARCH_23_2007_1117PM)
#define SPIRIT_OPTIONAL_MARCH_23_2007_1117PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/proxy.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
@@ -71,7 +67,7 @@ namespace boost { namespace spirit { namespace x3
inline optional<typename extension::as_parser<Subject>::value_type>
operator-(Subject const& subject)
{
- return {as_parser(subject)};
+ return { as_parser(subject) };
}
}}}
diff --git a/boost/spirit/home/x3/operator/plus.hpp b/boost/spirit/home/x3/operator/plus.hpp
index 32c7dbfffb..152731e622 100644
--- a/boost/spirit/home/x3/operator/plus.hpp
+++ b/boost/spirit/home/x3/operator/plus.hpp
@@ -8,10 +8,6 @@
#if !defined(SPIRIT_PLUS_MARCH_13_2007_0127PM)
#define SPIRIT_PLUS_MARCH_13_2007_0127PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
@@ -48,7 +44,7 @@ namespace boost { namespace spirit { namespace x3
inline plus<typename extension::as_parser<Subject>::value_type>
operator+(Subject const& subject)
{
- return {as_parser(subject)};
+ return { as_parser(subject) };
}
}}}
diff --git a/boost/spirit/home/x3/operator/sequence.hpp b/boost/spirit/home/x3/operator/sequence.hpp
index 23d5e3d8d9..661a23cd37 100644
--- a/boost/spirit/home/x3/operator/sequence.hpp
+++ b/boost/spirit/home/x3/operator/sequence.hpp
@@ -7,10 +7,6 @@
#if !defined(SPIRIT_SEQUENCE_JAN_06_2013_1015AM)
#define SPIRIT_SEQUENCE_JAN_06_2013_1015AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/operator/detail/sequence.hpp>
@@ -23,7 +19,7 @@ namespace boost { namespace spirit { namespace x3
{
typedef binary_parser<Left, Right, sequence<Left, Right>> base_type;
- sequence(Left left, Right right)
+ sequence(Left const& left, Right const& right)
: base_type(left, right) {}
template <typename Iterator, typename Context, typename RContext>
@@ -56,16 +52,13 @@ namespace boost { namespace spirit { namespace x3
, typename extension::as_parser<Right>::value_type>
operator>>(Left const& left, Right const& right)
{
- return {as_parser(left), as_parser(right)};
+ return { as_parser(left), as_parser(right) };
}
template <typename Left, typename Right>
- inline sequence<
- typename extension::as_parser<Left>::value_type
- , expect_directive<typename extension::as_parser<Right>::value_type>>
- operator>(Left const& left, Right const& right)
+ auto operator>(Left const& left, Right const& right)
{
- return {as_parser(left), as_parser(right)};
+ return left >> expect[right];
}
}}}
diff --git a/boost/spirit/home/x3/string.hpp b/boost/spirit/home/x3/string.hpp
index e0f5c6ebac..425e731134 100644
--- a/boost/spirit/home/x3/string.hpp
+++ b/boost/spirit/home/x3/string.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_STRING_FEBRUARY_03_2007_0355PM)
#define BOOST_SPIRIT_X3_STRING_FEBRUARY_03_2007_0355PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/string/literal_string.hpp>
#include <boost/spirit/home/x3/string/symbols.hpp>
diff --git a/boost/spirit/home/x3/string/detail/no_case_string_parse.hpp b/boost/spirit/home/x3/string/detail/no_case_string_parse.hpp
new file mode 100644
index 0000000000..6e1bbf4cee
--- /dev/null
+++ b/boost/spirit/home/x3/string/detail/no_case_string_parse.hpp
@@ -0,0 +1,60 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+
+ Distributed under the 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_SPIRIT_X3_NO_CASE_STRING_PARSE_APR_18_2014_1125PM)
+#define BOOST_SPIRIT_X3_NO_CASE_STRING_PARSE_APR_18_2014_1125PM
+
+#include <boost/spirit/home/x3/char/char.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ template <typename Char, typename Encoding>
+ struct no_case_string
+ {
+ typedef std::basic_string< Char > string_type;
+ typedef typename string_type::const_iterator const_iterator;
+
+ no_case_string(char_type const* str)
+ : lower(str)
+ , upper(str)
+ {
+ typename string_type::iterator loi = lower.begin();
+ typename string_type::iterator upi = upper.begin();
+
+ typedef typename Encoding::char_type encoded_char_type;
+ Encoding encoding;
+ for (; loi != lower.end(); ++loi, ++upi)
+ {
+ *loi = static_cast<char_type>(encoding.tolower(encoded_char_type(*loi)));
+ *upi = static_cast<char_type>(encoding.toupper(encoded_char_type(*upi)));
+ }
+ }
+ string_type lower;
+ string_type upper;
+
+ };
+
+ template <typename String, typename Iterator, typename Attribute>
+ inline bool no_case_string_parse(
+ String const& str
+ , Iterator& first, Iterator const& last, Attribute& attr)
+ {
+ typename String::const_iterator uc_i = str.upper.begin();
+ typename String::const_iterator uc_last = str.upper.end();
+ typename String::const_iterator lc_i = str.lower.begin();
+ Iterator i = first;
+
+ for (; uc_i != uc_last; ++uc_i, ++lc_i, ++i)
+ if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
+ return false;
+ x3::traits::move_to(first, i, attr);
+ first = i;
+ return true;
+ }
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/string/detail/string_parse.hpp b/boost/spirit/home/x3/string/detail/string_parse.hpp
index f7a77df804..dd7de67692 100644
--- a/boost/spirit/home/x3/string/detail/string_parse.hpp
+++ b/boost/spirit/home/x3/string/detail/string_parse.hpp
@@ -7,25 +7,21 @@
#if !defined(BOOST_SPIRIT_X3_STRING_PARSE_APR_18_2006_1125PM)
#define BOOST_SPIRIT_X3_STRING_PARSE_APR_18_2006_1125PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
- template <typename Char, typename Iterator, typename Attribute>
+ template <typename Char, typename Iterator, typename Attribute, typename CaseCompareFunc>
inline bool string_parse(
Char const* str
- , Iterator& first, Iterator const& last, Attribute& attr)
+ , Iterator& first, Iterator const& last, Attribute& attr, CaseCompareFunc const& compare)
{
Iterator i = first;
Char ch = *str;
for (; !!ch; ++i)
{
- if (i == last || (ch != *i))
+ if (i == last || (compare(ch, *i) != 0))
return false;
ch = *++str;
}
@@ -35,17 +31,17 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
return true;
}
- template <typename String, typename Iterator, typename Attribute>
+ template <typename String, typename Iterator, typename Attribute, typename CaseCompareFunc>
inline bool string_parse(
String const& str
- , Iterator& first, Iterator const& last, Attribute& attr)
+ , Iterator& first, Iterator const& last, Attribute& attr, CaseCompareFunc const& compare)
{
Iterator i = first;
typename String::const_iterator stri = str.begin();
typename String::const_iterator str_last = str.end();
for (; stri != str_last; ++stri, ++i)
- if (i == last || (*stri != *i))
+ if (i == last || (compare(*stri, *i) != 0))
return false;
x3::traits::move_to(first, i, attr);
first = i;
diff --git a/boost/spirit/home/x3/string/detail/tst.hpp b/boost/spirit/home/x3/string/detail/tst.hpp
index df61f4dec7..50f6df6a95 100644
--- a/boost/spirit/home/x3/string/detail/tst.hpp
+++ b/boost/spirit/home/x3/string/detail/tst.hpp
@@ -7,13 +7,8 @@
#if !defined(BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM)
#define BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/call_traits.hpp>
#include <boost/detail/iterator.hpp>
-#include <boost/foreach.hpp>
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
@@ -61,9 +56,9 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
return 0;
}
- template <typename Iterator, typename Filter>
+ template <typename Iterator, typename CaseCompare>
static T*
- find(tst_node* start, Iterator& first, Iterator last, Filter filter)
+ find(tst_node* start, Iterator& first, Iterator last, CaseCompare comp)
{
if (first == last)
return 0;
@@ -75,11 +70,8 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
while (p && i != last)
{
- typename
- boost::detail::iterator_traits<Iterator>::value_type
- c = filter(*i); // filter only the input
-
- if (c == p->id)
+ int32_t c = comp(*i,p->id);
+ if (c == 0)
{
if (p->data)
{
@@ -89,7 +81,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
p = p->eq;
i++;
}
- else if (c < p->id)
+ else if (c < 0)
{
p = p->lt;
}
@@ -117,7 +109,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
return 0;
tst_node** pp = &start;
- for(;;)
+ for (;;)
{
typename
boost::detail::iterator_traits<Iterator>::value_type
diff --git a/boost/spirit/home/x3/string/literal_string.hpp b/boost/spirit/home/x3/string/literal_string.hpp
index bf05a9a08e..c562721b2e 100644
--- a/boost/spirit/home/x3/string/literal_string.hpp
+++ b/boost/spirit/home/x3/string/literal_string.hpp
@@ -7,13 +7,11 @@
#if !defined(BOOST_SPIRIT_X3_LITERAL_STRING_APR_18_2006_1125PM)
#define BOOST_SPIRIT_X3_LITERAL_STRING_APR_18_2006_1125PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/string/detail/string_parse.hpp>
+#include <boost/spirit/home/x3/support/no_case.hpp>
+#include <boost/spirit/home/x3/string/detail/no_case_string_parse.hpp>
#include <boost/spirit/home/x3/support/utility/utf8.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/spirit/home/support/char_encoding/standard.hpp>
@@ -36,7 +34,7 @@ namespace boost { namespace spirit { namespace x3
!is_same<unused_type, attribute_type>::value;
static bool const handles_container = has_attribute;
- literal_string(typename add_reference<String>::type str)
+ literal_string(typename add_reference< typename add_const<String>::type >::type str)
: str(str)
{}
@@ -45,7 +43,7 @@ namespace boost { namespace spirit { namespace x3
, Context const& context, unused_type, Attribute_& attr) const
{
x3::skip_over(first, last, context);
- return detail::string_parse(str, first, last, attr);
+ return detail::string_parse(str, first, last, attr, get_case_compare<encoding>(context));
}
String str;
@@ -56,19 +54,124 @@ namespace boost { namespace spirit { namespace x3
inline literal_string<char const*, char_encoding::standard>
string(char const* s)
{
- return literal_string<char const*, char_encoding::standard>(s);
+ return { s };
+ }
+
+ inline literal_string<std::basic_string<char>, char_encoding::standard>
+ string(std::basic_string<char> const& s)
+ {
+ return { s };
+ }
+
+ inline literal_string<char const*, char_encoding::standard, unused_type>
+ lit(char const* s)
+ {
+ return { s };
+ }
+
+ template <typename Char>
+ literal_string<Char const*, char_encoding::standard, unused_type>
+ lit(std::basic_string<Char> const& s)
+ {
+ return { s.c_str() };
+ }
+ }
+
+ namespace standard_wide
+ {
+ inline literal_string<wchar_t const*, char_encoding::standard_wide>
+ string(wchar_t const* s)
+ {
+ return { s };
+ }
+
+ inline literal_string<std::basic_string<wchar_t>, char_encoding::standard_wide>
+ string(std::basic_string<wchar_t> const& s)
+ {
+ return { s };
+ }
+
+ inline literal_string<wchar_t const*, char_encoding::standard_wide, unused_type>
+ lit(wchar_t const* s)
+ {
+ return { s };
+ }
+
+ inline literal_string<wchar_t const*, char_encoding::standard_wide, unused_type>
+ lit(std::basic_string<wchar_t> const& s)
+ {
+ return { s.c_str() };
}
}
+
+ namespace ascii
+ {
+ inline literal_string<wchar_t const*, char_encoding::ascii>
+ string(wchar_t const* s)
+ {
+ return { s };
+ }
+
+ inline literal_string<std::basic_string<wchar_t>, char_encoding::ascii>
+ string(std::basic_string<wchar_t> const& s)
+ {
+ return { s };
+ }
+
+ inline literal_string<char const*, char_encoding::ascii, unused_type>
+ lit(char const* s)
+ {
+ return { s };
+ }
+
+ template <typename Char>
+ literal_string<Char const*, char_encoding::ascii, unused_type>
+ lit(std::basic_string<Char> const& s)
+ {
+ return { s.c_str() };
+ }
+ }
+
+ namespace iso8859_1
+ {
+ inline literal_string<wchar_t const*, char_encoding::iso8859_1>
+ string(wchar_t const* s)
+ {
+ return { s };
+ }
+
+ inline literal_string<std::basic_string<wchar_t>, char_encoding::iso8859_1>
+ string(std::basic_string<wchar_t> const& s)
+ {
+ return { s };
+ }
+
+ inline literal_string<char const*, char_encoding::iso8859_1, unused_type>
+ lit(char const* s)
+ {
+ return { s };
+ }
+
+ template <typename Char>
+ literal_string<Char const*, char_encoding::iso8859_1, unused_type>
+ lit(std::basic_string<Char> const& s)
+ {
+ return { s.c_str() };
+ }
+ }
+
using standard::string;
+ using standard::lit;
+ using standard_wide::string;
+ using standard_wide::lit;
namespace extension
{
template <int N>
struct as_parser<char[N]>
{
- typedef
- literal_string<
- char const*, char_encoding::standard, unused_type>
+ typedef literal_string<
+ char const*, char_encoding::standard, unused_type>
type;
typedef type value_type;
@@ -85,9 +188,8 @@ namespace boost { namespace spirit { namespace x3
template <int N>
struct as_parser<wchar_t[N]>
{
- typedef
- literal_string<
- wchar_t const*, char_encoding::standard_wide, unused_type>
+ typedef literal_string<
+ wchar_t const*, char_encoding::standard_wide, unused_type>
type;
typedef type value_type;
@@ -100,14 +202,36 @@ namespace boost { namespace spirit { namespace x3
template <int N>
struct as_parser<wchar_t const[N]> : as_parser<wchar_t[N]> {};
- }
- using standard::string;
+ template <>
+ struct as_parser<char const*>
+ {
+ typedef literal_string<
+ char const*, char_encoding::standard, unused_type>
+ type;
- inline literal_string<char const*, char_encoding::standard, unused_type>
- lit(char const* s)
- {
- return literal_string<char const*, char_encoding::standard, unused_type>(s);
+ typedef type value_type;
+
+ static type call(char const* s)
+ {
+ return type(s);
+ }
+ };
+
+ template <typename Char>
+ struct as_parser< std::basic_string<Char> >
+ {
+ typedef literal_string<
+ Char const*, char_encoding::standard, unused_type>
+ type;
+
+ typedef type value_type;
+
+ static type call(std::basic_string<Char> const& s)
+ {
+ return type(s.c_str());
+ }
+ };
}
template <typename String, typename Encoding, typename Attribute>
diff --git a/boost/spirit/home/x3/string/symbols.hpp b/boost/spirit/home/x3/string/symbols.hpp
index b35a00a121..2d00944be2 100644
--- a/boost/spirit/home/x3/string/symbols.hpp
+++ b/boost/spirit/home/x3/string/symbols.hpp
@@ -8,16 +8,18 @@
#if !defined(BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM)
#define BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/string/tst.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/string_traits.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/spirit/home/x3/support/no_case.hpp>
+
+#include <boost/spirit/home/support/char_encoding/ascii.hpp>
+#include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
+#include <boost/spirit/home/support/char_encoding/standard.hpp>
+#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/range.hpp>
@@ -35,15 +37,14 @@
namespace boost { namespace spirit { namespace x3
{
template <
- typename Char = char
+ typename Encoding
, typename T = unused_type
- , typename Lookup = tst<Char, T>
- , typename Filter = tst_pass_through>
- struct symbols : parser<symbols<Char, T, Lookup, Filter>>
+ , typename Lookup = tst<typename Encoding::char_type, T> >
+ struct symbols_parser : parser<symbols_parser<Encoding, T, Lookup>>
{
- typedef Char char_type; // the character type
+ typedef typename Encoding::char_type char_type; // the character type
+ typedef Encoding encoding;
typedef T value_type; // the value associated with each entry
- typedef symbols<Char, T, Lookup, Filter> this_type;
typedef value_type attribute_type;
static bool const has_attribute =
@@ -51,7 +52,7 @@ namespace boost { namespace spirit { namespace x3
static bool const handles_container =
traits::is_container<attribute_type>::value;
- symbols(std::string const& name = "symbols")
+ symbols_parser(std::string const& name = "symbols")
: add(*this)
, remove(*this)
, lookup(new Lookup())
@@ -59,16 +60,7 @@ namespace boost { namespace spirit { namespace x3
{
}
- symbols(symbols const& syms)
- : add(*this)
- , remove(*this)
- , lookup(syms.lookup)
- , name_(syms.name_)
- {
- }
-
- template <typename Filter_>
- symbols(symbols<Char, T, Lookup, Filter_> const& syms)
+ symbols_parser(symbols_parser const& syms)
: add(*this)
, remove(*this)
, lookup(syms.lookup)
@@ -77,7 +69,7 @@ namespace boost { namespace spirit { namespace x3
}
template <typename Symbols>
- symbols(Symbols const& syms, std::string const& name = "symbols")
+ symbols_parser(Symbols const& syms, std::string const& name = "symbols")
: add(*this)
, remove(*this)
, lookup(new Lookup())
@@ -89,7 +81,7 @@ namespace boost { namespace spirit { namespace x3
}
template <typename Symbols, typename Data>
- symbols(Symbols const& syms, Data const& data
+ symbols_parser(Symbols const& syms, Data const& data
, std::string const& name = "symbols")
: add(*this)
, remove(*this)
@@ -102,43 +94,34 @@ namespace boost { namespace spirit { namespace x3
add(*si++, *di++);
}
- symbols(std::initializer_list<std::pair<Char const*, T>> syms
+ symbols_parser(std::initializer_list<std::pair<char_type const*, T>> syms
, std::string const & name="symbols")
: add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
- typedef std::initializer_list<std::pair<Char const*, T>> symbols_t;
+ typedef std::initializer_list<std::pair<char_type const*, T>> symbols_t;
typename range_const_iterator<symbols_t>::type si = boost::begin(syms);
for (;si != boost::end(syms); ++si)
add(si->first, si->second);
}
-
- symbols(std::initializer_list<Char const*> syms
+
+ symbols_parser(std::initializer_list<char_type const*> syms
, std::string const &name="symbols")
: add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
- typedef std::initializer_list<Char const*> symbols_t;
+ typedef std::initializer_list<char_type const*> symbols_t;
typename range_const_iterator<symbols_t>::type si = boost::begin(syms);
while (si != boost::end(syms))
add(*si++);
}
- symbols&
- operator=(symbols const& rhs)
- {
- name_ = rhs.name_;
- lookup = rhs.lookup;
- return *this;
- }
-
- template <typename Filter_>
- symbols&
- operator=(symbols<Char, T, Lookup, Filter_> const& rhs)
+ symbols_parser&
+ operator=(symbols_parser const& rhs)
{
name_ = rhs.name_;
lookup = rhs.lookup;
@@ -163,14 +146,14 @@ namespace boost { namespace spirit { namespace x3
template <typename Str>
friend adder const&
- operator+=(symbols& sym, Str const& str)
+ operator+=(symbols_parser& sym, Str const& str)
{
return sym.add(str);
}
template <typename Str>
friend remover const&
- operator-=(symbols& sym, Str const& str)
+ operator-=(symbols_parser& sym, Str const& str)
{
return sym.remove(str);
}
@@ -184,48 +167,48 @@ namespace boost { namespace spirit { namespace x3
template <typename Str>
value_type& at(Str const& str)
{
- return *lookup->add(traits::get_string_begin<Char>(str)
- , traits::get_string_end<Char>(str), T());
+ return *lookup->add(traits::get_string_begin<char_type>(str)
+ , traits::get_string_end<char_type>(str), T());
}
template <typename Iterator>
value_type* prefix_find(Iterator& first, Iterator const& last)
{
- return lookup->find(first, last, Filter());
+ return lookup->find(first, last, case_compare<Encoding>());
}
template <typename Iterator>
value_type const* prefix_find(Iterator& first, Iterator const& last) const
{
- return lookup->find(first, last, Filter());
+ return lookup->find(first, last, case_compare<Encoding>());
}
template <typename Str>
value_type* find(Str const& str)
{
- return find_impl(traits::get_string_begin<Char>(str)
- , traits::get_string_end<Char>(str));
+ return find_impl(traits::get_string_begin<char_type>(str)
+ , traits::get_string_end<char_type>(str));
}
template <typename Str>
value_type const* find(Str const& str) const
{
- return find_impl(traits::get_string_begin<Char>(str)
- , traits::get_string_end<Char>(str));
+ return find_impl(traits::get_string_begin<char_type>(str)
+ , traits::get_string_end<char_type>(str));
}
private:
template <typename Iterator>
value_type* find_impl(Iterator begin, Iterator end)
{
- value_type* r = lookup->find(begin, end, Filter());
+ value_type* r = lookup->find(begin, end, case_compare<Encoding>());
return begin == end ? r : 0;
}
template <typename Iterator>
value_type const* find_impl(Iterator begin, Iterator end) const
{
- value_type const* r = lookup->find(begin, end, Filter());
+ value_type const* r = lookup->find(begin, end, case_compare<Encoding>());
return begin == end ? r : 0;
}
@@ -237,7 +220,7 @@ namespace boost { namespace spirit { namespace x3
x3::skip_over(first, last, context);
if (value_type* val_ptr
- = lookup->find(first, last, Filter()))
+ = lookup->find(first, last, get_case_compare<Encoding>(context)))
{
x3::traits::move_to(*val_ptr, attr);
return true;
@@ -259,7 +242,7 @@ namespace boost { namespace spirit { namespace x3
template <typename, typename = unused_type, typename = unused_type>
struct result { typedef adder const& type; };
- adder(symbols& sym)
+ adder(symbols_parser& sym)
: sym(sym)
{
}
@@ -276,8 +259,8 @@ namespace boost { namespace spirit { namespace x3
adder const&
operator()(Str const& s, T const& val = T()) const
{
- sym.lookup->add(traits::get_string_begin<Char>(s)
- , traits::get_string_end<Char>(s), val);
+ sym.lookup->add(traits::get_string_begin<char_type>(s)
+ , traits::get_string_end<char_type>(s), val);
return *this;
}
@@ -285,12 +268,12 @@ namespace boost { namespace spirit { namespace x3
adder const&
operator,(Str const& s) const
{
- sym.lookup->add(traits::get_string_begin<Char>(s)
- , traits::get_string_end<Char>(s), T());
+ sym.lookup->add(traits::get_string_begin<char_type>(s)
+ , traits::get_string_end<char_type>(s), T());
return *this;
}
- symbols& sym;
+ symbols_parser& sym;
};
struct remover
@@ -298,7 +281,7 @@ namespace boost { namespace spirit { namespace x3
template <typename, typename = unused_type, typename = unused_type>
struct result { typedef remover const& type; };
- remover(symbols& sym)
+ remover(symbols_parser& sym)
: sym(sym)
{
}
@@ -315,8 +298,8 @@ namespace boost { namespace spirit { namespace x3
remover const&
operator()(Str const& s) const
{
- sym.lookup->remove(traits::get_string_begin<Char>(s)
- , traits::get_string_end<Char>(s));
+ sym.lookup->remove(traits::get_string_begin<char_type>(s)
+ , traits::get_string_end<char_type>(s));
return *this;
}
@@ -324,12 +307,12 @@ namespace boost { namespace spirit { namespace x3
remover const&
operator,(Str const& s) const
{
- sym.lookup->remove(traits::get_string_begin<Char>(s)
- , traits::get_string_end<Char>(s));
+ sym.lookup->remove(traits::get_string_begin<char_type>(s)
+ , traits::get_string_end<char_type>(s));
return *this;
}
- symbols& sym;
+ symbols_parser& sym;
};
adder add;
@@ -338,17 +321,44 @@ namespace boost { namespace spirit { namespace x3
std::string name_;
};
- template <typename Char, typename T, typename Lookup, typename Filter>
- struct get_info<symbols<Char, T, Lookup, Filter>>
+ template <typename Encoding, typename T, typename Lookup>
+ struct get_info<symbols_parser<Encoding, T, Lookup>>
{
typedef std::string result_type;
- result_type operator()(symbols< Char, T
- , Lookup, Filter
+ result_type operator()(symbols_parser< Encoding, T
+ , Lookup
> const& symbols) const
{
return symbols.name();
}
};
+
+ namespace standard
+ {
+ template <typename T = unused_type>
+ using symbols = symbols_parser<char_encoding::standard, T>;
+ }
+
+ using standard::symbols;
+
+ namespace standard_wide
+ {
+ template <typename T = unused_type>
+ using symbols = symbols_parser<char_encoding::standard_wide, T>;
+ }
+
+ namespace ascii
+ {
+ template <typename T = unused_type>
+ using symbols = symbols_parser<char_encoding::ascii, T>;
+ }
+
+ namespace iso8859_1
+ {
+ template <typename T = unused_type>
+ using symbols = symbols_parser<char_encoding::iso8859_1, T>;
+ }
+
}}}
#if defined(BOOST_MSVC)
diff --git a/boost/spirit/home/x3/string/tst.hpp b/boost/spirit/home/x3/string/tst.hpp
index 5379b032be..704ef92c70 100644
--- a/boost/spirit/home/x3/string/tst.hpp
+++ b/boost/spirit/home/x3/string/tst.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_TST_JUNE_03_2007_1031AM)
#define BOOST_SPIRIT_X3_TST_JUNE_03_2007_1031AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/string/detail/tst.hpp>
namespace boost { namespace spirit { namespace x3
@@ -52,17 +48,17 @@ namespace boost { namespace spirit { namespace x3
return assign(rhs);
}
- template <typename Iterator, typename Filter>
- T* find(Iterator& first, Iterator last, Filter filter) const
+ template <typename Iterator, typename CaseCompare>
+ T* find(Iterator& first, Iterator last, CaseCompare caseCompare) const
{
- return node::find(root, first, last, filter);
+ return node::find(root, first, last, caseCompare);
}
- template <typename Iterator>
+ /*template <typename Iterator>
T* find(Iterator& first, Iterator last) const
{
- return find(first, last, tst_pass_through());
- }
+ return find(first, last, case_compare<tst_pass_through());
+ }*/
template <typename Iterator>
T* add(
diff --git a/boost/spirit/home/x3/string/tst_map.hpp b/boost/spirit/home/x3/string/tst_map.hpp
index 2501324de6..11fb135449 100644
--- a/boost/spirit/home/x3/string/tst_map.hpp
+++ b/boost/spirit/home/x3/string/tst_map.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_TST_MAP_JUNE_03_2007_1143AM)
#define BOOST_SPIRIT_X3_TST_MAP_JUNE_03_2007_1143AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/string/detail/tst.hpp>
#include <unordered_map>
#include <boost/pool/object_pool.hpp>
@@ -129,7 +125,7 @@ namespace boost { namespace spirit { namespace x3
void clear()
{
- BOOST_FOREACH(typename map_type::value_type& x, map)
+ for (typename map_type::value_type& x : map)
{
node::destruct_node(x.second.root, this);
if (x.second.data)
@@ -141,7 +137,7 @@ namespace boost { namespace spirit { namespace x3
template <typename F>
void for_each(F f) const
{
- BOOST_FOREACH(typename map_type::value_type const& x, map)
+ for (typename map_type::value_type const& x : map)
{
std::basic_string<Char> s(1, x.first);
node::for_each(x.second.root, s, f);
@@ -164,7 +160,7 @@ namespace boost { namespace spirit { namespace x3
void copy(tst_map const& rhs)
{
- BOOST_FOREACH(typename map_type::value_type const& x, rhs.map)
+ for (typename map_type::value_type const& x : rhs.map)
{
map_data xx = {node::clone_node(x.second.root, this), 0};
if (x.second.data)
@@ -177,7 +173,7 @@ namespace boost { namespace spirit { namespace x3
{
if (this != &rhs)
{
- BOOST_FOREACH(typename map_type::value_type& x, map)
+ for (typename map_type::value_type& x : map)
{
node::destruct_node(x.second.root, this);
}
diff --git a/boost/spirit/home/x3/support/ast/variant.hpp b/boost/spirit/home/x3/support/ast/variant.hpp
index cf626e88be..52e565d1d4 100644
--- a/boost/spirit/home/x3/support/ast/variant.hpp
+++ b/boost/spirit/home/x3/support/ast/variant.hpp
@@ -7,13 +7,10 @@
#if !defined(BOOST_SPIRIT_X3_VARIANT_AUGUST_6_2011_0859AM)
#define BOOST_SPIRIT_X3_VARIANT_AUGUST_6_2011_0859AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/variant.hpp>
#include <boost/mpl/list.hpp>
#include <boost/type_traits/is_base_of.hpp>
+#include <type_traits>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace x3
@@ -126,17 +123,25 @@ namespace boost { namespace spirit { namespace x3
// tell spirit that this is an adapted variant
struct adapted_variant_tag;
- typedef boost::variant<Types...> variant_type;
- typedef mpl::list<typename detail::remove_forward<Types>::type...> types;
- typedef variant<Types...> base_type;
+ using variant_type = boost::variant<Types...>;
+ using types = mpl::list<typename detail::remove_forward<Types>::type...>;
+ using base_type = variant; // The current instantiation
+
+ template<typename T>
+ using non_self_t // used only for SFINAE checks below
+ = std::enable_if_t<!(std::is_base_of<base_type
+ ,std::remove_reference_t<T>
+ >
+ ::value)
+ >;
variant() : var() {}
- template <typename T, typename disable_if<is_base_of<base_type, T>>::type>
+ template <typename T, class = non_self_t<T>>
explicit variant(T const& rhs)
: var(rhs) {}
- template <typename T, typename disable_if<is_base_of<base_type, T>>::type>
+ template <typename T, class = non_self_t<T>>
explicit variant(T&& rhs)
: var(std::forward<T>(rhs)) {}
@@ -161,16 +166,14 @@ namespace boost { namespace spirit { namespace x3
return *this;
}
- template <typename T>
- //typename disable_if<is_base_of<base_type, T>, variant&>::type
+ template <typename T, class = non_self_t<T>>
variant& operator=(T const& rhs)
{
var = rhs;
return *this;
}
- template <typename T>
- //typename disable_if<is_base_of<base_type, T>, variant&>::type
+ template <typename T, class = non_self_t<T>>
variant& operator=(T&& rhs)
{
var = std::forward<T>(rhs);
diff --git a/boost/spirit/home/x3/support/context.hpp b/boost/spirit/home/x3/support/context.hpp
index 93bcb24070..592ce3ff76 100644
--- a/boost/spirit/home/x3/support/context.hpp
+++ b/boost/spirit/home/x3/support/context.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM)
#define BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/mpl/identity.hpp>
@@ -23,26 +19,13 @@ namespace boost { namespace spirit { namespace x3
context(T& val, Next const& next)
: val(val), next(next) {}
- template <typename ID_, typename Unused = void>
- struct get_result
- {
- typedef typename Next::template get_result<ID_>::type type;
- };
-
- template <typename Unused>
- struct get_result<mpl::identity<ID>, Unused>
- {
- typedef T& type;
- };
-
T& get(mpl::identity<ID>) const
{
return val;
}
template <typename ID_>
- typename Next::template get_result<ID_>::type
- get(ID_ id) const
+ decltype(auto) get(ID_ id) const
{
return next.get(id);
}
@@ -60,37 +43,22 @@ namespace boost { namespace spirit { namespace x3
context(T& val, unused_type)
: val(val) {}
- template <typename ID_, typename Unused = void>
- struct get_result
- {
- typedef unused_type type;
- };
-
- template <typename Unused>
- struct get_result<mpl::identity<ID>, Unused>
- {
- typedef T& type;
- };
-
T& get(mpl::identity<ID>) const
{
return val;
}
template <typename ID_>
- unused_type
- get(ID_) const
+ unused_type get(ID_) const
{
- return unused;
+ return {};
}
T& val;
};
template <typename Tag, typename Context>
- inline auto
- get(Context const& context)
- -> decltype(context.get(mpl::identity<Tag>()))
+ inline decltype(auto) get(Context const& context)
{
return context.get(mpl::identity<Tag>());
}
@@ -98,13 +66,13 @@ namespace boost { namespace spirit { namespace x3
template <typename ID, typename T, typename Next>
inline context<ID, T, Next> make_context(T& val, Next const& next)
{
- return context<ID, T, Next>(val, next);
+ return { val, next };
}
template <typename ID, typename T>
inline context<ID, T> make_context(T& val)
{
- return context<ID, T>(val);
+ return { val };
}
namespace detail
@@ -120,7 +88,7 @@ namespace boost { namespace spirit { namespace x3
inline context<ID, T, Next>
make_unique_context(T& val, Next const& next, unused_type)
{
- return context<ID, T, Next>(val, next);
+ return { val, next };
}
}
diff --git a/boost/spirit/home/x3/support/no_case.hpp b/boost/spirit/home/x3/support/no_case.hpp
new file mode 100644
index 0000000000..2ad3f709c6
--- /dev/null
+++ b/boost/spirit/home/x3/support/no_case.hpp
@@ -0,0 +1,102 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+
+ Distributed under the 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_SPIRIT_X3_SUPPORT_NO_CASE_SEPT_24_2014_1125PM)
+#define BOOST_SPIRIT_X3_SUPPORT_NO_CASE_SEPT_24_2014_1125PM
+
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/char/char_class_tags.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ struct no_case_tag {};
+
+ template <typename Encoding>
+ struct case_compare
+ {
+ template < template <typename> class basic_charset>
+ typename Encoding::char_type
+ in_set( typename Encoding::char_type const ch
+ , basic_charset<typename Encoding::char_type> const &set)
+ {
+ return set.test(ch);
+ }
+
+ int32_t operator()(
+ typename Encoding::char_type const lc
+ , typename Encoding::char_type const rc) const
+ {
+ return lc - rc;
+ }
+
+
+ template <typename CharClassTag>
+ CharClassTag get_char_class_tag(CharClassTag tag) const
+ {
+ return tag;
+ }
+ };
+
+ template <typename Encoding>
+ struct no_case_compare
+ {
+ template < template <typename> class basic_charset>
+ typename Encoding::char_type
+ in_set( typename Encoding::char_type const ch
+ , basic_charset<typename Encoding::char_type> const &set)
+ {
+ return set.test(ch)
+ || set.test(Encoding::islower(ch) ? Encoding::toupper(ch) : Encoding::tolower(ch));
+ }
+
+ int32_t operator()(
+ typename Encoding::char_type const lc
+ , typename Encoding::char_type const rc) const
+ {
+ return Encoding::islower(rc) ? Encoding::tolower(lc) - rc : Encoding::toupper(lc) - rc;
+ }
+
+ template <typename CharClassTag>
+ CharClassTag get_char_class_tag(CharClassTag tag) const
+ {
+ return tag;
+ }
+
+ alpha_tag get_char_class_tag(lower_tag ) const
+ {
+ return {};
+ }
+
+ alpha_tag get_char_class_tag(upper_tag ) const
+ {
+ return {};
+ }
+
+ };
+
+ template <typename Encoding>
+ case_compare<Encoding> get_case_compare_impl(unused_type const&)
+ {
+ return {};
+ }
+
+ template <typename Encoding>
+ no_case_compare<Encoding> get_case_compare_impl(no_case_tag const&)
+ {
+ return {};
+ }
+
+ template <typename Encoding, typename Context>
+ inline decltype(auto) get_case_compare(Context const& context)
+ {
+ return get_case_compare_impl<Encoding>(x3::get<no_case_tag>(context));
+ }
+ auto const no_case_compare_ = no_case_tag{};
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp b/boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp
index 73770c87d0..4ebd66f182 100644
--- a/boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp
+++ b/boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp
@@ -11,10 +11,6 @@
#if !defined(BOOST_SPIRIT_X3_DETAIL_EXTRACT_INT_APRIL_17_2006_0816AM)
#define BOOST_SPIRIT_X3_DETAIL_EXTRACT_INT_APRIL_17_2006_0816AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_type.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
diff --git a/boost/spirit/home/x3/support/numeric_utils/extract_int.hpp b/boost/spirit/home/x3/support/numeric_utils/extract_int.hpp
index aa80cdd6ea..621275f4c8 100644
--- a/boost/spirit/home/x3/support/numeric_utils/extract_int.hpp
+++ b/boost/spirit/home/x3/support/numeric_utils/extract_int.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_EXTRACT_INT_APRIL_17_2006_0830AM)
#define BOOST_SPIRIT_X3_EXTRACT_INT_APRIL_17_2006_0830AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp>
#include <boost/assert.hpp>
diff --git a/boost/spirit/home/x3/support/numeric_utils/extract_real.hpp b/boost/spirit/home/x3/support/numeric_utils/extract_real.hpp
index fb30f02306..ea1f0df949 100644
--- a/boost/spirit/home/x3/support/numeric_utils/extract_real.hpp
+++ b/boost/spirit/home/x3/support/numeric_utils/extract_real.hpp
@@ -9,10 +9,6 @@
#if !defined(SPIRIT_EXTRACT_REAL_APRIL_18_2006_0901AM)
#define SPIRIT_EXTRACT_REAL_APRIL_18_2006_0901AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <cmath>
#include <boost/limits.hpp>
#include <boost/type_traits/is_same.hpp>
diff --git a/boost/spirit/home/x3/support/numeric_utils/pow10.hpp b/boost/spirit/home/x3/support/numeric_utils/pow10.hpp
index f51d29fba8..1ff3a077a1 100644
--- a/boost/spirit/home/x3/support/numeric_utils/pow10.hpp
+++ b/boost/spirit/home/x3/support/numeric_utils/pow10.hpp
@@ -9,10 +9,6 @@
#if !defined(BOOST_SPIRIT_X3_POW10_DECEMBER_26_2008_1118AM)
#define BOOST_SPIRIT_X3_POW10_DECEMBER_26_2008_1118AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/limits.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
diff --git a/boost/spirit/home/x3/support/numeric_utils/sign.hpp b/boost/spirit/home/x3/support/numeric_utils/sign.hpp
index fe2feceeed..2ee4142de6 100644
--- a/boost/spirit/home/x3/support/numeric_utils/sign.hpp
+++ b/boost/spirit/home/x3/support/numeric_utils/sign.hpp
@@ -9,10 +9,6 @@
#if !defined(SPIRIT_SIGN_MAR_11_2009_0734PM)
#define SPIRIT_SIGN_MAR_11_2009_0734PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/math/special_functions/sign.hpp>
diff --git a/boost/spirit/home/x3/support/subcontext.hpp b/boost/spirit/home/x3/support/subcontext.hpp
index 7614fcbcae..d4c60d084b 100644
--- a/boost/spirit/home/x3/support/subcontext.hpp
+++ b/boost/spirit/home/x3/support/subcontext.hpp
@@ -9,10 +9,6 @@
#if !defined(BOOST_SPIRIT_X3_SUBCONTEXT_APR_15_2013_0840AM)
#define BOOST_SPIRIT_X3_SUBCONTEXT_APR_15_2013_0840AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/fusion/support/pair.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
@@ -29,12 +25,6 @@ namespace boost { namespace spirit { namespace x3
subcontext(Context const& /*context*/)
{}
- template <typename ID_, typename Unused = void>
- struct get_result
- {
- typedef unused_type type;
- };
-
template <typename ID_>
unused_type
get(ID_) const
diff --git a/boost/spirit/home/x3/support/traits/attribute_category.hpp b/boost/spirit/home/x3/support/traits/attribute_category.hpp
index a003327de2..53e806c613 100644
--- a/boost/spirit/home/x3/support/traits/attribute_category.hpp
+++ b/boost/spirit/home/x3/support/traits/attribute_category.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_CATEGORY_JAN_4_2012_1150AM)
#define BOOST_SPIRIT_X3_ATTRIBUTE_CATEGORY_JAN_4_2012_1150AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/mpl/identity.hpp>
#include <boost/mpl/logical.hpp>
#include <boost/mpl/eval_if.hpp>
diff --git a/boost/spirit/home/x3/support/traits/attribute_of.hpp b/boost/spirit/home/x3/support/traits/attribute_of.hpp
index 71f70b0273..93ee79b57b 100644
--- a/boost/spirit/home/x3/support/traits/attribute_of.hpp
+++ b/boost/spirit/home/x3/support/traits/attribute_of.hpp
@@ -9,10 +9,6 @@
#if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_OF_JAN_7_2012_0914AM)
#define BOOST_SPIRIT_X3_ATTRIBUTE_OF_JAN_7_2012_0914AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/utility/enable_if.hpp>
diff --git a/boost/spirit/home/x3/support/traits/attribute_type.hpp b/boost/spirit/home/x3/support/traits/attribute_type.hpp
index 55e788b41c..f1b8d871a9 100644
--- a/boost/spirit/home/x3/support/traits/attribute_type.hpp
+++ b/boost/spirit/home/x3/support/traits/attribute_type.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_TYPE_JAN_5_2012_0358PM)
#define BOOST_SPIRIT_X3_ATTRIBUTE_TYPE_JAN_5_2012_0358PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
diff --git a/boost/spirit/home/x3/support/traits/container_traits.hpp b/boost/spirit/home/x3/support/traits/container_traits.hpp
index c382b7bfaa..ed9213b68c 100644
--- a/boost/spirit/home/x3/support/traits/container_traits.hpp
+++ b/boost/spirit/home/x3/support/traits/container_traits.hpp
@@ -9,10 +9,6 @@
#if !defined(BOOST_SPIRIT_X3_CONTAINER_FEBRUARY_06_2007_1001AM)
#define BOOST_SPIRIT_X3_CONTAINER_FEBRUARY_06_2007_1001AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/fusion/support/category_of.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/detail/iterator.hpp>
@@ -20,8 +16,12 @@
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
+
#include <vector>
+#include <map>
#include <string>
+#include <iterator>
+#include <algorithm>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
@@ -112,10 +112,22 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename Container, typename Enable = void>
struct push_back_container
{
+ template <typename Key, typename Value, typename Compare, typename Allocator, typename T>
+ static void push_back(std::map<Key, Value, Compare, Allocator>& c, T&& val)
+ {
+ c.insert(std::move(val));
+ }
+
+ template <typename Container_, typename T>
+ static void push_back(Container_& c, T&& val)
+ {
+ c.push_back(std::move(val));
+ }
+
template <typename T>
static bool call(Container& c, T&& val)
{
- c.insert(c.end(), std::move(val));
+ push_back(c, std::move(val));
return true;
}
};
@@ -154,17 +166,23 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename Container_>
static void reserve(Container_& c, std::size_t size) {}
- template <typename T>
- static void reserve(std::vector<T>& c, std::size_t size)
+ template <typename T, typename Allocator>
+ static void reserve(std::vector<T, Allocator>& c, std::size_t size)
{
c.reserve(size);
}
+
+ template <typename Container_, typename Iterator>
+ static void insert(Container_& c, Iterator first, Iterator last)
+ {
+ std::copy(first, last, std::inserter(c, c.end()));
+ }
template <typename Iterator>
static bool call(Container& c, Iterator first, Iterator last)
{
reserve(c, c.size() + std::distance(first, last));
- c.insert(c.end(), first, last);
+ insert(c, first, last);
return true;
}
};
diff --git a/boost/spirit/home/x3/support/traits/handles_container.hpp b/boost/spirit/home/x3/support/traits/handles_container.hpp
index 3fe05aef87..ad0d1f19ea 100644
--- a/boost/spirit/home/x3/support/traits/handles_container.hpp
+++ b/boost/spirit/home/x3/support/traits/handles_container.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_HANDLES_CONTAINER_DEC_18_2010_0920AM)
#define BOOST_SPIRIT_X3_HANDLES_CONTAINER_DEC_18_2010_0920AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
diff --git a/boost/spirit/home/x3/support/traits/has_attribute.hpp b/boost/spirit/home/x3/support/traits/has_attribute.hpp
index c8b1f8a347..cf4ab00801 100644
--- a/boost/spirit/home/x3/support/traits/has_attribute.hpp
+++ b/boost/spirit/home/x3/support/traits/has_attribute.hpp
@@ -9,10 +9,6 @@
#if !defined(BOOST_SPIRIT_X3_HAS_ATTRIBUTE_JUN_6_2012_1714PM)
#define BOOST_SPIRIT_X3_HAS_ATTRIBUTE_JUN_6_2012_1714PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
#include <boost/mpl/bool.hpp>
diff --git a/boost/spirit/home/x3/support/traits/is_parser.hpp b/boost/spirit/home/x3/support/traits/is_parser.hpp
index cfbe8f74b4..a65d984584 100644
--- a/boost/spirit/home/x3/support/traits/is_parser.hpp
+++ b/boost/spirit/home/x3/support/traits/is_parser.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_IS_PARSER_MAY_20_2013_0235PM)
#define BOOST_SPIRIT_X3_IS_PARSER_MAY_20_2013_0235PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/mpl/bool.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
diff --git a/boost/spirit/home/x3/support/traits/is_substitute.hpp b/boost/spirit/home/x3/support/traits/is_substitute.hpp
index 9e023371ce..ef1c472c7f 100644
--- a/boost/spirit/home/x3/support/traits/is_substitute.hpp
+++ b/boost/spirit/home/x3/support/traits/is_substitute.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_IS_SUBSTITUTE_JAN_9_2012_1049PM)
#define BOOST_SPIRIT_X3_IS_SUBSTITUTE_JAN_9_2012_1049PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/map.hpp>
diff --git a/boost/spirit/home/x3/support/traits/is_variant.hpp b/boost/spirit/home/x3/support/traits/is_variant.hpp
index 829a673c3f..a936044a81 100644
--- a/boost/spirit/home/x3/support/traits/is_variant.hpp
+++ b/boost/spirit/home/x3/support/traits/is_variant.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_IS_VARIANT_JAN_10_2012_0823AM)
#define BOOST_SPIRIT_X3_IS_VARIANT_JAN_10_2012_0823AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/variant.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/bool.hpp>
diff --git a/boost/spirit/home/x3/support/traits/make_attribute.hpp b/boost/spirit/home/x3/support/traits/make_attribute.hpp
index cf3baeedaf..9465228c1d 100644
--- a/boost/spirit/home/x3/support/traits/make_attribute.hpp
+++ b/boost/spirit/home/x3/support/traits/make_attribute.hpp
@@ -9,10 +9,6 @@
#if !defined(BOOST_SPIRIT_X3_MAKE_ATTRIBUTE_JAN_8_2012_0721PM)
#define BOOST_SPIRIT_X3_MAKE_ATTRIBUTE_JAN_8_2012_0721PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/mpl/if.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/add_reference.hpp>
diff --git a/boost/spirit/home/x3/support/traits/move_to.hpp b/boost/spirit/home/x3/support/traits/move_to.hpp
index ecd7c6f202..fd3d59d7e2 100644
--- a/boost/spirit/home/x3/support/traits/move_to.hpp
+++ b/boost/spirit/home/x3/support/traits/move_to.hpp
@@ -9,10 +9,6 @@
#if !defined(BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM)
#define BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
#include <boost/spirit/home/x3/support/traits/tuple_traits.hpp>
#include <boost/spirit/home/x3/support/traits/variant_has_substitute.hpp>
@@ -181,14 +177,14 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename T>
inline void move_to(T& src, T& dest)
{
- if (&src != &dest)
+ if (boost::addressof(src) != boost::addressof(dest))
dest = std::move(src);
}
template <typename T>
inline void move_to(T const& src, T& dest)
{
- if (&src != &dest)
+ if (boost::addressof(src) != boost::addressof(dest))
dest = std::move(src);
}
diff --git a/boost/spirit/home/x3/support/traits/numeric_traits.hpp b/boost/spirit/home/x3/support/traits/numeric_traits.hpp
index 3cdbdaec63..9f455cc627 100644
--- a/boost/spirit/home/x3/support/traits/numeric_traits.hpp
+++ b/boost/spirit/home/x3/support/traits/numeric_traits.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_NUMERIC_TRAITS_JAN_07_2011_0722AM)
#define BOOST_SPIRIT_X3_NUMERIC_TRAITS_JAN_07_2011_0722AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/config.hpp>
#include <boost/integer_traits.hpp>
#include <boost/mpl/bool.hpp>
diff --git a/boost/spirit/home/x3/support/traits/optional_traits.hpp b/boost/spirit/home/x3/support/traits/optional_traits.hpp
index 65568b0265..3c5e853797 100644
--- a/boost/spirit/home/x3/support/traits/optional_traits.hpp
+++ b/boost/spirit/home/x3/support/traits/optional_traits.hpp
@@ -9,10 +9,6 @@
#if !defined(BOOST_SPIRIT_X3_OPTIONAL_TRAITS_FEBRUARY_06_2007_1001AM)
#define BOOST_SPIRIT_X3_OPTIONAL_TRAITS_FEBRUARY_06_2007_1001AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/optional/optional.hpp>
#include <boost/mpl/identity.hpp>
diff --git a/boost/spirit/home/x3/support/traits/print_attribute.hpp b/boost/spirit/home/x3/support/traits/print_attribute.hpp
index 47bffce1a1..cc76e02d30 100644
--- a/boost/spirit/home/x3/support/traits/print_attribute.hpp
+++ b/boost/spirit/home/x3/support/traits/print_attribute.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM)
#define BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/variant.hpp>
#include <boost/optional/optional.hpp>
#include <boost/fusion/include/is_sequence.hpp>
diff --git a/boost/spirit/home/x3/support/traits/print_token.hpp b/boost/spirit/home/x3/support/traits/print_token.hpp
index f1429f4776..e8f4dea325 100644
--- a/boost/spirit/home/x3/support/traits/print_token.hpp
+++ b/boost/spirit/home/x3/support/traits/print_token.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_PRINT_TOKEN_JANUARY_20_2013_0814AM)
#define BOOST_SPIRIT_X3_PRINT_TOKEN_JANUARY_20_2013_0814AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/type_traits/is_convertible.hpp>
diff --git a/boost/spirit/home/x3/support/traits/string_traits.hpp b/boost/spirit/home/x3/support/traits/string_traits.hpp
index 46ee356cdc..44c8d144a8 100644
--- a/boost/spirit/home/x3/support/traits/string_traits.hpp
+++ b/boost/spirit/home/x3/support/traits/string_traits.hpp
@@ -9,10 +9,6 @@
#if !defined(BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM)
#define BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <string>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
diff --git a/boost/spirit/home/x3/support/traits/transform_attribute.hpp b/boost/spirit/home/x3/support/traits/transform_attribute.hpp
index 24268520d7..98af3099e6 100644
--- a/boost/spirit/home/x3/support/traits/transform_attribute.hpp
+++ b/boost/spirit/home/x3/support/traits/transform_attribute.hpp
@@ -9,10 +9,6 @@
#if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_TRANSFORM_JAN_8_2012_0721PM)
#define BOOST_SPIRIT_X3_ATTRIBUTE_TRANSFORM_JAN_8_2012_0721PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
diff --git a/boost/spirit/home/x3/support/traits/tuple_traits.hpp b/boost/spirit/home/x3/support/traits/tuple_traits.hpp
index 17bfd4e1cb..46e4246b74 100644
--- a/boost/spirit/home/x3/support/traits/tuple_traits.hpp
+++ b/boost/spirit/home/x3/support/traits/tuple_traits.hpp
@@ -7,10 +7,6 @@
#if !defined(BOOST_SPIRIT_X3_TUPLE_TRAITS_JANUARY_2012_1132PM)
#define BOOST_SPIRIT_X3_TUPLE_TRAITS_JANUARY_2012_1132PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/mpl/bool.hpp>
diff --git a/boost/spirit/home/x3/support/traits/value_traits.hpp b/boost/spirit/home/x3/support/traits/value_traits.hpp
index 5f004c957c..d28af74d3f 100644
--- a/boost/spirit/home/x3/support/traits/value_traits.hpp
+++ b/boost/spirit/home/x3/support/traits/value_traits.hpp
@@ -9,10 +9,6 @@
#if !defined(BOOST_SPIRIT_X3_VALUE_TRAITS_MAY_07_2013_0203PM)
#define BOOST_SPIRIT_X3_VALUE_TRAITS_MAY_07_2013_0203PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/utility/value_init.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
diff --git a/boost/spirit/home/x3/support/traits/variant_find_substitute.hpp b/boost/spirit/home/x3/support/traits/variant_find_substitute.hpp
index 4de7b7d5e3..d258d54dc5 100644
--- a/boost/spirit/home/x3/support/traits/variant_find_substitute.hpp
+++ b/boost/spirit/home/x3/support/traits/variant_find_substitute.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_VARIANT_FIND_SUBSTITUTE_APR_18_2014_930AM)
#define BOOST_SPIRIT_X3_VARIANT_FIND_SUBSTITUTE_APR_18_2014_930AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
diff --git a/boost/spirit/home/x3/support/traits/variant_has_substitute.hpp b/boost/spirit/home/x3/support/traits/variant_has_substitute.hpp
index d0dfb49b8d..2f8b42a834 100644
--- a/boost/spirit/home/x3/support/traits/variant_has_substitute.hpp
+++ b/boost/spirit/home/x3/support/traits/variant_has_substitute.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_VARIANT_HAS_SUBSTITUTE_APR_18_2014_925AM)
#define BOOST_SPIRIT_X3_VARIANT_HAS_SUBSTITUTE_APR_18_2014_925AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
diff --git a/boost/spirit/home/x3/support/unused.hpp b/boost/spirit/home/x3/support/unused.hpp
index cf42d13098..f7857e0dbd 100644
--- a/boost/spirit/home/x3/support/unused.hpp
+++ b/boost/spirit/home/x3/support/unused.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_UNUSED_APRIL_16_2006_0616PM)
#define BOOST_SPIRIT_X3_UNUSED_APRIL_16_2006_0616PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <ostream>
#include <istream>
#include <boost/mpl/identity.hpp>
@@ -64,16 +60,13 @@ namespace boost { namespace spirit { namespace x3
// unused_type can also masquerade as an empty context (see context.hpp)
template <typename ID>
- struct get_result : mpl::identity<unused_type> {};
-
- template <typename ID>
unused_type get(ID) const
{
- return unused_type();
+ return {};
}
};
- unused_type const unused = unused_type();
+ auto const unused = unused_type{};
inline std::ostream& operator<<(std::ostream& out, unused_type const&)
{
diff --git a/boost/spirit/home/x3/support/utility/annotate_on_success.hpp b/boost/spirit/home/x3/support/utility/annotate_on_success.hpp
new file mode 100644
index 0000000000..8129675559
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/annotate_on_success.hpp
@@ -0,0 +1,51 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 Joel de Guzman
+
+ Distributed under the 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_SPIRIT_X3__ANNOTATE_ON_SUCCESS_HPP)
+#define BOOST_SPIRIT_X3__ANNOTATE_ON_SUCCESS_HPP
+
+#include <boost/spirit/home/x3/support/ast/variant.hpp>
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/support/utility/error_reporting.hpp>
+#include <boost/spirit/home/x3/support/utility/lambda_visitor.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // The on_success handler tags the AST with the iterator position
+ // for error handling.
+ //
+ // The on_success handler also ties the AST to a vector of iterator
+ // positions for the purpose of subsequent semantic error handling
+ // when the program is being compiled. See x3::position_cache in
+ // x3/support/ast.
+ //
+ // We'll ask the X3's error_handler utility to do these.
+ ///////////////////////////////////////////////////////////////////////////
+
+ struct annotate_on_success
+ {
+ template <typename Iterator, typename Context, typename... Types>
+ inline void on_success(Iterator const& first, Iterator const& last
+ , variant<Types...>& ast, Context const& context)
+ {
+ ast.apply_visitor(x3::make_lambda_visitor<void>([&](auto& node)
+ {
+ this->on_success(first, last, node, context);
+ }));
+ }
+
+ template <typename T, typename Iterator, typename Context>
+ inline void on_success(Iterator const& first, Iterator const& last
+ , T& ast, Context const& context)
+ {
+ auto& error_handler = get<error_handler_tag>(context).get();
+ error_handler.tag(ast, first, last);
+ }
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/error_reporting.hpp b/boost/spirit/home/x3/support/utility/error_reporting.hpp
index 9e65f2149b..51ac403728 100644
--- a/boost/spirit/home/x3/support/utility/error_reporting.hpp
+++ b/boost/spirit/home/x3/support/utility/error_reporting.hpp
@@ -7,7 +7,11 @@
#if !defined(BOOST_SPIRIT_X3_ERROR_REPORTING_MAY_19_2014_00405PM)
#define BOOST_SPIRIT_X3_ERROR_REPORTING_MAY_19_2014_00405PM
+#ifndef BOOST_SPIRIT_X3_NO_FILESYSTEM
#include <boost/filesystem/path.hpp>
+#endif
+
+#include <boost/locale/encoding_utf.hpp>
#include <boost/spirit/home/x3/support/ast/position_tagged.hpp>
#include <ostream>
@@ -15,6 +19,9 @@
namespace boost { namespace spirit { namespace x3
{
+ // tag used to get our error handler from the context
+ struct error_handler_tag;
+
template <typename Iterator>
class error_handler
{
@@ -37,11 +44,7 @@ namespace boost { namespace spirit { namespace x3
void operator()(position_tagged pos, std::string const& message) const
{
auto where = pos_cache.position_of(pos);
- (*this)(
- where.begin()
- , where.end()
- , message
- );
+ (*this)(where.begin(), where.end(), message);
}
template <typename AST>
@@ -49,20 +52,16 @@ namespace boost { namespace spirit { namespace x3
{
return pos_cache.annotate(ast, first, last);
}
-//
-// void operator()(
-// Iterator first
-// , Iterator last
-// , Iterator err_op
-// , Iterator err_first
-// , Iterator err_last
-// , std::string const& error_message
-// ) const;
+
+ boost::iterator_range<Iterator> position_of(position_tagged pos) const
+ {
+ return pos_cache.position_of(pos);
+ }
private:
void print_file_line(std::size_t line) const;
- void print_line(Iterator& line_start, Iterator last) const;
+ void print_line(Iterator line_start, Iterator last) const;
void print_indicator(Iterator& line_start, Iterator last, char ind) const;
void skip_whitespace(Iterator& err_pos, Iterator last) const;
void skip_non_whitespace(Iterator& err_pos, Iterator last) const;
@@ -78,29 +77,39 @@ namespace boost { namespace spirit { namespace x3
template <typename Iterator>
void error_handler<Iterator>::print_file_line(std::size_t line) const
{
- namespace fs = boost::filesystem;
-
if (file != "")
+ {
+#ifdef BOOST_SPIRIT_X3_NO_FILESYSTEM
+ err_out << "In file " << file << ", ";
+#else
+ namespace fs = boost::filesystem;
err_out << "In file " << fs::path(file).generic_string() << ", ";
+#endif
+ }
else
+ {
err_out << "In ";
+ }
err_out << "line " << line << ':' << std::endl;
}
template <typename Iterator>
- void error_handler<Iterator>::print_line(Iterator& start, Iterator last) const
+ void error_handler<Iterator>::print_line(Iterator start, Iterator last) const
{
- for (; start != last; ++start)
+ auto end = start;
+ while (end != last)
{
- auto c = *start;
+ auto c = *end;
if (c == '\r' || c == '\n')
break;
else
- err_out << c;
+ ++end;
}
- err_out << std::endl;
- }
+ typedef typename std::iterator_traits<Iterator>::value_type char_type;
+ std::basic_string<char_type> line{start, end};
+ err_out << locale::conv::utf_to_utf<char>(line) << std::endl;
+ }
template <typename Iterator>
void error_handler<Iterator>::print_indicator(Iterator& start, Iterator last, char ind) const
@@ -159,8 +168,25 @@ namespace boost { namespace spirit { namespace x3
template <typename Iterator>
std::size_t error_handler<Iterator>::position(Iterator i) const
{
- // $$$ asumes iterator is similar to line_pos_iterator $$$
- return i.position();
+ std::size_t line { 1 };
+ typename std::iterator_traits<Iterator>::value_type prev { 0 };
+
+ for (Iterator pos = pos_cache.first(); pos != i; ++pos) {
+ auto c = *pos;
+ switch (c) {
+ case '\n':
+ if (prev != '\r') ++line;
+ break;
+ case '\r':
+ if (prev != '\n') ++line;
+ break;
+ default:
+ break;
+ }
+ prev = c;
+ }
+
+ return line;
}
template <typename Iterator>
@@ -179,8 +205,7 @@ namespace boost { namespace spirit { namespace x3
Iterator start = get_line_start(first, err_pos);
if (start != first)
++start;
- Iterator i = start;
- print_line(i, last);
+ print_line(start, last);
print_indicator(start, err_pos, '_');
err_out << "^_" << std::endl;
}
@@ -201,40 +226,11 @@ namespace boost { namespace spirit { namespace x3
Iterator start = get_line_start(first, err_first);
if (start != first)
++start;
- Iterator i = start;
- print_line(i, last);
+ print_line(start, last);
print_indicator(start, err_first, ' ');
print_indicator(start, err_last, '~');
err_out << " <<-- Here" << std::endl;
}
-//
-// template <typename Iterator>
-// void error_handler<Iterator>::operator()(
-// Iterator first
-// , Iterator last
-// , Iterator err_op
-// , Iterator err_first
-// , Iterator err_last
-// , std::string const& error_message
-// ) const
-// {
-// // make sure err_pos does not point to white space
-// skip_whitespace(err_first, last);
-//
-// print_file_line(position(err_pos));
-// err_out << error_message << std::endl;
-//
-// Iterator start = get_line_start(first, err_first);
-// if (start != first)
-// ++start;
-// Iterator i = start;
-// print_line(i, last);
-// print_indicator(start, err_first, ' ');
-// print_indicator(start, err_op, '~');
-// err_out << '^';
-// print_indicator(++start, err_last, '~');
-// err_out << " <<-- Here" << std::endl;
-// }
}}}
diff --git a/boost/spirit/home/x3/support/utility/integer_sequence.hpp b/boost/spirit/home/x3/support/utility/integer_sequence.hpp
deleted file mode 100644
index 1f0bace72b..0000000000
--- a/boost/spirit/home/x3/support/utility/integer_sequence.hpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*//////////////////////////////////////////////////////////////////////////////
- Copyright (c) 2014 Jamboree
-
- Distributed under the 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_SPIRIT_X3_INTEGER_SEQUENCE_HPP_INCLUDED
-#define BOOST_SPIRIT_X3_INTEGER_SEQUENCE_HPP_INCLUDED
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <cstddef>
-#include <boost/type_traits/integral_constant.hpp>
-
-// This is a standard (c++1y) compatible integer_sequence implementation,
-// it's needed for now, and it could be replaced with std::integer_sequence
-// once the new standard is available everywhere.
-
-namespace boost { namespace spirit { namespace x3
-{
- template <typename T, T... Ns>
- struct integer_sequence
- {
- typedef T value_type;
-
- static constexpr std::size_t size() noexcept
- {
- return sizeof...(Ns);
- }
- };
-}}}
-
-namespace boost { namespace spirit { namespace x3 { namespace detail
-{
- template <typename T, typename S1, typename S2, T N>
- struct accum_integer_sequence;
-
- template <typename T, T... N1, T... N2, T N>
- struct accum_integer_sequence<T, integer_sequence<T, N1...>, integer_sequence<T, N2...>, N>
- {
- typedef integer_sequence<T, N1..., (N + N2)...> type;
- };
-
- template <typename N>
- struct make_integer_sequence_impl
- {
- typedef typename N::value_type T;
- static T const n = N::value;
- static T const m = n / 2;
- typedef typename
- make_integer_sequence_impl<integral_constant<T, m>>::type
- part1;
- typedef typename
- make_integer_sequence_impl<integral_constant<T, n - m>>::type
- part2;
- typedef typename
- accum_integer_sequence<T, part1, part2, m>::type
- type;
- };
-
- template <typename T>
- struct make_integer_sequence_impl<integral_constant<T, 0>>
- {
- typedef integer_sequence<T> type;
- };
-
- template <typename T>
- struct make_integer_sequence_impl<integral_constant<T, 1>>
- {
- typedef integer_sequence<T, 0> type;
- };
-}}}}
-
-namespace boost { namespace spirit { namespace x3
-{
- template <std::size_t... Ns>
- using index_sequence = integer_sequence<std::size_t, Ns...>;
-
- template <typename T, T N>
- using make_integer_sequence = typename detail::make_integer_sequence_impl<
- integral_constant<T, N>>::type;
-
- template <std::size_t N>
- using make_index_sequence = make_integer_sequence<std::size_t, N>;
-
- template <typename... T>
- using index_sequence_for = make_index_sequence<sizeof...(T)>;
-}}}
-
-
-#endif
-
diff --git a/boost/spirit/home/x3/support/utility/is_callable.hpp b/boost/spirit/home/x3/support/utility/is_callable.hpp
index 17f86822b8..5e116de410 100644
--- a/boost/spirit/home/x3/support/utility/is_callable.hpp
+++ b/boost/spirit/home/x3/support/utility/is_callable.hpp
@@ -7,25 +7,17 @@
#ifndef BOOST_SPIRIT_X3_IS_CALLABLE_HPP_INCLUDED
#define BOOST_SPIRIT_X3_IS_CALLABLE_HPP_INCLUDED
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/utility/result_of.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
-
namespace boost { namespace spirit { namespace x3 { namespace detail
{
template <typename Sig, typename Enable = void>
- struct is_callable_impl
- : mpl::false_
- {};
+ struct is_callable_impl : mpl::false_ {};
template <typename F, typename... A>
struct is_callable_impl<F(A...), typename disable_if_substitution_failure<
- typename result_of<F(A...)>::type>::type>
+ decltype(std::declval<F>()(std::declval<A>()...))>::type>
: mpl::true_
{};
}}}}
@@ -36,9 +28,7 @@ namespace boost { namespace spirit { namespace x3
struct is_callable;
template <typename F, typename... A>
- struct is_callable<F(A...)>
- : detail::is_callable_impl<F(A...)>
- {};
+ struct is_callable<F(A...)> : detail::is_callable_impl<F(A...)> {};
}}}
diff --git a/boost/spirit/home/x3/support/utility/sfinae.hpp b/boost/spirit/home/x3/support/utility/sfinae.hpp
index 6cefa95961..532ae5c54d 100644
--- a/boost/spirit/home/x3/support/utility/sfinae.hpp
+++ b/boost/spirit/home/x3/support/utility/sfinae.hpp
@@ -8,10 +8,6 @@
#if !defined(BOOST_SPIRIT_X3_SFINAE_MAY_20_2013_0840AM)
#define BOOST_SPIRIT_X3_SFINAE_MAY_20_2013_0840AM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
namespace boost { namespace spirit { namespace x3
{
template <typename Expr, typename T = void>
@@ -19,6 +15,7 @@ namespace boost { namespace spirit { namespace x3
{
typedef T type;
};
+
template <typename Expr, typename T>
struct lazy_disable_if_substitution_failure
{
diff --git a/boost/spirit/home/x3/support/utility/testing.hpp b/boost/spirit/home/x3/support/utility/testing.hpp
index fced46bef8..6d38ccfed7 100644
--- a/boost/spirit/home/x3/support/utility/testing.hpp
+++ b/boost/spirit/home/x3/support/utility/testing.hpp
@@ -1,68 +1,268 @@
/*=============================================================================
- Copyright (c) 2014 Joel de Guzman
+ Copyright (c) 2001-2015 Joel de Guzman
Distributed under the 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_SPIRIT_X3_TESTING_JUNE_05_2014_00422PM)
-#define BOOST_SPIRIT_X3_TESTING_JUNE_05_2014_00422PM
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_X3_TEST_UTILITIES)
+#define BOOST_SPIRIT_X3_TEST_UTILITIES
+
+#include <boost/regex.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
namespace boost { namespace spirit { namespace x3 { namespace testing
{
+ namespace fs = boost::filesystem;
+
////////////////////////////////////////////////////////////////////////////
+ // compare
//
- // Test utility
- //
- // The test function accepts a file loaded in memory. The 'test_file'
- // range param points to the data contained in the file. This file
- // contains two parts.
- //
- // 1) The source input for testing
- // 2) The expected result.
- //
- // The first part of the file is sent to the generator function
- // 'gen' which returns a string. This generated string is then compared
- // to the contents of the second (expected result) part.
- //
- // The second part is demarcated by the string parameter 'demarcation'
- // which defaults to "<**expected**>". The expected template may include
- // embedded regular expressions marked-up within re_prefix and re_suffix
- // parameter tags. For example, given the default RE markup ("<%" and
- // "%>"), this template:
- //
- // <%[0-9]+%>
- //
- // will match any integer in the source input being tested. The function
- // will return the first non-matching position. The flag full_match
- // indicates a full match. It is possible for returned pos to be
- // at the end of in (in.end()) while still returning full_match ==
- // false. In that case, we have a partial match.
- //
- // Here's an example of a test file:
- //
- // Hello World, I am Joel. This is a test.
- //
- // <**expected**>
- // Hello World, I am <%[a-zA-Z]+%>. This is a test.
- //
+ // Compares the contents of in with the template tem. The template
+ // may include embedded regular expressions marked up within re_prefix
+ // and re_suffix tags. For example, given the default RE markup, this
+ // template <%[0-9]+%> will match any integer in in. The function
+ // will return the first non-matching position. The flag full_match
+ // indicates a full match. It is possible for returned pos to be
+ // at the end of in (in.end()) while still returning full_match ==
+ // false. In that case, we have a partial match.
////////////////////////////////////////////////////////////////////////////
template <typename Iterator>
- struct test_result
+ struct compare_result
{
+ compare_result(
+ Iterator pos
+ , bool full_match
+ ) : pos(pos), full_match(full_match) {}
+
Iterator pos;
bool full_match;
};
- template <typename Range, typename F>
- test_result<typename Range::const_iterator>
- test(
- Range test_file
- , F gen
- , char const* demarcation = "<**expected**>"
+ template <typename Range>
+ compare_result<typename Range::const_iterator>
+ compare(
+ Range const& in
+ , Range const& tem
+ , char const* re_prefix = "<%"
+ , char const* re_suffix = "%>"
+ );
+
+ ////////////////////////////////////////////////////////////////////////////
+ // compare
+ //
+ // 1) Call f, given the contents of input_path loaded in a string.
+ // The result of calling f is the output string.
+ // 2) Compare the result of calling f with expected template
+ // file (expect_path) using the low-level compare utility
+ // abive
+ ////////////////////////////////////////////////////////////////////////////
+ template <typename F>
+ bool compare(
+ fs::path input_path, fs::path expect_path
+ , F f
, char const* re_prefix = "<%"
, char const* re_suffix = "%>"
- );
+ );
+
+ ////////////////////////////////////////////////////////////////////////////
+ // for_each_file
+ //
+ // For each *.input and *.expect file in a given directory,
+ // call the function f, passing in the *.input and *.expect paths.
+ ////////////////////////////////////////////////////////////////////////////
+ template <typename F>
+ int for_each_file(fs::path p, F f);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // load_file
+ //
+ // Load file into a string.
+ ////////////////////////////////////////////////////////////////////////////
+ std::string load(fs::path p);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Implementation
+ ////////////////////////////////////////////////////////////////////////////
+
+ template <typename Iterator>
+ inline bool is_regex(
+ Iterator& first
+ , Iterator last
+ , std::string& re
+ , char const* re_prefix
+ , char const* re_suffix
+ )
+ {
+ boost::regex e(re_prefix + std::string("(.*?)") + re_suffix);
+ boost::match_results<Iterator> what;
+ if (boost::regex_search(
+ first, last, what, e
+ , boost::match_default | boost::match_continuous))
+ {
+ re = what[1].str();
+ first = what[0].second;
+ return true;
+ }
+ return false;
+ }
+
+ template <typename Range>
+ inline compare_result<typename Range::const_iterator>
+ compare(
+ Range const& in
+ , Range const& tem
+ , char const* re_prefix
+ , char const* re_suffix
+ )
+ {
+ typedef typename Range::const_iterator iter_t;
+ typedef compare_result<iter_t> compare_result_t;
+
+ iter_t in_first = in.begin();
+ iter_t in_last = in.end();
+ iter_t tem_first = tem.begin();
+ iter_t tem_last = tem.end();
+ std::string re;
+
+ while (in_first != in_last && tem_first != tem_last)
+ {
+ if (is_regex(tem_first, tem_last, re, re_prefix, re_suffix))
+ {
+ boost::match_results<iter_t> what;
+ boost::regex e(re);
+ if (!boost::regex_search(
+ in_first, in_last, what, e
+ , boost::match_default | boost::match_continuous))
+ {
+ // RE mismatch: exit now.
+ return compare_result_t(in_first, false);
+ }
+ else
+ {
+ // RE match: gobble the matching string.
+ in_first = what[0].second;
+ }
+ }
+ else
+ {
+ // Char by char comparison. Exit if we have a mismatch.
+ if (*in_first++ != *tem_first++)
+ return compare_result_t(in_first, false);
+ }
+ }
+
+ // Ignore trailing spaces in template
+ bool has_trailing_nonspaces = false;
+ while (tem_first != tem_last)
+ {
+ if (!std::isspace(*tem_first++))
+ {
+ has_trailing_nonspaces = true;
+ break;
+ }
+ }
+ while (in_first != in_last)
+ {
+ if (!std::isspace(*in_first++))
+ {
+ has_trailing_nonspaces = true;
+ break;
+ }
+ }
+ // return a full match only if the template is fully matched and if there
+ // are no more characters to match in the source
+ return compare_result_t(in_first, !has_trailing_nonspaces);
+ }
+
+ template <typename F>
+ inline int for_each_file(fs::path p, F f)
+ {
+ try
+ {
+ if (fs::exists(p) && fs::is_directory(p))
+ {
+ for (auto i = fs::directory_iterator(p); i != fs::directory_iterator(); ++i)
+ {
+ auto ext = fs::extension(i->path());
+ if (ext == ".input")
+ {
+ auto input_path = i->path();
+ auto expect_path = input_path;
+ expect_path.replace_extension(".expect");
+ f(input_path, expect_path);
+ }
+ }
+ }
+ else
+ {
+ std::cerr << "Directory: " << fs::absolute(p) << " does not exist." << std::endl;
+ return 1;
+ }
+ }
+
+ catch (const fs::filesystem_error& ex)
+ {
+ std::cerr << ex.what() << '\n';
+ return 1;
+ }
+ return 0;
+ }
+
+ inline std::string load(fs::path p)
+ {
+ boost::filesystem::ifstream file(p);
+ if (!file)
+ return "";
+ std::string contents((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
+ return contents;
+ }
+
+ template <typename F>
+ inline bool compare(
+ fs::path input_path, fs::path expect_path
+ , F f
+ , char const* re_prefix
+ , char const* re_suffix
+ )
+ {
+ std::string output = f(load(input_path), input_path);
+ std::string expected = load(expect_path);
+
+ auto result = compare(output, expected);
+ if (!result.full_match)
+ {
+ std::cout << "=============================================" << std::endl;
+ std::cout << "==== Mismatch Found:" << std::endl;
+ int line = 1;
+ int col = 1;
+ for (auto i = output.begin(); i != result.pos; ++i)
+ {
+ if (*i == '\n')
+ {
+ line++;
+ col = 0;
+ }
+ ++col;
+ }
+
+ std::cerr
+ << "==== File: " << expect_path
+ << ", Line: " << line
+ << ", Column: " << col
+ << std::endl;
+ std::cerr << "=============================================" << std::endl;
+
+ // Print output
+ std::cerr << output;
+ std::cerr << "=============================================" << std::endl;
+ std::cerr << "==== End" << std::endl;
+ std::cerr << "=============================================" << std::endl;
+ return false;
+ }
+ return true;
+ }
}}}}
diff --git a/boost/spirit/home/x3/support/utility/unrefcv.hpp b/boost/spirit/home/x3/support/utility/unrefcv.hpp
index fa4d448178..b12620b591 100644
--- a/boost/spirit/home/x3/support/utility/unrefcv.hpp
+++ b/boost/spirit/home/x3/support/utility/unrefcv.hpp
@@ -7,10 +7,6 @@
#ifndef BOOST_SPIRIT_X3_UNREFCV_HPP_INCLUDED
#define BOOST_SPIRIT_X3_UNREFCV_HPP_INCLUDED
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
diff --git a/boost/spirit/home/x3/support/utility/utf8.hpp b/boost/spirit/home/x3/support/utility/utf8.hpp
index 93b5a22077..b141cce6d2 100644
--- a/boost/spirit/home/x3/support/utility/utf8.hpp
+++ b/boost/spirit/home/x3/support/utility/utf8.hpp
@@ -7,12 +7,7 @@
#if !defined(BOOST_SPIRIT_X3_UC_TYPES_NOVEMBER_23_2008_0840PM)
#define BOOST_SPIRIT_X3_UC_TYPES_NOVEMBER_23_2008_0840PM
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
#include <boost/cstdint.hpp>
-#include <boost/foreach.hpp>
#include <boost/regex/pending/unicode_iterator.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <string>
@@ -61,7 +56,7 @@ namespace boost { namespace spirit { namespace x3
insert_iter out_iter(result);
utf8_output_iterator<insert_iter> utf8_iter(out_iter);
typedef typename make_unsigned<Char>::type UChar;
- BOOST_FOREACH(Char ch, str)
+ for (Char ch : str)
{
*utf8_iter++ = (UChar)ch;
}
diff --git a/boost/spirit/home/x3/version.hpp b/boost/spirit/home/x3/version.hpp
new file mode 100644
index 0000000000..3add2f4149
--- /dev/null
+++ b/boost/spirit/home/x3/version.hpp
@@ -0,0 +1,19 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Distributed under the 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(SPIRIT_X3_VERSION_INCLUDED)
+#define SPIRIT_X3_VERSION_INCLUDED
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// This is the version of the current Spirit X3 distribution
+//
+///////////////////////////////////////////////////////////////////////////////
+#define SPIRIT_X3_VERSION 0x3000
+
+#endif
diff --git a/boost/spirit/repository/home/karma/nonterminal/subrule.hpp b/boost/spirit/repository/home/karma/nonterminal/subrule.hpp
index 0c6fc6bfa8..a2893bc404 100644
--- a/boost/spirit/repository/home/karma/nonterminal/subrule.hpp
+++ b/boost/spirit/repository/home/karma/nonterminal/subrule.hpp
@@ -414,7 +414,11 @@ namespace boost { namespace spirit { namespace repository { namespace karma
// create Defs map with only one entry: (ID -> def)
typedef typename
+#ifndef BOOST_FUSION_HAS_VARIADIC_MAP
fusion::result_of::make_map<id_type, def_type>::type
+#else
+ fusion::result_of::make_map<id_type>::template apply<def_type>::type
+#endif
defs_type;
typedef subrule_group<defs_type> type;
diff --git a/boost/spirit/repository/home/qi/directive/kwd.hpp b/boost/spirit/repository/home/qi/directive/kwd.hpp
index 18020804bd..98f49409ba 100644
--- a/boost/spirit/repository/home/qi/directive/kwd.hpp
+++ b/boost/spirit/repository/home/qi/directive/kwd.hpp
@@ -255,7 +255,7 @@ template <typename T>
};
// This class enables the transportation of parameters needed to call
- // the occurence constraint checker from higher level calls
+ // the occurrence constraint checker from higher level calls
// It also serves to select the correct parse function call
// of the keyword parser. The implementation changes depending if it is
// called form a keyword parsing loop or not.
diff --git a/boost/spirit/repository/home/qi/nonterminal/subrule.hpp b/boost/spirit/repository/home/qi/nonterminal/subrule.hpp
index 170367b71c..4a29f44e65 100644
--- a/boost/spirit/repository/home/qi/nonterminal/subrule.hpp
+++ b/boost/spirit/repository/home/qi/nonterminal/subrule.hpp
@@ -440,7 +440,11 @@ namespace boost { namespace spirit { namespace repository { namespace qi
// create Defs map with only one entry: (ID -> def)
typedef typename
+#ifndef BOOST_FUSION_HAS_VARIADIC_MAP
fusion::result_of::make_map<id_type, def_type>::type
+#else
+ fusion::result_of::make_map<id_type>::template apply<def_type>::type
+#endif
defs_type;
typedef subrule_group<defs_type> type;
diff --git a/boost/spirit/repository/home/qi/operator/keywords.hpp b/boost/spirit/repository/home/qi/operator/keywords.hpp
index 4933f91104..f6b05fcb39 100644
--- a/boost/spirit/repository/home/qi/operator/keywords.hpp
+++ b/boost/spirit/repository/home/qi/operator/keywords.hpp
@@ -254,7 +254,7 @@ namespace boost { namespace spirit { namespace repository { namespace qi
// We have a bool array 'flags' with one flag for each parser as well as a 'counter'
// array.
- // The kwd directive sets and increments the counter when a successeful parse occured
+ // The kwd directive sets and increments the counter when a successeful parse occurred
// as well as the slot of the corresponding parser to true in the flags array as soon
// the minimum repetition requirement is met and keeps that value to true as long as
// the maximum repetition requirement is met.
@@ -335,7 +335,7 @@ namespace boost { namespace spirit { namespace repository { namespace qi
// We have a bool array 'flags' with one flag for each parser as well as a 'counter'
// array.
- // The kwd directive sets and increments the counter when a successeful parse occured
+ // The kwd directive sets and increments the counter when a successeful parse occurred
// as well as the slot of the corresponding parser to true in the flags array as soon
// the minimum repetition requirement is met and keeps that value to true as long as
// the maximum repetition requirement is met.
diff --git a/boost/test/auto_unit_test.hpp b/boost/test/auto_unit_test.hpp
index c99316888e..df41743962 100644
--- a/boost/test/auto_unit_test.hpp
+++ b/boost/test/auto_unit_test.hpp
@@ -1,15 +1,13 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : deprecated
+//! @file
+//! @brief Deprecated header.
+//! @deprecated Use @c boost/test/unit_test.hpp instead.
// ***************************************************************************
#ifndef BOOST_TEST_AUTO_UNIT_TEST_HPP_071894GER
diff --git a/boost/test/data/config.hpp b/boost/test/data/config.hpp
new file mode 100644
index 0000000000..bedfae5de0
--- /dev/null
+++ b/boost/test/data/config.hpp
@@ -0,0 +1,48 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+//!@file
+//!@brief common dataset macros
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_CONFIG_HPP_112611GER
+#define BOOST_TEST_DATA_CONFIG_HPP_112611GER
+
+// Boost.Test
+#include <boost/test/detail/config.hpp>
+#include <boost/test/detail/throw_exception.hpp>
+
+// STL
+#include <stdexcept> // for std::logic_error
+
+
+// availability on features: preprocessed by doxygen
+
+#if defined(BOOST_NO_CXX11_HDR_RANDOM) || defined(BOOST_TEST_DOXYGEN_DOC__)
+//! Defined when the random dataset feature is not available
+#define BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE
+
+#endif
+
+
+#if defined(BOOST_NO_CXX11_HDR_TUPLE) || defined(BOOST_TEST_DOXYGEN_DOC__)
+
+//! Defined when grid composition of datasets is not available
+#define BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE
+
+//! Defined when zip composition of datasets is not available
+#define BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE
+
+#endif
+
+//____________________________________________________________________________//
+
+#define BOOST_TEST_DS_ERROR( msg ) BOOST_TEST_IMPL_THROW( std::logic_error( msg ) )
+#define BOOST_TEST_DS_ASSERT( cond, msg ) if( cond ) {} else BOOST_TEST_DS_ERROR( msg )
+
+#endif // BOOST_TEST_DATA_CONFIG_HPP_112611GER
+
diff --git a/boost/test/data/dataset.hpp b/boost/test/data/dataset.hpp
new file mode 100644
index 0000000000..390cf5bf3f
--- /dev/null
+++ b/boost/test/data/dataset.hpp
@@ -0,0 +1,19 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+//!@file
+//!@brief dataset interfaces
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_DATASET_HPP_102211GER
+#define BOOST_TEST_DATA_DATASET_HPP_102211GER
+
+// Boost.Test
+#include <boost/test/data/monomorphic.hpp>
+
+#endif // BOOST_TEST_DATA_DATASET_HPP_102211GER
+
diff --git a/boost/test/data/generators.hpp b/boost/test/data/generators.hpp
new file mode 100644
index 0000000000..ff8ad07400
--- /dev/null
+++ b/boost/test/data/generators.hpp
@@ -0,0 +1,19 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+//!@file
+//!@brief specific generators
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
+#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
+
+// Boost.Test
+#include <boost/test/data/monomorphic/generators/xrange.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
+
diff --git a/boost/test/data/monomorphic.hpp b/boost/test/data/monomorphic.hpp
new file mode 100644
index 0000000000..487b2a9cce
--- /dev/null
+++ b/boost/test/data/monomorphic.hpp
@@ -0,0 +1,26 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+//!@file
+//!@brief Monomorphic dataset interfaces
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_HPP_102211GER
+#define BOOST_TEST_DATA_MONOMORPHIC_HPP_102211GER
+
+// Boost.Test
+#include <boost/test/data/monomorphic/array.hpp>
+#include <boost/test/data/monomorphic/collection.hpp>
+#include <boost/test/data/monomorphic/generate.hpp>
+#include <boost/test/data/monomorphic/generators.hpp>
+#include <boost/test/data/monomorphic/grid.hpp>
+#include <boost/test/data/monomorphic/join.hpp>
+#include <boost/test/data/monomorphic/singleton.hpp>
+#include <boost/test/data/monomorphic/zip.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_HPP_102211GER
+
diff --git a/boost/test/data/monomorphic/array.hpp b/boost/test/data/monomorphic/array.hpp
new file mode 100644
index 0000000000..87c55e7653
--- /dev/null
+++ b/boost/test/data/monomorphic/array.hpp
@@ -0,0 +1,113 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+///@file
+///Defines monomorphic dataset based on C type arrays
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_ARRAY_HPP_121411GER
+#define BOOST_TEST_DATA_MONOMORPHIC_ARRAY_HPP_121411GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+#include <boost/test/data/monomorphic/dataset.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+namespace monomorphic {
+
+// ************************************************************************** //
+// ************** array ************** //
+// ************************************************************************** //
+
+/// Dataset view of an C array
+template<typename T>
+class array : public monomorphic::dataset<T> {
+ typedef monomorphic::dataset<T> base;
+ typedef typename base::iter_ptr iter_ptr;
+
+ struct iterator : public base::iterator {
+ // Constructor
+ explicit iterator( T const* begin, data::size_t size )
+ : m_it( begin )
+ , m_singleton( size == 1 )
+ {}
+
+ // forward iterator interface
+ virtual T const& operator*() { return *m_it; }
+ virtual void operator++() { if( !m_singleton ) ++m_it; }
+
+ private:
+ // Data members
+ T const* m_it;
+ bool m_singleton;
+ };
+
+public:
+ enum { arity = 1 };
+
+ // Constructor
+ array( T const* arr, std::size_t size )
+ : m_arr( arr )
+ , m_size( size )
+ {}
+
+ // dataset interface
+ virtual data::size_t size() const { return m_size; }
+ virtual iter_ptr begin() const { return boost::make_shared<iterator>( m_arr, m_size ); }
+
+private:
+ // Data members
+ T const* m_arr;
+ std::size_t m_size;
+};
+
+//____________________________________________________________________________//
+
+//! An array dataset is a dataset
+template<typename T>
+struct is_dataset<array<T> > : mpl::true_ {};
+
+} // namespace monomorphic
+
+
+//! @overload boost::unit_test::data::make()
+template<typename T, std::size_t size>
+inline monomorphic::array< typename boost::remove_const<T>::type > make( T (&a)[size] )
+{
+ return monomorphic::array< typename boost::remove_const<T>::type >( a, size );
+}
+
+//! @overload boost::unit_test::data::make()
+template<typename T, std::size_t size>
+inline monomorphic::array< typename boost::remove_const<T>::type > make( T const (&a)[size] )
+{
+ return monomorphic::array<T>( a, size );
+}
+
+template<typename T, std::size_t size>
+inline monomorphic::array< typename boost::remove_const<T>::type > make( T a[size] )
+{
+ return monomorphic::array<T>( a, size );
+}
+
+
+//____________________________________________________________________________//
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_ARRAY_HPP_121411GER
+
diff --git a/boost/test/data/monomorphic/collection.hpp b/boost/test/data/monomorphic/collection.hpp
new file mode 100644
index 0000000000..5666a62f8d
--- /dev/null
+++ b/boost/test/data/monomorphic/collection.hpp
@@ -0,0 +1,125 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+///@file
+///Defines monomorphic dataset based on forward iterable sequence
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_COLLECTION_HPP_102211GER
+#define BOOST_TEST_DATA_MONOMORPHIC_COLLECTION_HPP_102211GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+#include <boost/test/data/monomorphic/dataset.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+namespace monomorphic {
+
+// ************************************************************************** //
+// ************** collection ************** //
+// ************************************************************************** //
+
+
+//!@brief Dataset from a forward iterable container (collection)
+//!
+//! This dataset is applicable to any container implementing a forward iterator. Note that
+//! container with one element will be considered as singletons.
+//! This dataset is constructible with the @ref boost::unit_test::data::make function.
+//!
+//! For compilers supporting r-value references, the collection is moved instead of copied.
+template<typename C>
+class collection : public monomorphic::dataset<typename boost::decay<C>::type::value_type> {
+ typedef typename boost::decay<C>::type col_type;
+ typedef typename col_type::value_type T;
+ typedef monomorphic::dataset<T> base;
+ typedef typename base::iter_ptr iter_ptr;
+
+ struct iterator : public base::iterator {
+ // Constructor
+ explicit iterator( collection<C> const& owner )
+ : m_iter( owner.col().begin() )
+ , m_singleton( owner.col().size() == 1 )
+ {}
+
+ // forward iterator interface
+ virtual T const& operator*() { return *m_iter; }
+ virtual void operator++() { if( !m_singleton ) ++m_iter; }
+
+ private:
+ // Data members
+ typename col_type::const_iterator m_iter;
+ bool m_singleton;
+ };
+
+public:
+ enum { arity = 1 };
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ //! Constructor
+ //! The collection is moved
+ explicit collection( C&& col ) : m_col( std::forward<C>(col) ) {}
+
+ //! Move constructor
+ collection( collection&& c ) : m_col( std::forward<C>( c.m_col ) ) {}
+#else
+ //! Constructor
+ //! The collection is copied
+ explicit collection( C const& col ) : m_col( col ) {}
+#endif
+
+ //! Returns the underlying collection
+ C const& col() const { return m_col; }
+
+ // dataset interface
+ virtual data::size_t size() const { return m_col.size(); }
+ virtual iter_ptr begin() const { return boost::make_shared<iterator>( *this ); }
+
+private:
+ // Data members
+ C m_col;
+};
+
+//____________________________________________________________________________//
+
+//! A collection from a forward iterable container is a dataset.
+template<typename C>
+struct is_dataset<collection<C> > : mpl::true_ {};
+
+} // namespace monomorphic
+
+//! @overload boost::unit_test::data::make()
+template<typename C>
+inline typename BOOST_TEST_ENABLE_IF<is_forward_iterable<C>::value,
+ monomorphic::collection<C> >::type
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+make( C&& c )
+{
+ return monomorphic::collection<C>( std::forward<C>(c) );
+}
+#else
+make( C const& c )
+{
+ return monomorphic::collection<C>( c );
+}
+#endif
+
+//____________________________________________________________________________//
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_COLLECTION_HPP_102211GER
+
diff --git a/boost/test/data/monomorphic/dataset.hpp b/boost/test/data/monomorphic/dataset.hpp
new file mode 100644
index 0000000000..122dbea8c5
--- /dev/null
+++ b/boost/test/data/monomorphic/dataset.hpp
@@ -0,0 +1,174 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+/// @file
+/// Defines monomorphic dataset interface
+//
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_DATASET_HPP_102211GER
+#define BOOST_TEST_DATA_MONOMORPHIC_DATASET_HPP_102211GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+#include <boost/test/data/monomorphic/fwd.hpp>
+
+// STL
+#ifndef BOOST_NO_CXX11_HDR_TUPLE
+#include <tuple>
+#endif
+//#include <stdexcept>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+namespace monomorphic {
+
+// ************************************************************************** //
+// ************** monomorphic::traits ************** //
+// ************************************************************************** //
+
+template<typename T>
+struct traits {
+ // type of the reference to sample returned by iterator
+ typedef T const& ref_type;
+
+ template<typename Action>
+ static void
+ invoke_action( ref_type arg, Action const& action )
+ {
+ action( arg );
+ }
+};
+
+//____________________________________________________________________________//
+
+#ifndef BOOST_NO_CXX11_HDR_TUPLE
+// !! ?? reimplement using variadics
+template<typename T1, typename T2>
+struct traits<std::tuple<T1,T2>> {
+ // type of the reference to sample returned by iterator
+ typedef std::tuple<T1 const&,T2 const&> ref_type;
+
+ template<typename Action>
+ static void
+ invoke_action( ref_type arg, Action const& action )
+ {
+ action( std::get<0>(arg), std::get<1>(arg) );
+ }
+};
+
+//____________________________________________________________________________//
+
+template<typename T1, typename T2, typename T3>
+struct traits<std::tuple<T1,T2,T3>> {
+ // type of the reference to sample returned by iterator
+ typedef std::tuple<T1 const&,T2 const&,T3 const&> ref_type;
+
+ template<typename Action>
+ static void
+ invoke_action( ref_type arg, Action const& action )
+ {
+ action( std::get<0>(arg), std::get<1>(arg), std::get<2>(arg) );
+ }
+};
+
+//____________________________________________________________________________//
+
+#endif
+
+// ************************************************************************** //
+// ************** monomorphic::dataset ************** //
+// ************************************************************************** //
+
+//!@brief Dataset base class
+//!
+//! This class defines the dataset concept, which is an implementation of a sequence.
+//! Each dataset should implement
+//! - the @c size
+//! - the @c begin function, which provides a forward iterator on the beginning of the sequence. The returned
+//! iterator should be incrementable a number of times corresponding to the returned size.
+//!
+template<typename T>
+class dataset {
+public:
+ //! Type of the samples in this dataset
+ typedef T data_type;
+
+ virtual ~dataset()
+ {}
+
+ //! Interface of the dataset iterator
+ class iterator {
+ public:
+ typedef typename monomorphic::traits<T>::ref_type ref_type;
+
+ virtual ~iterator() {}
+
+ // forward iterator interface
+ virtual ref_type operator*() = 0;
+ virtual void operator++() = 0;
+ };
+
+ //! Type of the iterator
+ typedef boost::shared_ptr<iterator> iter_ptr;
+
+ //! Dataset size
+ virtual data::size_t size() const = 0;
+
+ //! Iterator to use to iterate over this dataset
+ virtual iter_ptr begin() const = 0;
+};
+
+} // namespace monomorphic
+
+// ************************************************************************** //
+// ************** for_each_sample ************** //
+// ************************************************************************** //
+
+template<typename SampleType, typename Action>
+inline void
+for_each_sample( monomorphic::dataset<SampleType> const& ds,
+ Action const& act,
+ data::size_t number_of_samples = BOOST_TEST_DS_INFINITE_SIZE )
+{
+ data::size_t size = (std::min)( ds.size(), number_of_samples );
+ BOOST_TEST_DS_ASSERT( !size.is_inf(), "Dataset has infinite size. Please specify the number of samples" );
+
+ typename monomorphic::dataset<SampleType>::iter_ptr it = ds.begin();
+
+ while( size-- > 0 ) {
+ monomorphic::traits<SampleType>::invoke_action( **it, act );
+ ++(*it);
+ }
+}
+
+//____________________________________________________________________________//
+
+template<typename SampleType, typename Action>
+inline typename BOOST_TEST_ENABLE_IF<!monomorphic::is_dataset<SampleType>::value,void>::type
+for_each_sample( SampleType const& samples,
+ Action const& act,
+ data::size_t number_of_samples = BOOST_TEST_DS_INFINITE_SIZE )
+{
+ data::for_each_sample( data::make( samples ), act, number_of_samples );
+}
+
+//____________________________________________________________________________//
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_DATASET_HPP_102211GER
+
diff --git a/boost/test/data/monomorphic/fwd.hpp b/boost/test/data/monomorphic/fwd.hpp
new file mode 100644
index 0000000000..9ff4955432
--- /dev/null
+++ b/boost/test/data/monomorphic/fwd.hpp
@@ -0,0 +1,314 @@
+// (C) Copyright Gennadiy Rozental 2012-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/test for the library home page.
+//
+/// @file
+/// Forward declares monomorphic datasets interfaces
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_FWD_HPP_102212GER
+#define BOOST_TEST_DATA_MONOMORPHIC_FWD_HPP_102212GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+#include <boost/test/data/size.hpp>
+
+#include <boost/test/utils/is_forward_iterable.hpp>
+
+
+// Boost
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/add_const.hpp>
+#else
+#include <boost/utility/declval.hpp>
+#endif
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/type_traits/decay.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+
+namespace monomorphic {
+
+
+#if !defined(BOOST_TEST_DOXYGEN_DOC__)
+template<typename T>
+struct traits;
+
+template<typename T>
+class dataset;
+
+template<typename T>
+class singleton;
+
+template<typename C>
+class collection;
+
+template<typename T>
+class array;
+#endif
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+# define BOOST_TEST_ENABLE_IF std::enable_if
+#else
+# define BOOST_TEST_ENABLE_IF boost::enable_if_c
+#endif
+
+// ************************************************************************** //
+// ************** monomorphic::is_dataset ************** //
+// ************************************************************************** //
+
+//! Helper metafunction indicating if the specified type is a dataset.
+template<typename DataSet>
+struct is_dataset : mpl::false_ {};
+
+//! A reference to a dataset is a dataset
+template<typename DataSet>
+struct is_dataset<DataSet&> : is_dataset<DataSet> {};
+
+//! A const dataset is a dataset
+template<typename DataSet>
+struct is_dataset<DataSet const> : is_dataset<DataSet> {};
+
+//____________________________________________________________________________//
+
+} // namespace monomorphic
+
+// ************************************************************************** //
+// ************** data::make ************** //
+// ************************************************************************** //
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+
+//! @brief Creates a dataset from a value, a collection or an array
+//!
+//! This function has several overloads:
+//! @code
+//! // returns ds if ds is already a dataset
+//! template <typename DataSet> DataSet make(DataSet&& ds);
+//!
+//! // creates a singleton dataset, for non forward iterable and non dataset type T
+//! // (a C string is not considered as a sequence).
+//! template <typename T> monomorphic::singleton<T> make(T&& v);
+//! monomorphic::singleton<char*> make( char* str );
+//! monomorphic::singleton<char const*> make( char const* str );
+//!
+//! // creates a collection dataset, for forward iterable and non dataset type C
+//! template <typename C> monomorphic::collection<C> make(C && c);
+//!
+//! // creates an array dataset
+//! template<typename T, std::size_t size> monomorphic::array<T> make( T (&a)[size] );
+//! @endcode
+template<typename DataSet>
+inline typename BOOST_TEST_ENABLE_IF<monomorphic::is_dataset<DataSet>::value,DataSet>::type
+make(DataSet&& ds)
+{
+ return std::forward<DataSet>( ds );
+}
+
+
+// warning: doxygen is apparently unable to handle @overload from different files, so if the overloads
+// below are not declared with @overload in THIS file, they do not appear in the documentation.
+
+// fwrd declaration for singletons
+//! @overload boost::unit_test::data::make()
+template<typename T>
+inline typename BOOST_TEST_ENABLE_IF<!is_forward_iterable<T>::value &&
+ !monomorphic::is_dataset<T>::value &&
+ !boost::is_array< typename boost::remove_reference<T>::type >::value,
+ monomorphic::singleton<T> >::type
+make( T&& v );
+
+
+//! @overload boost::unit_test::data::make()
+template<typename C>
+inline typename BOOST_TEST_ENABLE_IF<is_forward_iterable<C>::value,
+ monomorphic::collection<C> >::type
+make( C&& c );
+
+
+#else // !BOOST_NO_CXX11_RVALUE_REFERENCES
+
+//! @overload boost::unit_test:data::make()
+template<typename DataSet>
+inline typename BOOST_TEST_ENABLE_IF<monomorphic::is_dataset<DataSet>::value,DataSet const&>::type
+make(DataSet const& ds)
+{
+ return ds;
+}
+
+
+// fwrd declaration for singletons
+#if !(defined(BOOST_MSVC) && (BOOST_MSVC < 1600))
+//! @overload boost::unit_test::data::make()
+template<typename T>
+inline typename BOOST_TEST_ENABLE_IF<!is_forward_iterable<T>::value &&
+ !monomorphic::is_dataset<T>::value &&
+ !boost::is_array< typename boost::remove_reference<T>::type >::value,
+ monomorphic::singleton<T> >::type
+make( T const& v );
+#endif
+
+
+// fwrd declaration for collections
+//! @overload boost::unit_test::data::make()
+template<typename C>
+inline typename BOOST_TEST_ENABLE_IF<is_forward_iterable<C>::value,
+ monomorphic::collection<C> >::type
+make( C const& c );
+
+//____________________________________________________________________________//
+
+
+
+#endif // !BOOST_NO_CXX11_RVALUE_REFERENCES
+
+
+
+
+// fwrd declarations
+//! @overload boost::unit_test::data::make()
+template<typename T, std::size_t size>
+inline monomorphic::array< typename boost::remove_const<T>::type >
+make( T (&a)[size] );
+
+// apparently some compilers (eg clang-3.4 on linux) have trouble understanding
+// the previous line for T being const
+//! @overload boost::unit_test::data::make()
+template<typename T, std::size_t size>
+inline monomorphic::array< typename boost::remove_const<T>::type >
+make( T const (&)[size] );
+
+template<typename T, std::size_t size>
+inline monomorphic::array< typename boost::remove_const<T>::type >
+make( T a[size] );
+
+
+
+//! @overload boost::unit_test::data::make()
+inline monomorphic::singleton<char*>
+make( char* str );
+
+//! @overload boost::unit_test::data::make()
+inline monomorphic::singleton<char const*>
+make( char const* str );
+
+
+
+//____________________________________________________________________________//
+
+
+
+namespace result_of {
+
+#ifndef BOOST_NO_CXX11_DECLTYPE
+//! Result of the make call.
+template<typename DataSet>
+struct make
+{
+ typedef decltype(data::make(boost::declval<DataSet>())) type;
+};
+#else
+
+// explicit specialisation, cumbersome
+
+template <typename DataSet, typename Enable = void>
+struct make;
+
+template <typename DataSet>
+struct make<
+ DataSet const&,
+ typename BOOST_TEST_ENABLE_IF<monomorphic::is_dataset<DataSet>::value>::type
+ >
+{
+ typedef DataSet const& type;
+};
+
+template <typename T>
+struct make<
+ T,
+ typename BOOST_TEST_ENABLE_IF< (!is_forward_iterable<T>::value &&
+ !monomorphic::is_dataset<T>::value &&
+ !boost::is_array< typename boost::remove_reference<T>::type >::value)
+ >::type
+ >
+{
+ typedef monomorphic::singleton<T> type;
+};
+
+template <typename C>
+struct make<
+ C,
+ typename BOOST_TEST_ENABLE_IF< is_forward_iterable<C>::value>::type
+ >
+{
+ typedef monomorphic::collection<C> type;
+};
+
+#if 1
+template <typename T, std::size_t size>
+struct make<T [size]>
+{
+ typedef monomorphic::array<typename boost::remove_const<T>::type> type;
+};
+#endif
+
+template <typename T, std::size_t size>
+struct make<T (&)[size]>
+{
+ typedef monomorphic::array<typename boost::remove_const<T>::type> type;
+};
+
+template <typename T, std::size_t size>
+struct make<T const (&)[size]>
+{
+ typedef monomorphic::array<typename boost::remove_const<T>::type> type;
+};
+
+template <>
+struct make<char*>
+{
+ typedef monomorphic::singleton<char*> type;
+};
+
+template <>
+struct make<char const*>
+{
+ typedef monomorphic::singleton<char const*> type;
+};
+
+#endif // BOOST_NO_CXX11_DECLTYPE
+
+
+} // namespace result_of
+
+
+
+
+//____________________________________________________________________________//
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+
+
+
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_FWD_HPP_102212GER
+
diff --git a/boost/test/data/monomorphic/generate.hpp b/boost/test/data/monomorphic/generate.hpp
new file mode 100644
index 0000000000..c5ff1d699b
--- /dev/null
+++ b/boost/test/data/monomorphic/generate.hpp
@@ -0,0 +1,116 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+/// @file
+/// Defines generic interface for monomorphic dataset based on generator
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATE_HPP_112011GER
+#define BOOST_TEST_DATA_MONOMORPHIC_GENERATE_HPP_112011GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+#include <boost/test/data/monomorphic/dataset.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+namespace monomorphic {
+
+// ************************************************************************** //
+// ************** generated_by ************** //
+// ************************************************************************** //
+
+/*!@brief Generators interface
+ *
+ * This class implements the dataset concept over a generator. Examples of generators are:
+ * - xrange_t
+ * - random_t
+ *
+ * The generator concept is the following:
+ * - the type of the generated samples is given by field @c data_type
+ * - the member function @c capacity should return the size of the collection being generated (potentially infinite)
+ * - the member function @c next should change the state of the generator to the next generated value
+ * - the member function @c reset should put the state of the object in the same state as right after its instanciation
+ */
+template<typename Generator>
+class generated_by : public monomorphic::dataset<typename Generator::data_type> {
+ typedef typename Generator::data_type T;
+ typedef monomorphic::dataset<T> base;
+ typedef typename base::iter_ptr iter_ptr;
+
+ struct iterator : public base::iterator {
+ // Constructor
+ explicit iterator( Generator& gen )
+ : m_gen( gen )
+ {
+ if(m_gen.capacity() > 0) {
+ m_gen.reset();
+ ++*this;
+ }
+ }
+
+ // forward iterator interface
+ virtual T const& operator*() { return m_curr_sample; }
+ virtual void operator++() { m_curr_sample = m_gen.next(); }
+
+ private:
+ // Data members
+ Generator& m_gen;
+ T m_curr_sample;
+ };
+public:
+ enum { arity = 1 };
+ typedef Generator generator_type;
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ // Constructor
+ explicit generated_by( Generator&& G )
+ : m_generator( std::forward<Generator>(G) )
+ {}
+
+ // Move constructor
+ generated_by( generated_by&& rhs )
+ : m_generator( std::forward<Generator>(rhs.m_generator) )
+ {}
+#else
+ // Constructor
+ explicit generated_by( Generator const& G )
+ : m_generator( G )
+ {}
+#endif
+
+ //! Size of the underlying dataset
+ data::size_t size() const { return m_generator.capacity(); }
+
+ //! Iterator on the beginning of the dataset
+ virtual iter_ptr begin() const { return boost::make_shared<iterator>( boost::ref(const_cast<Generator&>(m_generator)) ); }
+
+private:
+ // Data members
+ Generator m_generator;
+};
+
+
+//! A generated dataset is a dataset.
+template<typename Generator>
+struct is_dataset<generated_by<Generator> > : mpl::true_ {};
+
+
+} // namespace monomorphic
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATE_HPP_112011GER
+
diff --git a/boost/test/data/monomorphic/generators.hpp b/boost/test/data/monomorphic/generators.hpp
new file mode 100644
index 0000000000..aa74d7abb1
--- /dev/null
+++ b/boost/test/data/monomorphic/generators.hpp
@@ -0,0 +1,20 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+///@file
+///Defines specific generators
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
+#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
+
+// Boost.Test
+#include <boost/test/data/monomorphic/generators/xrange.hpp>
+#include <boost/test/data/monomorphic/generators/random.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
+
diff --git a/boost/test/data/monomorphic/generators/keywords.hpp b/boost/test/data/monomorphic/generators/keywords.hpp
new file mode 100644
index 0000000000..4983678f95
--- /dev/null
+++ b/boost/test/data/monomorphic/generators/keywords.hpp
@@ -0,0 +1,39 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+///@file
+/// Keywords used in generator interfaces
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_KEYWORDS_HPP_101512GER
+#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_KEYWORDS_HPP_101512GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+#include <boost/test/utils/named_params.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+
+namespace {
+nfp::keyword<struct begin_t> begin;
+nfp::keyword<struct end_t> end;
+nfp::keyword<struct step_t> step;
+} // local namespace
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_KEYWORDS_HPP_101512GER
diff --git a/boost/test/data/monomorphic/generators/random.hpp b/boost/test/data/monomorphic/generators/random.hpp
new file mode 100644
index 0000000000..a82eef103d
--- /dev/null
+++ b/boost/test/data/monomorphic/generators/random.hpp
@@ -0,0 +1,198 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+//!@file
+//!@brief Random generator
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER
+#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+
+
+
+
+#if !defined(BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE) || defined(BOOST_TEST_DOXYGEN_DOC__)
+
+#include <boost/test/data/monomorphic/generate.hpp>
+#include <boost/test/data/monomorphic/generators/keywords.hpp>
+
+// STL
+#include <random>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+
+namespace {
+nfp::keyword<struct seed_t> seed;
+nfp::keyword<struct distrbution_t> distribution;
+nfp::keyword<struct engine_t> engine;
+} // local namespace
+
+namespace monomorphic {
+
+namespace ds_detail {
+template<typename SampleType>
+struct default_distribution {
+ typedef typename mpl::if_<std::is_integral<SampleType>,
+ std::uniform_int_distribution<SampleType>,
+ std::uniform_real_distribution<SampleType> >::type type;
+};
+
+} // namespace ds_detail
+
+// ************************************************************************** //
+// ************** random_t ************** //
+// ************************************************************************** //
+
+/*!@brief Generator for the random sequences
+ *
+ * This class implements the generator concept (see @ref boost::unit_test::data::monomorphic::generated_by) for implementing
+ * a random number generator.
+ */
+template<typename SampleType = double,
+ typename DistributionType = typename ds_detail::default_distribution<SampleType>::type,
+ typename EngineType = std::default_random_engine>
+class random_t {
+public:
+ typedef SampleType data_type;
+ typedef DistributionType distr_type;
+ typedef EngineType engine_type;
+
+ random_t()
+ : m_distribution()
+ , m_engine( std::random_device()() )
+ {}
+ explicit random_t( distr_type&& d )
+ : m_distribution( std::forward<distr_type>(d) )
+ , m_engine( std::random_device()() ){}
+ random_t( engine_type&& e, distr_type&& d )
+ : m_distribution( std::forward<distr_type>(d) )
+ , m_engine( std::forward<engine_type>(e) ){}
+
+ // Generator interface
+ data::size_t capacity() const { return BOOST_TEST_DS_INFINITE_SIZE; }
+ SampleType next()
+ {
+ return m_distribution( m_engine );
+ }
+ void reset() {}
+
+ //! Sets the seed of the pseudo-random number engine.
+ template<typename SeedType>
+ void seed( SeedType&& seed ) { m_engine.seed( std::forward<SeedType>( seed ) ); }
+
+private:
+ // Data members
+ DistributionType m_distribution;
+ EngineType m_engine;
+};
+
+//____________________________________________________________________________//
+
+} // namespace monomorphic
+
+
+//! @brief Returns an infinite sequence of random numbers.
+//!
+//! The following overloads are available:
+//! @code
+//! auto d = random();
+//! auto d = random(begin, end);
+//! auto d = random(params);
+//! @endcode
+//!
+//!
+//! - The first overload uses the default distribution, which is uniform and which elements
+//! are @c double type (the values are in [0, 1) ).
+//! - The second overload generates numbers in the given interval. The distribution is uniform (in [begin, end)
+//! for real numbers, and in [begin, end] for integers). The type of the distribution is deduced from the type
+//! of the @c begin and @c end parameters.
+//! - The third overload generates numbers using the named parameter inside @c params , which are:
+//! - @c distribution: the distribution used. In this overload, since the type of the samples cannot be deduced,
+//! the samples are of type @c double and the distribution is uniform real in [0, 1).
+//! - @c seed: the seed for generating the values
+//! - @c engine: the random number generator engine
+//!
+//! The function returns an object that implements the dataset API.
+//! @note This function is available only for C++11 capable compilers.
+inline monomorphic::generated_by< monomorphic::random_t<> > random()
+{
+ return monomorphic::generated_by<monomorphic::random_t<>>( monomorphic::random_t<>() );
+}
+
+//____________________________________________________________________________//
+
+/// @overload boost::unit_test::data::random()
+template<typename SampleType>
+inline monomorphic::generated_by< monomorphic::random_t<SampleType> >
+random( SampleType begin, SampleType end )
+{
+ typedef monomorphic::random_t<SampleType> Gen;
+ typedef typename Gen::distr_type distr_type;
+ return monomorphic::generated_by<Gen>( Gen( distr_type(begin,end) ) );
+}
+
+//____________________________________________________________________________//
+
+namespace ds_detail {
+template<typename Params>
+struct random_gen_type {
+ typedef typename nfp::param_type<Params,decltype(distribution),std::uniform_real_distribution<>>::type distr_type;
+ typedef typename nfp::param_type<Params,decltype(engine),std::default_random_engine>::type engine_type;
+ typedef typename distr_type::result_type sample_type;
+
+ typedef monomorphic::random_t<sample_type,distr_type,engine_type> type;
+};
+
+}
+
+
+/// @overload boost::unit_test::data::random()
+template<typename Params>
+inline monomorphic::generated_by<typename ds_detail::random_gen_type<Params>::type>
+random( Params const& params )
+{
+ typedef typename ds_detail::random_gen_type<Params>::type Gen;
+ typedef typename Gen::distr_type distr_type;
+ typedef typename Gen::engine_type engine_type;
+
+ std::random_device rd;
+ engine_type E;
+// engine_type E( rd );
+ if( params.has(engine) )
+ E = params[engine];
+
+ distr_type D;
+ if( params.has(distribution) )
+ D = params[distribution];
+
+ Gen G( std::move(E), std::move(D) );
+
+ if( params.has(seed) )
+ G.seed( params[seed] );
+
+ return monomorphic::generated_by<Gen>( std::move(G) );
+}
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE
+
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER
diff --git a/boost/test/data/monomorphic/generators/xrange.hpp b/boost/test/data/monomorphic/generators/xrange.hpp
new file mode 100644
index 0000000000..55a51110b4
--- /dev/null
+++ b/boost/test/data/monomorphic/generators/xrange.hpp
@@ -0,0 +1,221 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+///@file
+///Defines range generator
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER
+#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+
+#include <boost/test/data/monomorphic/generators/keywords.hpp>
+#include <boost/test/data/monomorphic/generate.hpp>
+
+// Boost
+#include <boost/optional.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_unsigned.hpp>
+
+// STL
+#include <limits>
+#include <cmath>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+namespace monomorphic {
+
+// ************************************************************************** //
+// ************** monomorphic::xrange_t ************** //
+// ************************************************************************** //
+
+
+/*!@brief Generator for the range sequences
+ *
+ * This class implements the generator concept (see @ref boost::unit_test::data::monomorphic::generated_by) for implementing
+ * a range like sequence of numbers.
+ */
+template<typename SampleType, typename StepType=SampleType>
+class xrange_t {
+public:
+ typedef SampleType data_type;
+
+ xrange_t( SampleType const& begin, StepType const& step, data::size_t size )
+ : m_begin( begin )
+ , m_curr( begin )
+ , m_step( step )
+ , m_index( 0 )
+ , m_size( size )
+ {}
+
+ // Generator interface
+ data::size_t capacity() const { return m_size; }
+ SampleType next()
+ {
+ if( m_index == m_size )
+ return m_curr;
+
+ SampleType res = m_curr;
+
+ m_curr += m_step;
+ ++m_index;
+
+ return res;
+ }
+ void reset()
+ {
+ m_curr = m_begin;
+ m_index = 0;
+ }
+
+private:
+ // Data members
+ SampleType m_begin;
+ SampleType m_curr;
+ StepType m_step;
+ data::size_t m_index;
+ data::size_t m_size;
+};
+
+//____________________________________________________________________________//
+
+namespace ds_detail {
+
+template<typename SampleType, typename StepType=SampleType>
+struct make_xrange {
+ static StepType abs( StepType s, boost::true_type* ) { return s; }
+ static StepType abs( StepType s, boost::false_type* ) { return std::abs(s); }
+
+ typedef xrange_t<SampleType, StepType> range_gen;
+
+ template<typename Params>
+ static generated_by<range_gen>
+ _( Params const& params )
+ {
+ SampleType begin_val = params.has( data::begin ) ? params[data::begin] : SampleType();
+ optional<SampleType> end_val = params.has( data::end ) ? params[data::end] : optional<SampleType>();
+ StepType step_val = params.has( data::step ) ? params[data::step] : 1;
+
+ BOOST_TEST_DS_ASSERT( step_val != 0, "Range step can't be zero" );
+
+ data::size_t size;
+ if( !end_val.is_initialized() )
+ size = BOOST_TEST_DS_INFINITE_SIZE;
+ else {
+ BOOST_TEST_DS_ASSERT( (step_val < 0) ^ (begin_val < *end_val), "Invalid step direction" );
+
+ SampleType abs_distance = step_val < 0 ? begin_val - *end_val : *end_val-begin_val;
+ StepType abs_step = make_xrange::abs(step_val, (typename boost::is_unsigned<StepType>::type*)0 );
+ std::size_t s = static_cast<std::size_t>(abs_distance/abs_step);
+
+ if( static_cast<SampleType>(s*abs_step) < abs_distance )
+ s++;
+
+ size = s;
+ }
+
+ return generated_by<range_gen>( range_gen( begin_val, step_val, size ) );
+ }
+};
+
+} // namespace ds_detail
+} // namespace monomorphic
+
+//____________________________________________________________________________//
+
+//! Creates a range (sequence) dataset.
+//!
+//! The following overloads are available:
+//! @code
+//! auto d = xrange();
+//! auto d = xrange(end_val);
+//! auto d = xrange(end_val, param);
+//! auto d = xrange(begin_val, end_val);
+//! auto d = xrange(begin_val, end_val, step_val);
+//! auto d = xrange(param);
+//! @endcode
+//!
+//! - @c begin_val indicates the start of the sequence (default to 0).
+//! - @c end_val is the end of the sequence. If ommited, the dataset has infinite size.\n
+//! - @c step_val is the step between two consecutive elements of the sequence, and defaults to 1.\n
+//! - @c param is the named parameters that describe the sequence. The following parameters are accepted:
+//! - @c begin: same meaning @c begin_val
+//! - @c end: same meaning as @c end_val
+//! - @c step: same meaning as @c step_val
+//!
+//!
+//! The returned value is an object that implements the dataset API.
+//!
+//! @note the step size cannot be null, and it should be positive if @c begin_val < @c end_val, negative otherwise.
+template<typename SampleType, typename Params>
+inline monomorphic::generated_by<monomorphic::xrange_t<SampleType> >
+xrange( Params const& params )
+{
+ return monomorphic::ds_detail::make_xrange<SampleType>::_( params );
+}
+
+//____________________________________________________________________________//
+
+/// @overload boost::unit_test::data::xrange()
+template<typename SampleType>
+inline monomorphic::generated_by<monomorphic::xrange_t<SampleType> >
+xrange( SampleType const& end_val )
+{
+ return monomorphic::ds_detail::make_xrange<SampleType>::_( data::end=end_val );
+}
+
+//____________________________________________________________________________//
+
+/// @overload boost::unit_test::data::xrange()
+template<typename SampleType, typename Params>
+inline typename enable_if_c<nfp::is_named_params<Params>::value,monomorphic::generated_by<monomorphic::xrange_t<SampleType> > >::type
+xrange( SampleType const& end_val, Params const& params )
+{
+ return monomorphic::ds_detail::make_xrange<SampleType>::
+ _(( params, data::end=end_val ));
+}
+
+//____________________________________________________________________________//
+
+/// @overload boost::unit_test::data::xrange()
+template<typename SampleType>
+inline monomorphic::generated_by<monomorphic::xrange_t<SampleType> >
+xrange( SampleType const& begin_val, SampleType const& end_val )
+{
+ return monomorphic::ds_detail::make_xrange<SampleType>::
+ _(( data::begin=begin_val, data::end=end_val ));
+}
+
+//____________________________________________________________________________//
+
+
+
+/// @overload boost::unit_test::data::xrange()
+template<typename SampleType,typename StepType>
+inline monomorphic::generated_by<monomorphic::xrange_t<SampleType> >
+xrange( SampleType const& begin_val, SampleType const& end_val, StepType const& step_val )
+{
+ return monomorphic::ds_detail::make_xrange<SampleType,StepType>::
+ _(( data::begin=begin_val, data::end=end_val, data::step=step_val ));
+}
+
+//____________________________________________________________________________//
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER
diff --git a/boost/test/data/monomorphic/grid.hpp b/boost/test/data/monomorphic/grid.hpp
new file mode 100644
index 0000000000..00aaa56cd1
--- /dev/null
+++ b/boost/test/data/monomorphic/grid.hpp
@@ -0,0 +1,226 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+///@file
+/// Defines monomorphic dataset n+m dimentional *. Samples in this
+/// dataset is grid of elements in DS1 and DS2. There will be total
+/// |DS1| * |DS2| samples
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_GRID_HPP_101512GER
+#define BOOST_TEST_DATA_MONOMORPHIC_GRID_HPP_101512GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+
+
+#if !defined(BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE) || defined(BOOST_TEST_DOXYGEN_DOC__)
+
+#include <boost/test/data/monomorphic/dataset.hpp>
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+namespace monomorphic {
+
+namespace ds_detail {
+
+// !! ?? variadic template implementation; use forward_as_tuple?
+template<typename T1, typename T2>
+struct grid_traits {
+ typedef std::tuple<T1,T2> type;
+ typedef typename monomorphic::traits<type>::ref_type ref_type;
+
+ static ref_type
+ tuple_merge(T1 const& a1, T2 const& a2)
+ {
+ return ref_type(a1,a2);
+ }
+};
+
+//____________________________________________________________________________//
+
+template<typename T1, typename T2,typename T3>
+struct grid_traits<T1,std::tuple<T2,T3>> {
+ typedef std::tuple<T1,T2,T3> type;
+ typedef typename monomorphic::traits<type>::ref_type ref_type;
+
+ static ref_type
+ tuple_merge(T1 const& a1, std::tuple<T2 const&,T3 const&> const& a2)
+ {
+ return ref_type(a1,get<0>(a2),get<1>(a2));
+ }
+};
+
+//____________________________________________________________________________//
+
+template<typename T1, typename T2,typename T3>
+struct grid_traits<std::tuple<T1,T2>,T3> {
+ typedef std::tuple<T1,T2,T3> type;
+ typedef typename monomorphic::traits<type>::ref_type ref_type;
+
+ static ref_type
+ tuple_merge(std::tuple<T1 const&,T2 const&> const& a1, T3 const& a2)
+ {
+ return ref_type(get<0>(a1),get<1>(a1),a2);
+ }
+};
+
+//____________________________________________________________________________//
+
+} // namespace ds_detail
+
+// ************************************************************************** //
+// ************** grid ************** //
+// ************************************************************************** //
+
+
+//! Implements the dataset resulting from a cartesian product/grid operation on datasets.
+//!
+//! The arity of the resulting dataset is the sum of the arity of its operands.
+template<typename DS1, typename DS2>
+class grid : public monomorphic::dataset<typename ds_detail::grid_traits<typename boost::decay<DS1>::type::data_type,
+ typename boost::decay<DS2>::type::data_type>::type> {
+ typedef typename boost::decay<DS1>::type::data_type T1;
+ typedef typename boost::decay<DS2>::type::data_type T2;
+
+ typedef typename monomorphic::dataset<T1>::iter_ptr ds1_iter_ptr;
+ typedef typename monomorphic::dataset<T2>::iter_ptr ds2_iter_ptr;
+
+ typedef typename ds_detail::grid_traits<T1,T2>::type T;
+ typedef monomorphic::dataset<T> base;
+ typedef typename base::iter_ptr iter_ptr;
+
+ struct iterator : public base::iterator {
+ typedef typename monomorphic::traits<T>::ref_type ref_type;
+
+ // Constructor
+ explicit iterator( ds1_iter_ptr iter1, DS2 const& ds2 )
+ : m_iter1( iter1 )
+ , m_iter2( ds2.begin() )
+ , m_ds2( ds2 )
+ , m_ds2_pos( 0 )
+ {}
+
+ // forward iterator interface
+ virtual ref_type operator*() { return ds_detail::grid_traits<T1,T2>::tuple_merge( **m_iter1, **m_iter2 ); }
+ virtual void operator++()
+ {
+ ++m_ds2_pos;
+ if( m_ds2_pos != m_ds2.size() )
+ ++(*m_iter2);
+ else {
+ m_ds2_pos = 0;
+ ++(*m_iter1);
+ m_iter2 = m_ds2.begin();
+ }
+ }
+
+ private:
+ // Data members
+ ds1_iter_ptr m_iter1;
+ ds2_iter_ptr m_iter2;
+ DS2 const& m_ds2;
+ data::size_t m_ds2_pos;
+ };
+
+public:
+ enum { arity = boost::decay<DS1>::type::arity + boost::decay<DS2>::type::arity };
+
+ //! Constructor
+ grid( DS1&& ds1, DS2&& ds2 )
+ : m_ds1( std::forward<DS1>( ds1 ) )
+ , m_ds2( std::forward<DS2>( ds2 ) )
+ {}
+
+ //! Move constructor
+ grid( grid&& j )
+ : m_ds1( std::forward<DS1>( j.m_ds1 ) )
+ , m_ds2( std::forward<DS2>( j.m_ds2 ) )
+ {}
+
+ // dataset interface
+ virtual data::size_t size() const { return m_ds1.size() * m_ds2.size(); }
+ virtual iter_ptr begin() const { return boost::make_shared<iterator>( m_ds1.begin(), m_ds2 ); }
+
+private:
+ // Data members
+ DS1 m_ds1;
+ DS2 m_ds2;
+};
+
+//____________________________________________________________________________//
+
+// A grid dataset is a dataset
+template<typename DS1, typename DS2>
+struct is_dataset<grid<DS1,DS2> > : mpl::true_ {};
+
+//____________________________________________________________________________//
+
+namespace result_of {
+
+/// Result type of the grid operation on dataset.
+template<typename DS1Gen, typename DS2Gen>
+struct grid {
+ typedef monomorphic::grid<typename DS1Gen::type,typename DS2Gen::type> type;
+};
+
+} // namespace result_of
+
+//____________________________________________________________________________//
+
+
+
+//! Grid operation
+template<typename DS1, typename DS2>
+inline typename boost::lazy_enable_if_c<is_dataset<DS1>::value && is_dataset<DS2>::value,
+ result_of::grid<mpl::identity<DS1>,mpl::identity<DS2>>
+>::type
+operator*( DS1&& ds1, DS2&& ds2 )
+{
+ BOOST_TEST_DS_ASSERT( !ds1.size().is_inf() && !ds2.size().is_inf(), "Grid dimension can't have infinite size" );
+
+ return grid<DS1,DS2>( std::forward<DS1>( ds1 ), std::forward<DS2>( ds2 ) );
+}
+
+//! @overload boost::unit_test::data::operator*
+template<typename DS1, typename DS2>
+inline typename boost::lazy_enable_if_c<is_dataset<DS1>::value && !is_dataset<DS2>::value,
+ result_of::grid<mpl::identity<DS1>,data::result_of::make<DS2>>
+>::type
+operator*( DS1&& ds1, DS2&& ds2 )
+{
+ return std::forward<DS1>(ds1) * data::make(std::forward<DS2>(ds2));
+}
+
+//! @overload boost::unit_test::data::operator*
+template<typename DS1, typename DS2>
+inline typename boost::lazy_enable_if_c<!is_dataset<DS1>::value && is_dataset<DS2>::value,
+ result_of::grid<data::result_of::make<DS1>,mpl::identity<DS2>>
+>::type
+operator*( DS1&& ds1, DS2&& ds2 )
+{
+ return data::make(std::forward<DS1>(ds1)) * std::forward<DS2>(ds2);
+}
+
+//____________________________________________________________________________//
+
+} // namespace monomorphic
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_GRID_HPP_101512GER
+
diff --git a/boost/test/data/monomorphic/join.hpp b/boost/test/data/monomorphic/join.hpp
new file mode 100644
index 0000000000..94b25c78e2
--- /dev/null
+++ b/boost/test/data/monomorphic/join.hpp
@@ -0,0 +1,194 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+//! @file
+//! Defines dataset join operation
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_JOIN_HPP_112711GER
+#define BOOST_TEST_DATA_MONOMORPHIC_JOIN_HPP_112711GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+#include <boost/test/data/monomorphic/dataset.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+namespace monomorphic {
+
+// ************************************************************************** //
+// ************** join ************** //
+// ************************************************************************** //
+
+//! Defines a new dataset from the concatenation of two datasets
+//!
+//! The size of the resulting dataset is the sum of the two underlying datasets. The arity of the datasets
+//! should match.
+template<typename DS1, typename DS2>
+class join : public monomorphic::dataset<typename boost::decay<DS1>::type::data_type> {
+ typedef typename boost::decay<DS1>::type::data_type T;
+ typedef monomorphic::dataset<T> base;
+ typedef typename base::iter_ptr iter_ptr;
+
+ struct iterator : public base::iterator {
+ // Constructor
+ explicit iterator( iter_ptr it1, iter_ptr it2, data::size_t first_size )
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ : m_it1( std::move(it1) )
+ , m_it2( std::move(it2) )
+#else
+ : m_it1( it1 )
+ , m_it2( it2 )
+#endif
+ , m_first_size( first_size )
+ {}
+
+ // forward iterator interface
+ virtual T const& operator*() { return m_first_size > 0 ? **m_it1 : **m_it2; }
+ virtual void operator++() { m_first_size > 0 ? (--m_first_size,++(*m_it1)) : ++(*m_it2); }
+
+ private:
+ // Data members
+ iter_ptr m_it1;
+ iter_ptr m_it2;
+ data::size_t m_first_size;
+ };
+
+public:
+ enum { arity = boost::decay<DS1>::type::arity };
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ // Constructor
+ join( DS1&& ds1, DS2&& ds2 )
+ : m_ds1( std::forward<DS1>( ds1 ) )
+ , m_ds2( std::forward<DS2>( ds2 ) )
+ {}
+
+ // Move constructor
+ join( join&& j )
+ : m_ds1( std::forward<DS1>( j.m_ds1 ) )
+ , m_ds2( std::forward<DS2>( j.m_ds2 ) )
+ {}
+#else
+ // Constructor
+ join( DS1 const& ds1, DS2 const& ds2 )
+ : m_ds1( ds1 )
+ , m_ds2( ds2 )
+ {}
+#endif
+
+ // dataset interface
+ virtual data::size_t size() const { return m_ds1.size() + m_ds2.size(); }
+ virtual iter_ptr begin() const { return boost::make_shared<iterator>( m_ds1.begin(),
+ m_ds2.begin(),
+ m_ds1.size() ); }
+
+private:
+ // Data members
+ DS1 m_ds1;
+ DS2 m_ds2;
+};
+
+//____________________________________________________________________________//
+
+// A joined dataset is a dataset.
+template<typename DS1, typename DS2>
+struct is_dataset<join<DS1,DS2> > : mpl::true_ {};
+
+//____________________________________________________________________________//
+
+namespace result_of {
+
+//! Result type of the join operation on datasets.
+template<typename DS1Gen, typename DS2Gen>
+struct join {
+ typedef monomorphic::join<typename DS1Gen::type,typename DS2Gen::type> type;
+};
+
+} // namespace result_of
+
+//____________________________________________________________________________//
+
+template<typename DS1, typename DS2>
+inline typename boost::lazy_enable_if_c<is_dataset<DS1>::value && is_dataset<DS2>::value,
+ result_of::join<mpl::identity<DS1>,mpl::identity<DS2> >
+>::type
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+operator+( DS1&& ds1, DS2&& ds2 )
+{
+ return join<DS1,DS2>( std::forward<DS1>( ds1 ), std::forward<DS2>( ds2 ) );
+}
+#else
+operator+( DS1 const& ds1, DS2 const& ds2 )
+{
+ return join<DS1,DS2>( ds1, ds2 );
+}
+#endif
+
+//____________________________________________________________________________//
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template<typename DS1, typename DS2>
+inline typename boost::lazy_enable_if_c<is_dataset<DS1>::value && !is_dataset<DS2>::value,
+ result_of::join<mpl::identity<DS1>,data::result_of::make<DS2> >
+>::type
+operator+( DS1&& ds1, DS2&& ds2 )
+{
+ return std::forward<DS1>(ds1) + data::make(std::forward<DS2>(ds2));
+}
+#else
+template<typename DS1, typename DS2>
+inline typename boost::lazy_enable_if_c<is_dataset<DS1>::value && !is_dataset<DS2>::value,
+ result_of::join<mpl::identity<DS1>,data::result_of::make<DS2> >
+>::type
+operator+( DS1 const& ds1, DS2 const& ds2 )
+{
+ return ds1 + data::make(ds2);
+}
+#endif
+
+//____________________________________________________________________________//
+
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+template<typename DS1, typename DS2>
+inline typename boost::lazy_enable_if_c<!is_dataset<DS1>::value && is_dataset<DS2>::value,
+ result_of::join<data::result_of::make<DS1>,mpl::identity<DS2> >
+>::type
+operator+( DS1&& ds1, DS2&& ds2 )
+{
+ return data::make(std::forward<DS1>(ds1)) + std::forward<DS2>(ds2);
+}
+#else
+template<typename DS1, typename DS2>
+inline typename boost::lazy_enable_if_c<!is_dataset<DS1>::value && is_dataset<DS2>::value,
+ result_of::join<data::result_of::make<DS1>,mpl::identity<DS2> >
+>::type
+operator+( DS1 const& ds1, DS2 const& ds2 )
+{
+ return data::make(ds1) + ds2;
+}
+
+#endif
+
+
+} // namespace monomorphic
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_JOIN_HPP_112711GER
+
diff --git a/boost/test/data/monomorphic/singleton.hpp b/boost/test/data/monomorphic/singleton.hpp
new file mode 100644
index 0000000000..4d305c2546
--- /dev/null
+++ b/boost/test/data/monomorphic/singleton.hpp
@@ -0,0 +1,137 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+/// @file
+/// Defines single element monomorphic dataset
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_SINGLETON_HPP_102211GER
+#define BOOST_TEST_DATA_MONOMORPHIC_SINGLETON_HPP_102211GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+#include <boost/test/data/monomorphic/dataset.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+namespace monomorphic {
+
+// ************************************************************************** //
+// ************** singleton ************** //
+// ************************************************************************** //
+
+/// Models a single element data set
+template<typename T>
+class singleton : public monomorphic::dataset<typename boost::decay<T>::type> {
+ typedef monomorphic::dataset<typename boost::decay<T>::type> base;
+ typedef typename base::iter_ptr iter_ptr;
+
+ struct iterator : public base::iterator {
+ // Constructor
+ explicit iterator( singleton<T> const& owner )
+ : m_owner( owner )
+ {}
+
+ // forward iterator interface
+ virtual typename base::data_type const&
+ operator*() { return m_owner.value(); }
+ virtual void operator++() {}
+
+ private:
+ singleton<T> const& m_owner;
+ };
+
+public:
+ enum { arity = 1 };
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ //! Constructor
+ explicit singleton( T&& value ) : m_value( std::forward<T>( value ) ) {}
+
+ //! Move constructor
+ singleton( singleton&& s ) : m_value( std::forward<T>( s.m_value ) ) {}
+#else
+ // Constructor
+ explicit singleton( T const& value ) : m_value( value ) {}
+#endif
+
+ // Access methods
+ T const& value() const { return m_value; }
+
+ // dataset interface
+ virtual data::size_t size() const { return 1; }
+ virtual iter_ptr begin() const { return boost::make_shared<iterator>( *this ); }
+
+private:
+ // Data members
+ T m_value;
+};
+
+// a singleton is a dataset
+template<typename T>
+struct is_dataset<singleton<T> > : mpl::true_ {};
+
+} // namespace monomorphic
+
+
+
+/// @overload boost::unit_test::data::make()
+template<typename T>
+inline typename BOOST_TEST_ENABLE_IF<!is_forward_iterable<T>::value &&
+ !monomorphic::is_dataset<T>::value &&
+ !boost::is_array< typename boost::remove_reference<T>::type >::value,
+ monomorphic::singleton<T>
+>::type
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+make( T&& v )
+{
+ return monomorphic::singleton<T>( std::forward<T>( v ) );
+}
+#else
+make( T const& v )
+{
+ return monomorphic::singleton<T>( v );
+}
+#endif
+
+
+/// @overload boost::unit_test::data::make
+inline monomorphic::singleton<char*> make( char* str )
+{
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ return monomorphic::singleton<char*>( std::move(str) );
+#else
+ return monomorphic::singleton<char*>( str );
+#endif
+}
+
+
+/// @overload boost::unit_test::data::make
+inline monomorphic::singleton<char const*> make( char const* str )
+{
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ return monomorphic::singleton<char const*>( std::move(str) );
+#else
+ return monomorphic::singleton<char const*>( str );
+#endif
+}
+
+
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_SINGLETON_HPP_102211GER
+
diff --git a/boost/test/data/monomorphic/zip.hpp b/boost/test/data/monomorphic/zip.hpp
new file mode 100644
index 0000000000..3ee91817a9
--- /dev/null
+++ b/boost/test/data/monomorphic/zip.hpp
@@ -0,0 +1,240 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+/// @file
+/// Defines monomorphic dataset based on zipping of 2 other monomorphic datasets
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_ZIP_HPP_102211GER
+#define BOOST_TEST_DATA_MONOMORPHIC_ZIP_HPP_102211GER
+
+#include <boost/test/data/config.hpp>
+
+#if !defined(BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE) || defined(BOOST_TEST_DOXYGEN_DOC__)
+
+// Boost.Test
+#include <boost/test/data/monomorphic/dataset.hpp>
+#include <boost/test/detail/suppress_warnings.hpp>
+
+
+namespace boost {
+namespace unit_test {
+namespace data {
+namespace monomorphic {
+
+namespace ds_detail {
+
+
+//____________________________________________________________________________//
+
+// !! ?? variadic template implementation; use forward_as_tuple?
+template<typename T1, typename T2>
+struct zip_traits {
+ typedef std::tuple<T1,T2> type;
+ typedef typename monomorphic::traits<type>::ref_type ref_type;
+
+ static ref_type
+ tuple_merge(T1 const& a1, T2 const& a2)
+ {
+ return ref_type(a1,a2);
+ }
+};
+
+//____________________________________________________________________________//
+
+template<typename T1, typename T2,typename T3>
+struct zip_traits<T1,std::tuple<T2,T3>> {
+ typedef std::tuple<T1,T2,T3> type;
+ typedef typename monomorphic::traits<type>::ref_type ref_type;
+
+ static ref_type
+ tuple_merge(T1 const& a1, std::tuple<T2 const&,T3 const&> const& a2)
+ {
+ return ref_type(a1,std::get<0>(a2),std::get<1>(a2));
+ }
+};
+
+//____________________________________________________________________________//
+
+template<typename T1, typename T2,typename T3>
+struct zip_traits<std::tuple<T1,T2>,T3> {
+ typedef std::tuple<T1,T2,T3> type;
+ typedef typename monomorphic::traits<type>::ref_type ref_type;
+
+ static ref_type
+ tuple_merge(std::tuple<T1 const&,T2 const&> const& a1, T3 const& a2)
+ {
+ return ref_type(std::get<0>(a1),std::get<1>(a1),a2);
+ }
+};
+
+//____________________________________________________________________________//
+
+} // namespace ds_detail
+
+// ************************************************************************** //
+// ************** zip ************** //
+// ************************************************************************** //
+
+//! Zip datasets
+//!
+//! A zip of two datasets is a dataset whose arity is the sum of the operand datasets arity. The size is given by
+//! the function creating the instance (see @c operator^ on datasets).
+template<typename DS1, typename DS2>
+class zip : public monomorphic::dataset<typename ds_detail::zip_traits<typename boost::decay<DS1>::type::data_type,
+ typename boost::decay<DS2>::type::data_type>::type> {
+ typedef typename boost::decay<DS1>::type::data_type T1;
+ typedef typename boost::decay<DS2>::type::data_type T2;
+
+ typedef typename monomorphic::dataset<T1>::iter_ptr ds1_iter_ptr;
+ typedef typename monomorphic::dataset<T2>::iter_ptr ds2_iter_ptr;
+
+ typedef typename ds_detail::zip_traits<T1,T2>::type T;
+ typedef monomorphic::dataset<T> base;
+ typedef typename base::iter_ptr iter_ptr;
+
+ struct iterator : public base::iterator {
+ typedef typename monomorphic::traits<T>::ref_type ref_type;
+
+ // Constructor
+ explicit iterator( ds1_iter_ptr iter1, ds2_iter_ptr iter2 )
+ : m_iter1( iter1 )
+ , m_iter2( iter2 )
+ {}
+
+ // forward iterator interface
+ virtual ref_type operator*() { return ds_detail::zip_traits<T1,T2>::tuple_merge( **m_iter1, **m_iter2 ); }
+ virtual void operator++() { ++(*m_iter1); ++(*m_iter2); }
+
+ private:
+ // Data members
+ ds1_iter_ptr m_iter1;
+ ds2_iter_ptr m_iter2;
+ };
+
+public:
+ enum { arity = boost::decay<DS1>::type::arity + boost::decay<DS2>::type::arity };
+
+ //! Constructor
+ //!
+ //! The datasets are moved and not copied.
+ zip( DS1&& ds1, DS2&& ds2, data::size_t size )
+ : m_ds1( std::forward<DS1>( ds1 ) )
+ , m_ds2( std::forward<DS2>( ds2 ) )
+ , m_size( size )
+ {}
+
+ //! Move constructor
+ zip( zip&& j )
+ : m_ds1( std::forward<DS1>( j.m_ds1 ) )
+ , m_ds2( std::forward<DS2>( j.m_ds2 ) )
+ , m_size( j.m_size )
+ {}
+
+ // dataset interface
+ virtual data::size_t size() const { return m_size; }
+ virtual iter_ptr begin() const { return boost::make_shared<iterator>( m_ds1.begin(), m_ds2.begin() ); }
+
+private:
+ // Data members
+ DS1 m_ds1;
+ DS2 m_ds2;
+ data::size_t m_size;
+};
+
+//____________________________________________________________________________//
+
+//! Zipped datasets results in a dataset.
+template<typename DS1, typename DS2>
+struct is_dataset<zip<DS1,DS2> > : mpl::true_ {};
+
+//____________________________________________________________________________//
+
+namespace ds_detail {
+
+//! Handles the sise of the resulting zipped dataset.
+template<typename DS1, typename DS2>
+inline data::size_t
+zip_size( DS1&& ds1, DS2&& ds2 )
+{
+ data::size_t ds1_size = ds1.size();
+ data::size_t ds2_size = ds2.size();
+
+ if( ds1_size == ds2_size )
+ return ds1_size;
+
+ if( ds1_size == 1 || ds1_size.is_inf() )
+ return ds2_size;
+
+ if( ds2_size == 1 || ds2_size.is_inf() )
+ return ds1_size;
+
+ BOOST_TEST_DS_ERROR( "Can't zip datasets of different sizes" );
+}
+
+} // namespace ds_detail
+
+//____________________________________________________________________________//
+
+namespace result_of {
+
+//! Result type of the zip operator.
+template<typename DS1Gen, typename DS2Gen>
+struct zip {
+ typedef monomorphic::zip<typename DS1Gen::type,typename DS2Gen::type> type;
+};
+
+} // namespace result_of
+
+
+//____________________________________________________________________________//
+
+
+//! Overload operator for zip support
+template<typename DS1, typename DS2>
+inline typename boost::lazy_enable_if_c<is_dataset<DS1>::value && is_dataset<DS2>::value,
+ result_of::zip<mpl::identity<DS1>,mpl::identity<DS2>>
+>::type
+operator^( DS1&& ds1, DS2&& ds2 )
+{
+ return zip<DS1,DS2>( std::forward<DS1>( ds1 ), std::forward<DS2>( ds2 ), ds_detail::zip_size( ds1, ds2 ) );
+}
+
+//! @overload boost::unit_test::data::monomorphic::operator^()
+template<typename DS1, typename DS2>
+inline typename boost::lazy_enable_if_c<is_dataset<DS1>::value && !is_dataset<DS2>::value,
+ result_of::zip<mpl::identity<DS1>,data::result_of::make<DS2>>
+>::type
+operator^( DS1&& ds1, DS2&& ds2 )
+{
+ return std::forward<DS1>(ds1) ^ data::make(std::forward<DS2>(ds2));
+}
+
+//! @overload boost::unit_test::data::monomorphic::operator^()
+template<typename DS1, typename DS2>
+inline typename boost::lazy_enable_if_c<!is_dataset<DS1>::value && is_dataset<DS2>::value,
+ result_of::zip<data::result_of::make<DS1>,mpl::identity<DS2>>
+>::type
+operator^( DS1&& ds1, DS2&& ds2 )
+{
+ return data::make(std::forward<DS1>(ds1)) ^ std::forward<DS2>(ds2);
+}
+
+//____________________________________________________________________________//
+
+} // namespace monomorphic
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_ZIP_HPP_102211GER
+
diff --git a/boost/test/data/size.hpp b/boost/test/data/size.hpp
new file mode 100644
index 0000000000..ddd725d26c
--- /dev/null
+++ b/boost/test/data/size.hpp
@@ -0,0 +1,145 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+//!@file
+//!@brief simple dataset size abstraction (can be infinite)
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_SIZE_HPP_102211GER
+#define BOOST_TEST_DATA_SIZE_HPP_102211GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+
+// STL
+#include <iosfwd>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+
+// ************************************************************************** //
+// ************** size_t ************** //
+// ************************************************************************** //
+
+//! Utility for handling the size of a datasets
+class size_t {
+ struct dummy { void nonnull() {} };
+ typedef void (dummy::*safe_bool)();
+public:
+ // Constructors
+ size_t( std::size_t s = 0 ) : m_value( s ), m_infinity( false ) {}
+ explicit size_t( bool ) : m_value( 0 ), m_infinity( true ) {}
+ template<typename T>
+ size_t( T v ) : m_value( static_cast<std::size_t>(v) ), m_infinity( false ) {}
+
+ // Access methods
+ std::size_t value() const { return m_value; }
+ bool is_inf() const { return m_infinity; }
+ operator safe_bool() const { return is_inf() || m_value != 0 ? &dummy::nonnull : 0; }
+
+ // Unary operators
+ data::size_t operator--() { if( !is_inf() ) m_value--; return *this; }
+ data::size_t operator--(int) { data::size_t res(*this); if( !is_inf() ) m_value--; return res; }
+ data::size_t operator++() { if( !is_inf() ) m_value++; return *this; }
+ data::size_t operator++(int) { data::size_t res(*this); if( !is_inf() ) m_value++; return res; }
+
+ // Binary operators
+ data::size_t& operator+=( std::size_t rhs ) { if( !is_inf() ) m_value += rhs; return *this; }
+ data::size_t& operator+=( data::size_t rhs )
+ {
+ if( !is_inf() ) {
+ if( rhs.is_inf() )
+ *this = rhs;
+ else
+ m_value += rhs.value();
+ }
+ return *this;
+ }
+ data::size_t& operator-=( std::size_t rhs ) { if( !is_inf() ) m_value -= rhs; return *this; }
+ data::size_t& operator-=( data::size_t rhs )
+ {
+ if( !is_inf() ) {
+ if( value() < rhs.value() )
+ m_value = 0;
+ else
+ m_value -= rhs.value();
+ }
+ return *this;
+ }
+
+private:
+ // Data members
+ std::size_t m_value;
+ bool m_infinity;
+};
+
+namespace { const data::size_t BOOST_TEST_DS_INFINITE_SIZE( true ); }
+
+//____________________________________________________________________________//
+
+// Binary operators
+inline bool operator>(data::size_t lhs, std::size_t rhs) { return lhs.is_inf() || (lhs.value() > rhs); }
+inline bool operator>(std::size_t lhs, data::size_t rhs) { return !rhs.is_inf() && (lhs > rhs.value()); }
+inline bool operator>(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() ? lhs.is_inf() : lhs.value() > rhs.value(); }
+
+inline bool operator>=(data::size_t lhs, std::size_t rhs ) { return lhs.is_inf() || (lhs.value() >= rhs); }
+inline bool operator>=(std::size_t lhs, data::size_t rhs) { return !rhs.is_inf() && (lhs >= rhs.value()); }
+inline bool operator>=(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() ? lhs.is_inf() : lhs.value() >= rhs.value(); }
+
+inline bool operator<(data::size_t lhs, std::size_t rhs) { return !lhs.is_inf() && (lhs.value() < rhs); }
+inline bool operator<(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() || (lhs < rhs.value()); }
+inline bool operator<(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() ? rhs.is_inf() : lhs.value() < rhs.value(); }
+
+inline bool operator<=(data::size_t lhs, std::size_t rhs) { return !lhs.is_inf() && (lhs.value() <= rhs); }
+inline bool operator<=(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() || (lhs <= rhs.value()); }
+inline bool operator<=(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() ? rhs.is_inf() : lhs.value() <= rhs.value(); }
+
+inline bool operator==(data::size_t lhs, std::size_t rhs) { return !lhs.is_inf() && (lhs.value() == rhs); }
+inline bool operator==(std::size_t lhs, data::size_t rhs) { return !rhs.is_inf() && (lhs == rhs.value()); }
+inline bool operator==(data::size_t lhs, data::size_t rhs) { return !(lhs.is_inf() ^ rhs.is_inf()) && lhs.value() == rhs.value(); }
+
+inline bool operator!=(data::size_t lhs, std::size_t rhs) { return lhs.is_inf() || (lhs.value() != rhs); }
+inline bool operator!=(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() || (lhs != rhs.value()); }
+inline bool operator!=(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() || lhs.value() != rhs.value(); }
+
+inline data::size_t operator+(data::size_t lhs, std::size_t rhs) { return lhs.is_inf() ? lhs : data::size_t( lhs.value()+rhs ); }
+inline data::size_t operator+(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() ? rhs : data::size_t( lhs+rhs.value() ); }
+inline data::size_t operator+(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() || rhs.is_inf() ? data::size_t(true) : data::size_t( lhs.value()+rhs.value() ); }
+
+inline data::size_t operator*(data::size_t lhs, std::size_t rhs) { return lhs.is_inf() ? lhs : data::size_t( lhs.value()*rhs ); }
+inline data::size_t operator*(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() ? rhs : data::size_t( lhs*rhs.value() ); }
+inline data::size_t operator*(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() || rhs.is_inf() ? data::size_t(true) : data::size_t( lhs.value()*rhs.value() ); }
+
+//____________________________________________________________________________//
+
+template<typename CharT1, typename Tr>
+inline std::basic_ostream<CharT1,Tr>&
+operator<<( std::basic_ostream<CharT1,Tr>& os, data::size_t const& s )
+{
+ if( s.is_inf() )
+ os << "infinity";
+ else
+ os << s.value();
+
+ return os;
+}
+
+//____________________________________________________________________________//
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_SIZE_HPP_102211GER
+
diff --git a/boost/test/data/test_case.hpp b/boost/test/data/test_case.hpp
new file mode 100644
index 0000000000..31a61d92ec
--- /dev/null
+++ b/boost/test/data/test_case.hpp
@@ -0,0 +1,195 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+//!@file
+//!@brief test case family based on data generator
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
+#define BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+#include <boost/test/data/dataset.hpp>
+
+// Boost
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
+#include <boost/preprocessor/variadic/to_seq.hpp>
+#include <boost/preprocessor/variadic/size.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/seq/for_each_i.hpp>
+#include <boost/preprocessor/seq/for_each.hpp>
+#include <boost/preprocessor/seq/enum.hpp>
+#include <boost/preprocessor/control/iif.hpp>
+#include <boost/preprocessor/comparison/equal.hpp>
+
+#include <boost/bind.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+#include <boost/test/tools/detail/print_helper.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+
+// ************************************************************************** //
+// ************** test_case_template ************** //
+// ************************************************************************** //
+
+namespace ds_detail {
+
+template<typename TestCase,typename DataSet>
+class test_case_gen : public test_unit_generator {
+public:
+ // Constructor
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet&& ds )
+ : m_tc_name( ut_detail::normalize_test_case_name( tc_name ) )
+ {
+ data::for_each_sample( std::forward<DataSet>( ds ), *this );
+ }
+ test_case_gen( test_case_gen&& gen )
+ : m_tc_name( gen.m_tc_name )
+ , m_test_cases( std::move(gen.m_test_cases) )
+ {}
+#else
+ test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet const& ds )
+ : m_tc_name( ut_detail::normalize_test_case_name( tc_name ) )
+ {
+ data::for_each_sample( ds, *this );
+ }
+#endif
+
+ virtual test_unit* next() const
+ {
+ if( m_test_cases.empty() )
+ return 0;
+
+ test_unit* res = m_test_cases.front();
+ m_test_cases.pop_front();
+
+ return res;
+ }
+
+ // !! ?? variadics based implementation
+#define TC_MAKE(z,arity,_) \
+ template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
+ void operator()( BOOST_PP_ENUM_BINARY_PARAMS(arity, Arg, const& arg) ) const \
+ { \
+ m_test_cases.push_back( new test_case( m_tc_name, m_tc_file, m_tc_line, \
+ boost::bind( &TestCase::template test_method<BOOST_PP_ENUM_PARAMS(arity,Arg)>, \
+ BOOST_PP_ENUM_PARAMS(arity, arg) ) ) ); \
+ } \
+
+ BOOST_PP_REPEAT_FROM_TO(1, 4, TC_MAKE, _)
+
+private:
+ // Data members
+ std::string m_tc_name;
+ const_string m_tc_file;
+ std::size_t m_tc_line;
+ mutable std::list<test_unit*> m_test_cases;
+};
+
+//____________________________________________________________________________//
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+template<typename TestCase,typename DataSet>
+test_case_gen<TestCase,DataSet>
+make_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet&& ds )
+{
+ return test_case_gen<TestCase,DataSet>( tc_name, tc_file, tc_line, std::forward<DataSet>(ds) );
+}
+#else
+template<typename TestCase,typename DataSet>
+test_case_gen<TestCase,DataSet>
+make_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet const& ds )
+{
+ return test_case_gen<TestCase,DataSet>( tc_name, tc_file, tc_line, ds );
+}
+#endif
+
+//____________________________________________________________________________//
+
+} // namespace ds_detail
+
+// ************************************************************************** //
+// ************** BOOST_DATA_TEST_CASE ************** //
+// ************************************************************************** //
+
+#define BOOST_DATA_TEST_CASE_PARAM(r, _, i, param) (BOOST_PP_CAT(Arg, i) const& param)
+#define BOOST_DATA_TEST_CONTEXT(r, _, param) << BOOST_STRINGIZE(param) << " = " << boost::test_tools::tt_detail::print_helper(param) << "; "
+
+#define BOOST_DATA_TEST_CASE_PARAMS( params ) \
+ BOOST_PP_SEQ_ENUM( \
+ BOOST_PP_SEQ_FOR_EACH_I(BOOST_DATA_TEST_CASE_PARAM, _, params)) \
+/**/
+
+#define BOOST_DATA_TEST_CASE_IMPL( arity, test_name, dataset, params ) \
+struct test_name { \
+ template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
+ static void test_method( BOOST_DATA_TEST_CASE_PARAMS( params ) ) \
+ { \
+ BOOST_TEST_CONTEXT( "" \
+ BOOST_PP_SEQ_FOR_EACH(BOOST_DATA_TEST_CONTEXT, _, params)) \
+ _impl(BOOST_PP_SEQ_ENUM(params)); \
+ } \
+private: \
+ template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
+ static void _impl(BOOST_DATA_TEST_CASE_PARAMS( params )); \
+}; \
+ \
+BOOST_AUTO_TU_REGISTRAR( test_name )( \
+ boost::unit_test::data::ds_detail::make_test_case_gen<test_name>( \
+ BOOST_STRINGIZE( test_name ), \
+ __FILE__, __LINE__, \
+ boost::unit_test::data::make(dataset) ), \
+ boost::unit_test::decorator::collector::instance() ); \
+ \
+ template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
+ void test_name::_impl( BOOST_DATA_TEST_CASE_PARAMS( params ) ) \
+/**/
+
+#define BOOST_DATA_TEST_CASE_WITH_PARAMS( test_name, dataset, ... ) \
+ BOOST_DATA_TEST_CASE_IMPL( BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
+ test_name, dataset, \
+ BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) ) \
+/**/
+#define BOOST_DATA_TEST_CASE_NO_PARAMS( test_name, dataset ) \
+ BOOST_DATA_TEST_CASE_WITH_PARAMS( test_name, dataset, sample ) \
+/**/
+
+#if BOOST_PP_VARIADICS_MSVC
+
+#define BOOST_DATA_TEST_CASE( ... ) \
+ BOOST_PP_CAT( \
+ BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \
+ BOOST_DATA_TEST_CASE_NO_PARAMS, \
+ BOOST_DATA_TEST_CASE_WITH_PARAMS) (__VA_ARGS__), ) \
+/**/
+#else
+
+#define BOOST_DATA_TEST_CASE( ... ) \
+ BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \
+ BOOST_DATA_TEST_CASE_NO_PARAMS, \
+ BOOST_DATA_TEST_CASE_WITH_PARAMS) (__VA_ARGS__) \
+/**/
+#endif
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
+
diff --git a/boost/test/debug.hpp b/boost/test/debug.hpp
index 1c45bc7e6e..2d367167ae 100644
--- a/boost/test/debug.hpp
+++ b/boost/test/debug.hpp
@@ -1,15 +1,14 @@
-// (C) Copyright Gennadiy Rozental 2006-2008.
+// (C) Copyright Gennadiy Rozental 2006-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : defines portable debug interfaces
+//! @file
+//! @brief defines portable debug interfaces
+//!
+//! Intended to standardize interface of programs with debuggers
// ***************************************************************************
#ifndef BOOST_TEST_DEBUG_API_HPP_112006GER
@@ -17,9 +16,11 @@
// Boost.Test
#include <boost/test/detail/config.hpp>
-#include <boost/test/utils/callback.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
+// Boost
+#include <boost/function/function1.hpp>
+
// STL
#include <string>
@@ -28,71 +29,107 @@
//____________________________________________________________________________//
namespace boost {
-
+/// Contains debugger and debug C Runtime interfaces
namespace debug {
+/// @defgroup DebuggerInterface Debugger and debug C Runtime portable interfaces
+/// @{
+/// These interfaces are intended to be used by application to:
+/// - check if we are running under debugger
+/// - attach the debugger to itself
+///
+/// Unfortunately these actions differ widely between different debuggers available in a field. These interface present generalized standard form of
+/// performing these actions. Implementation depends a lot on the environment application is running in and thus there are several custom implementations
+/// supported by the Boost.Test
+///
+/// In addition here you find interfaces for memory leaks detection and reporting.
+///
+/// All these interfaces are defined in namespace boost::debug
+
// ************************************************************************** //
-// ************** check if program is running under debugger ************** //
-// ************************************************************************** //
+/// Checks if programs runs under debugger
+/// @returns true if current process is under debugger. False otherwise
+// ************************************************************************** //
bool BOOST_TEST_DECL under_debugger();
// ************************************************************************** //
-// ************** cause program to break execution ************** //
-// ************** in debugger at call point ************** //
+/// Cause program to break execution in debugger at call point
// ************************************************************************** //
void BOOST_TEST_DECL debugger_break();
// ************************************************************************** //
-// ************** gui debugger setup ************** //
+/// Collection of data, which is used by debugger starter routine
// ************************************************************************** //
struct dbg_startup_info {
- long pid;
- bool break_or_continue;
- unit_test::const_string binary_path;
- unit_test::const_string display;
- unit_test::const_string init_done_lock;
+ long pid; ///< pid of a program to attach to
+ bool break_or_continue; ///< what to do after debugger is attached
+ unit_test::const_string binary_path; ///< path to executable for current process
+ unit_test::const_string display; ///< if debugger has a GUI, which display to use (on UNIX)
+ unit_test::const_string init_done_lock; ///< path to a uniquely named lock file, which is used to pause current application while debugger is being initialized
};
-typedef unit_test::callback1<dbg_startup_info const&> dbg_starter;
+/// Signature of debugger starter routine. Takes an instance of dbg_startup_into as only argument
+typedef boost::function<void (dbg_startup_info const&)> dbg_starter;
// ************************************************************************** //
-// ************** debugger setup ************** //
-// ************************************************************************** //
-
-#if BOOST_WORKAROUND( BOOST_MSVC, <1300)
-
-std::string BOOST_TEST_DECL set_debugger( unit_test::const_string dbg_id );
-
-#else
-
+/// Specifies which debugger to use when attaching and optionally what routine to use to start that debugger
+
+/// There are many different debuggers available for different platforms. Some of them also can be used in a different setups/configuratins.
+/// For example, gdb can be used in plain text mode, inside ddd, inside (x)emacs or in a separate xterm window.
+/// Boost.Test identifies each configuration with unique string.
+/// Also different debuggers configurations require different routines which is specifically tailored to start that debugger configuration.
+/// Boost.Test comes with set of predefined configuration names and corresponding routines for these configurations:
+/// - TODO
+///
+/// You can use this routine to select which one of the predefined debugger configurations to use in which case you do not need to provide starter
+/// routine (the one provided by Boost.Test will be used). You can also use this routine to select your own debugger by providing unique configuration
+/// id and starter routine for this configuration.
+///
+/// @param[in] dbg_id Unique id for debugger configuration (for example, gdb)
+/// @param[in] s Optional starter routine for selected configuration (use only you want to define your own configuration)
+/// @returns Id of previously selected debugger configuration
std::string BOOST_TEST_DECL set_debugger( unit_test::const_string dbg_id, dbg_starter s = dbg_starter() );
-#endif
-
-
// ************************************************************************** //
-// ************** attach debugger to the current process ************** //
+/// Attaches debugger to the current process
+
+/// Using currently selected debugger, this routine attempts to attach the debugger to this process.
+/// @param[in] break_or_continue tells what we wan to do after the debugger is attached. If true - process execution breaks
+/// in the point in invocation of this function. Otherwise execution continues, but now it is
+/// under the debugger
+/// @returns true if debugger successfully attached. False otherwise
// ************************************************************************** //
bool BOOST_TEST_DECL attach_debugger( bool break_or_continue = true );
// ************************************************************************** //
-// ************** switch on/off detect memory leaks feature ************** //
+/// Switches on/off memory leaks detection
+
+/// On platforms where memory leak detection is possible inside of running application (at the moment this is only Windows family) you can
+/// switch this feature on and off using this interface. In addition you can specify the name of the file to write a report into. Otherwise
+/// the report is going to be generated in standard error stream.
+/// @param[in] on_off boolean switch
+/// @param[in] report_file file, where the report should be directed to
// ************************************************************************** //
-void BOOST_TEST_DECL detect_memory_leaks( bool on_off );
+void BOOST_TEST_DECL detect_memory_leaks( bool on_off, unit_test::const_string report_file = unit_test::const_string() );
// ************************************************************************** //
-// ************** cause program to break execution in ************** //
-// ************** debugger at specific allocation point ************** //
+/// Causes program to break execution in debugger at specific allocation point
+
+/// On some platforms/memory managers (at the moment only on Windows/Visual Studio) one can tell a C Runtime to break
+/// on specific memory allocation. This can be used in combination with memory leak detection (which reports leaked memory
+/// allocation number) to locate the place where leak initiated.
+/// @param[in] mem_alloc_order_num Specific memory allocation number
// ************************************************************************** //
void BOOST_TEST_DECL break_memory_alloc( long mem_alloc_order_num );
} // namespace debug
+/// @}
} // namespace boost
diff --git a/boost/test/debug_config.hpp b/boost/test/debug_config.hpp
index 17f41a60a7..63ceed5f1a 100644
--- a/boost/test/debug_config.hpp
+++ b/boost/test/debug_config.hpp
@@ -1,15 +1,15 @@
-// (C) Copyright Gennadiy Rozental 2006-2008.
+// (C) Copyright Gennadiy Rozental 2006-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : user's config for Boost.Test debugging support
+//! @file
+//! @brief user's config for Boost.Test debugging support
+//!
+//! This file is intended to be edited by end user to specify varios macros, which configure debugger interface
+//! Alterntively you can set these parameters in your own sources/makefiles
// ***************************************************************************
#ifndef BOOST_TEST_DEBUG_CONFIG_HPP_112006GER
diff --git a/boost/test/detail/config.hpp b/boost/test/detail/config.hpp
index 4b12f0399c..0e0c1f2d45 100644
--- a/boost/test/detail/config.hpp
+++ b/boost/test/detail/config.hpp
@@ -1,15 +1,12 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : as a central place for global configuration switches
+//!@file
+//!@brief a central place for global configuration switches
// ***************************************************************************
#ifndef BOOST_TEST_CONFIG_HPP_071894GER
@@ -19,6 +16,18 @@
#include <boost/config.hpp> // compilers workarounds
#include <boost/detail/workaround.hpp>
+#if defined(_WIN32) && !defined(BOOST_DISABLE_WIN32) && \
+ (!defined(__COMO__) && !defined(__MWERKS__) && !defined(__GNUC__) || \
+ BOOST_WORKAROUND(__MWERKS__, >= 0x3000))
+# define BOOST_SEH_BASED_SIGNAL_HANDLING
+#endif
+
+#if defined(__COMO__) && defined(_MSC_VER)
+// eh.h uses type_info without declaring it.
+class type_info;
+# define BOOST_SEH_BASED_SIGNAL_HANDLING
+#endif
+
//____________________________________________________________________________//
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)) || \
@@ -37,9 +46,7 @@
//____________________________________________________________________________//
-#if !defined(BOOST_NO_STD_LOCALE) && \
- !BOOST_WORKAROUND(BOOST_MSVC, < 1310) && \
- !defined(__MWERKS__)
+#if !defined(BOOST_NO_STD_LOCALE) && !defined(__MWERKS__)
# define BOOST_TEST_USE_STD_LOCALE 1
#endif
@@ -65,10 +72,8 @@
//____________________________________________________________________________//
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
- !BOOST_WORKAROUND(BOOST_MSVC, <1310) && \
- !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x530))
-# define BOOST_TEST_SUPPORT_INTERACTION_TESTING 1
+#if !defined(__BORLANDC__) && !BOOST_WORKAROUND( __SUNPRO_CC, < 0x5100 )
+#define BOOST_TEST_SUPPORT_TOKEN_ITERATOR 1
#endif
//____________________________________________________________________________//
@@ -101,4 +106,10 @@
#define BOOST_TEST_MAIN BOOST_TEST_MODULE
#endif
+#ifdef __PGI
+#define BOOST_PP_VARIADICS 1
+#endif
+
+
+
#endif // BOOST_TEST_CONFIG_HPP_071894GER
diff --git a/boost/test/detail/enable_warnings.hpp b/boost/test/detail/enable_warnings.hpp
index 7c11ba2355..13fd01f445 100644
--- a/boost/test/detail/enable_warnings.hpp
+++ b/boost/test/detail/enable_warnings.hpp
@@ -1,22 +1,19 @@
-// (C) Copyright Gennadiy Rozental 2004-2008.
+// (C) Copyright Gennadiy Rozental 2004-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : enable previosly suppressed warnings
+//!@file
+//!@brief enable previously suppressed warnings
// ***************************************************************************
#ifdef BOOST_MSVC
# pragma warning(default: 4511) // copy constructor can't not be generated
# pragma warning(default: 4512) // assignment operator can't not be generated
-# pragma warning(default: 4100) // unreferenced formal parameter
-# pragma warning(default: 4996) // <symbol> was declared deprecated
+# pragma warning(default: 4100) // unreferenced formal parameter
+# pragma warning(default: 4996) // <symbol> was declared deprecated
# pragma warning(default: 4355) // 'this' : used in base member initializer list
# pragma warning(default: 4706) // assignment within conditional expression
# pragma warning(default: 4251) // class 'A<T>' needs to have dll-interface to be used by clients of class 'B'
@@ -28,3 +25,7 @@
# pragma warning(default: 4511) // 'class' : copy constructor could not be generated
# pragma warning(pop)
#endif
+
+#ifdef BOOST_CLANG
+#pragma clang diagnostic pop
+#endif
diff --git a/boost/test/detail/fwd_decl.hpp b/boost/test/detail/fwd_decl.hpp
index bde272a169..5f4110b096 100644
--- a/boost/test/detail/fwd_decl.hpp
+++ b/boost/test/detail/fwd_decl.hpp
@@ -1,15 +1,12 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : contains forward eclarations for Boost.Test data types
+//!@file
+//!@brief contains forward eclarations for Boost.Test data types
// ***************************************************************************
#ifndef BOOST_TEST_FWD_DECL_HPP_011605GER
diff --git a/boost/test/detail/global_typedef.hpp b/boost/test/detail/global_typedef.hpp
index ad66f984fe..0c71479a23 100644
--- a/boost/test/detail/global_typedef.hpp
+++ b/boost/test/detail/global_typedef.hpp
@@ -1,31 +1,36 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : some trivial global typedefs
+//!@file
+//!@brief some trivial global typedefs
// ***************************************************************************
#ifndef BOOST_TEST_GLOBAL_TYPEDEF_HPP_021005GER
#define BOOST_TEST_GLOBAL_TYPEDEF_HPP_021005GER
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
-#define BOOST_TEST_L( s ) boost::unit_test::const_string( s, sizeof( s ) - 1 )
+#include <boost/test/detail/workaround.hpp>
+
+#define BOOST_TEST_L( s ) ::boost::unit_test::const_string( s, sizeof( s ) - 1 )
#define BOOST_TEST_STRINGIZE( s ) BOOST_TEST_L( BOOST_STRINGIZE( s ) )
#define BOOST_TEST_EMPTY_STRING BOOST_TEST_L( "" )
+#define BOOST_TEST_SCOPE_SETCOLOR( os, attr, color ) \
+ scope_setcolor const& sc = runtime_config::color_output() \
+ ? scope_setcolor( os, attr, color ) \
+ : scope_setcolor(); \
+ ut_detail::ignore_unused_variable_warning( sc ) \
+/**/
+
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
typedef unsigned long counter_t;
@@ -36,11 +41,19 @@ enum report_level { INV_REPORT_LEVEL, CONFIRMATION_REPORT, SHORT_REPORT, DETAIL
//____________________________________________________________________________//
-enum output_format { INV_OF, CLF /* compiler log format */, XML /* XML */ };
+enum output_format { OF_INVALID,
+ OF_CLF, ///< compiler log format
+ OF_XML, ///< XML format for report and log,
+ OF_DOT ///< dot format for output content
+};
//____________________________________________________________________________//
-enum test_unit_type { tut_case = 0x01, tut_suite = 0x10, tut_any = 0x11 };
+enum test_unit_type { TUT_CASE = 0x01, TUT_SUITE = 0x10, TUT_ANY = 0x11 };
+
+//____________________________________________________________________________//
+
+enum assertion_result { AR_FAILED, AR_PASSED, AR_TRIGGERED };
//____________________________________________________________________________//
@@ -59,26 +72,25 @@ namespace ut_detail {
inline test_unit_type
test_id_2_unit_type( test_unit_id id )
{
- return (id & 0xFFFF0000) != 0 ? tut_case : tut_suite;
+ return (id & 0xFFFF0000) != 0 ? TUT_CASE : TUT_SUITE;
}
//____________________________________________________________________________//
-// helper templates to prevent ODR violations
-template<class T>
-struct static_constant {
- static T value;
-};
+// helper templates to prevent ODR violations
+template<class T>
+struct static_constant {
+ static T value;
+};
-template<class T>
-T static_constant<T>::value;
+template<class T>
+T static_constant<T>::value;
-//____________________________________________________________________________//
+//____________________________________________________________________________//
} // namespace ut_detail
} // namespace unit_test
-
} // namespace boost
//____________________________________________________________________________//
diff --git a/boost/test/detail/log_level.hpp b/boost/test/detail/log_level.hpp
index 371c4b9d60..5975161773 100644
--- a/boost/test/detail/log_level.hpp
+++ b/boost/test/detail/log_level.hpp
@@ -1,15 +1,12 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : shared definition for unit test log levels
+//!@file
+//!@brief shared definition for unit test log levels
// ***************************************************************************
#ifndef BOOST_TEST_LOG_LEVEL_HPP_011605GER
diff --git a/boost/test/detail/pp_variadic.hpp b/boost/test/detail/pp_variadic.hpp
new file mode 100644
index 0000000000..3d31cd1705
--- /dev/null
+++ b/boost/test/detail/pp_variadic.hpp
@@ -0,0 +1,49 @@
+// (C) Copyright Gennadiy Rozental 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/test for the library home page.
+//
+//!@file
+//!@brief few helpers for working with variadic macros
+// ***************************************************************************
+
+#ifndef BOOST_TEST_PP_VARIADIC_HPP_021515GER
+#define BOOST_TEST_PP_VARIADIC_HPP_021515GER
+
+// Boost
+#include <boost/preprocessor/control/iif.hpp>
+#include <boost/preprocessor/comparison/equal.hpp>
+#include <boost/preprocessor/variadic/size.hpp>
+
+//____________________________________________________________________________//
+
+#if BOOST_PP_VARIADICS
+
+#if BOOST_PP_VARIADICS_MSVC
+# define BOOST_TEST_INVOKE_VARIADIC( tool, ... ) BOOST_PP_CAT( tool (__VA_ARGS__), )
+#else
+# define BOOST_TEST_INVOKE_VARIADIC( tool, ... ) tool (__VA_ARGS__)
+#endif
+
+//____________________________________________________________________________//
+
+/// if sizeof(__VA_ARGS__) == N: F1(__VA_ARGS__)
+/// else: F2(__VA_ARGS__)
+#define BOOST_TEST_INVOKE_IF_N_ARGS( N, F1, F2, ... ) \
+ BOOST_TEST_INVOKE_VARIADIC( \
+ BOOST_PP_IIF( \
+ BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), N), \
+ F1, \
+ F2), \
+ __VA_ARGS__ ) \
+/**/
+
+//____________________________________________________________________________//
+
+#endif /* BOOST_PP_VARIADICS */
+
+#endif // BOOST_TEST_PP_VARIADIC_HPP_021515GER
+
+// EOF
diff --git a/boost/test/detail/suppress_warnings.hpp b/boost/test/detail/suppress_warnings.hpp
index d5c95266ed..f667d31242 100644
--- a/boost/test/detail/suppress_warnings.hpp
+++ b/boost/test/detail/suppress_warnings.hpp
@@ -1,23 +1,20 @@
-// (C) Copyright Gennadiy Rozental 2004-2008.
+// (C) Copyright Gennadiy Rozental 2004-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : suppress some warnings
+//!@file
+//!@brief suppress some warnings
// ***************************************************************************
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4511) // copy constructor can't not be generated
# pragma warning(disable: 4512) // assignment operator can't not be generated
-# pragma warning(disable: 4100) // unreferenced formal parameter
-# pragma warning(disable: 4996) // <symbol> was declared deprecated
+# pragma warning(disable: 4100) // unreferenced formal parameter
+# pragma warning(disable: 4996) // <symbol> was declared deprecated
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
# pragma warning(disable: 4706) // assignment within conditional expression
# pragma warning(disable: 4251) // class 'A<T>' needs to have dll-interface to be used by clients of class 'B'
@@ -29,3 +26,7 @@
# pragma warning(disable: 4511) // 'class' : copy constructor could not be generated
#endif
+#ifdef BOOST_CLANG
+#pragma clang diagnostic push
+//#pragma clang diagnostic ignored "-Wlogical-op-parentheses"
+#endif
diff --git a/boost/test/detail/throw_exception.hpp b/boost/test/detail/throw_exception.hpp
new file mode 100644
index 0000000000..b29b9c07dd
--- /dev/null
+++ b/boost/test/detail/throw_exception.hpp
@@ -0,0 +1,69 @@
+// (C) Copyright Gennadiy Rozental 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/test for the library home page.
+//
+//!@file
+//!@brief contains wrappers, which allows to build Boost.Test with no exception
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DETAIL_THROW_EXCEPTION_HPP
+#define BOOST_TEST_DETAIL_THROW_EXCEPTION_HPP
+
+// Boost
+#include <boost/config.hpp> // BOOST_NO_EXCEPTION
+
+#ifdef BOOST_NO_EXCEPTION
+// C RUNTIME
+#include <stdlib.h>
+
+#endif
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace ut_detail {
+
+#ifdef BOOST_NO_EXCEPTION
+
+template<typename E>
+inline int
+throw_exception(E const& e) { abort(); return 0; }
+
+#define BOOST_TEST_IMPL_TRY
+#define BOOST_TEST_IMPL_CATCH( T, var ) for(T const& var = *(T*)0; false;)
+#define BOOST_TEST_IMPL_CATCH0( T ) if(0)
+#define BOOST_TEST_IMPL_CATCHALL() if(0)
+#define BOOST_TEST_IMPL_RETHROW
+
+#else
+
+template<typename E>
+inline int
+throw_exception(E const& e) { throw e; return 0; }
+
+#define BOOST_TEST_IMPL_TRY try
+#define BOOST_TEST_IMPL_CATCH( T, var ) catch( T const& var )
+#define BOOST_TEST_IMPL_CATCH0( T ) catch( T const& )
+#define BOOST_TEST_IMPL_CATCHALL() catch(...)
+#define BOOST_TEST_IMPL_RETHROW throw
+#endif
+
+//____________________________________________________________________________//
+
+#define BOOST_TEST_IMPL_THROW( E ) unit_test::ut_detail::throw_exception( E )
+
+} // namespace ut_detail
+} // namespace unit_test
+} // namespace boost
+
+//____________________________________________________________________________//
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DETAIL_THROW_EXCEPTION_HPP
diff --git a/boost/test/detail/unit_test_parameters.hpp b/boost/test/detail/unit_test_parameters.hpp
deleted file mode 100644
index 740dc5d6fd..0000000000
--- a/boost/test/detail/unit_test_parameters.hpp
+++ /dev/null
@@ -1,69 +0,0 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
-// Distributed under the Boost 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/test for the library home page.
-//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : storage for unit test framework parameters information
-// ***************************************************************************
-
-#ifndef BOOST_TEST_UNIT_TEST_PARAMETERS_HPP_071894GER
-#define BOOST_TEST_UNIT_TEST_PARAMETERS_HPP_071894GER
-
-#include <boost/test/detail/global_typedef.hpp>
-#include <boost/test/detail/log_level.hpp>
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-// STL
-#include <iosfwd>
-
-//____________________________________________________________________________//
-
-namespace boost {
-
-namespace unit_test {
-
-// ************************************************************************** //
-// ************** runtime_config ************** //
-// ************************************************************************** //
-
-namespace runtime_config {
-
-BOOST_TEST_DECL void init( int& argc, char** argv );
-
-BOOST_TEST_DECL unit_test::log_level log_level();
-BOOST_TEST_DECL bool no_result_code();
-BOOST_TEST_DECL unit_test::report_level report_level();
-BOOST_TEST_DECL const_string test_to_run();
-BOOST_TEST_DECL const_string break_exec_path();
-BOOST_TEST_DECL bool save_pattern();
-BOOST_TEST_DECL bool show_build_info();
-BOOST_TEST_DECL bool show_progress();
-BOOST_TEST_DECL bool catch_sys_errors();
-BOOST_TEST_DECL bool auto_start_dbg();
-BOOST_TEST_DECL bool use_alt_stack();
-BOOST_TEST_DECL bool detect_fp_exceptions();
-BOOST_TEST_DECL output_format report_format();
-BOOST_TEST_DECL output_format log_format();
-BOOST_TEST_DECL std::ostream* report_sink();
-BOOST_TEST_DECL std::ostream* log_sink();
-BOOST_TEST_DECL long detect_memory_leaks();
-BOOST_TEST_DECL int random_seed();
-
-} // namespace runtime_config
-
-} // namespace unit_test
-
-} // namespace boost
-
-//____________________________________________________________________________//
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // BOOST_TEST_UNIT_TEST_PARAMETERS_HPP_071894GER
diff --git a/boost/test/detail/workaround.hpp b/boost/test/detail/workaround.hpp
index a7c50c2483..60a03eca61 100644
--- a/boost/test/detail/workaround.hpp
+++ b/boost/test/detail/workaround.hpp
@@ -1,15 +1,12 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : contains mics. workarounds
+//!@file
+//!@brief contains mics. workarounds
// ***************************************************************************
#ifndef BOOST_TEST_WORKAROUND_HPP_021005GER
@@ -26,15 +23,13 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
-
namespace ut_detail {
#ifdef BOOST_NO_STD_DISTANCE
template <class T>
std::ptrdiff_t distance( T const& x_, T const& y_ )
-{
+{
std::ptrdiff_t res = 0;
std::distance( x_, y_, res );
@@ -51,11 +46,7 @@ using std::distance;
template <class T> inline void ignore_unused_variable_warning(const T&) {}
} // namespace ut_detail
-
} // namespace unit_test
-
-namespace unit_test_framework = unit_test;
-
} // namespace boost
//____________________________________________________________________________//
diff --git a/boost/test/exception_safety.hpp b/boost/test/exception_safety.hpp
deleted file mode 100644
index e1e8d85ad1..0000000000
--- a/boost/test/exception_safety.hpp
+++ /dev/null
@@ -1,187 +0,0 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Distributed under the Boost 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/test for the library home page.
-//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : Facilities to perform exception safety tests
-// ***************************************************************************
-
-#ifndef BOOST_TEST_EXCEPTION_SAFETY_HPP_111705GER
-#define BOOST_TEST_EXCEPTION_SAFETY_HPP_111705GER
-
-// Boost.Test
-#include <boost/test/detail/config.hpp>
-
-#include <boost/test/utils/callback.hpp>
-#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
-
-// STL
-#include <memory>
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** BOOST_TEST_EXCEPTION_SAFETY ************** //
-// ************************************************************************** //
-
-#define BOOST_TEST_EXCEPTION_SAFETY( test_name ) \
-struct test_name : public BOOST_AUTO_TEST_CASE_FIXTURE \
-{ void test_method(); }; \
- \
-static void BOOST_AUTO_TC_INVOKER( test_name )() \
-{ \
- test_name t; \
- ::boost::itest::exception_safety( \
- boost::bind( &test_name::test_method, t ), \
- BOOST_STRINGIZE(test_name) ); \
-} \
- \
-struct BOOST_AUTO_TC_UNIQUE_ID( test_name ) {}; \
- \
-BOOST_AUTO_TU_REGISTRAR( test_name )( \
- boost::unit_test::make_test_case( \
- &BOOST_AUTO_TC_INVOKER( test_name ), #test_name ), \
- boost::unit_test::ut_detail::auto_tc_exp_fail< \
- BOOST_AUTO_TC_UNIQUE_ID( test_name )>::instance()->value() ); \
- \
-void test_name::test_method() \
-/**/
-
-namespace boost {
-
-namespace itest {
-
-// ************************************************************************** //
-// ************** exception safety test ************** //
-// ************************************************************************** //
-
-void BOOST_TEST_DECL exception_safety( unit_test::callback0<> const& F,
- unit_test::const_string test_name = "" );
-
-} // namespace itest
-
-} // namespace boost
-
-// ************************************************************************** //
-// ************** global operator new/delete overloads ************** //
-// ************************************************************************** //
-
-#ifndef BOOST_ITEST_NO_NEW_OVERLOADS
-
-#include <boost/test/interaction_based.hpp>
-
-# ifdef BOOST_NO_STDC_NAMESPACE
-namespace std { using ::isprint; using ::malloc; using ::free; }
-# endif
-
-inline void*
-operator new( std::size_t s ) throw(std::bad_alloc)
-{
- void* res = std::malloc(s ? s : 1);
-
- if( res )
- ::boost::itest::manager::instance().allocated( 0, 0, res, s );
- else
- throw std::bad_alloc();
-
- return res;
-}
-
-//____________________________________________________________________________//
-
-inline void*
-operator new( std::size_t s, std::nothrow_t const& ) throw()
-{
- void* res = std::malloc(s ? s : 1);
-
- if( res )
- ::boost::itest::manager::instance().allocated( 0, 0, res, s );
-
- return res;
-}
-
-//____________________________________________________________________________//
-
-inline void*
-operator new[]( std::size_t s ) throw(std::bad_alloc)
-{
- void* res = std::malloc(s ? s : 1);
-
- if( res )
- ::boost::itest::manager::instance().allocated( 0, 0, res, s );
- else
- throw std::bad_alloc();
-
- return res;
-}
-
-//____________________________________________________________________________//
-
-inline void*
-operator new[]( std::size_t s, std::nothrow_t const& ) throw()
-{
- void* res = std::malloc(s ? s : 1);
-
- if( res )
- ::boost::itest::manager::instance().allocated( 0, 0, res, s );
-
- return res;
-}
-
-//____________________________________________________________________________//
-
-inline void
-operator delete( void* p ) throw()
-{
- ::boost::itest::manager::instance().freed( p );
-
- std::free( p );
-}
-
-//____________________________________________________________________________//
-
-inline void
-operator delete( void* p, std::nothrow_t const& ) throw()
-{
- ::boost::itest::manager::instance().freed( p );
-
- std::free( p );
-}
-
-//____________________________________________________________________________//
-
-inline void
-operator delete[]( void* p ) throw()
-{
- ::boost::itest::manager::instance().freed( p );
-
- std::free( p );
-}
-
-//____________________________________________________________________________//
-
-inline void
-operator delete[]( void* p, std::nothrow_t const& ) throw()
-{
- ::boost::itest::manager::instance().freed( p );
-
- std::free( p );
-}
-
-//____________________________________________________________________________//
-
-#endif // BOOST_ITEST_NO_NEW_OVERLOADS
-
-//____________________________________________________________________________//
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // BOOST_TEST_EXCEPTION_SAFETY_HPP_111705GER
diff --git a/boost/test/execution_monitor.hpp b/boost/test/execution_monitor.hpp
index a1c2ee61c9..b01137da7b 100644
--- a/boost/test/execution_monitor.hpp
+++ b/boost/test/execution_monitor.hpp
@@ -1,32 +1,13 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// (C) Copyright Beman Dawes 2001.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : defines abstract monitor interfaces and implements execution exception
-// The original Boost Test Library included an implementation detail function
-// named catch_exceptions() which caught otherwise uncaught C++ exceptions.
-// It was derived from an existing test framework by Beman Dawes. The
-// intent was to expand later to catch other detectable but platform dependent
-// error events like Unix signals or Windows structured C exceptions.
-//
-// Requests from early adopters of the Boost Test Library included
-// configurable levels of error message detail, elimination of templates,
-// separation of error reporting, and making the catch_exceptions() facilities
-// available as a public interface. Support for unit testing also stretched
-// the function based design. Implementation within the header became less
-// attractive due to the need to include many huge system dependent headers,
-// although still preferable in certain cases.
-//
-// All those issues have been addressed by introducing the class-based
-// design presented here.
+//!@file
+//!@brief Defines public interface of the Execution Monitor and related classes
// ***************************************************************************
#ifndef BOOST_TEST_EXECUTION_MONITOR_HPP_071894GER
@@ -35,99 +16,257 @@
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/fwd_decl.hpp>
-#include <boost/test/utils/callback.hpp>
+#include <boost/test/detail/throw_exception.hpp>
+
#include <boost/test/utils/class_properties.hpp>
// Boost
-#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/type.hpp>
#include <boost/cstdlib.hpp>
+#include <boost/function/function0.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
+#ifdef BOOST_SEH_BASED_SIGNAL_HANDLING
+
+// for the FP constants and control routines
+#include <float.h>
+
+#ifndef EM_INVALID
+#define EM_INVALID _EM_INVALID
+#endif
+
+#ifndef EM_DENORMAL
+#define EM_DENORMAL _EM_DENORMAL
+#endif
+
+#ifndef EM_ZERODIVIDE
+#define EM_ZERODIVIDE _EM_ZERODIVIDE
+#endif
+
+#ifndef EM_OVERFLOW
+#define EM_OVERFLOW _EM_OVERFLOW
+#endif
+
+#ifndef EM_UNDERFLOW
+#define EM_UNDERFLOW _EM_UNDERFLOW
+#endif
+
+#ifndef MCW_EM
+#define MCW_EM _MCW_EM
+#endif
+
+#else // based on ISO C standard
+
+#if !defined(BOOST_NO_FENV_H)
+ #include <boost/detail/fenv.hpp>
+#endif
+
+#endif
+
//____________________________________________________________________________//
namespace boost {
-namespace detail {
+/// @defgroup ExecutionMonitor Function Execution Monitor
+/// @{
+/// @section Intro Introduction
+/// Sometimes we need to call a function and make sure that no user or system originated exceptions are being thrown by it. Uniform exception reporting
+/// is also may be convenient. That's the purpose of the Boost.Test's Execution Monitor.
+///
+/// The Execution Monitor is a lower-level component of the Boost Test Library. It is the base for implementing all other Boost.Test components, but also
+/// can be used standalone to get controlled execution of error-prone functions with a uniform error notification. The Execution Monitor calls a user-supplied
+/// function in a controlled environment, relieving users from messy error detection.
+///
+/// The Execution Monitor usage is demonstrated in the example exec_mon_example.
+///
+/// @section DesignRationale Design Rationale
+///
+/// The Execution Monitor design assumes that it can be used when no (or almost no) memory available. Also the Execution Monitor is intended to be portable to as many platforms as possible.
+///
+/// @section UserGuide User's guide
+/// The Execution Monitor is designed to solve the problem of executing potentially dangerous function that may result in any number of error conditions,
+/// in monitored environment that should prevent any undesirable exceptions to propagate out of function call and produce consistent result report for all outcomes.
+/// The Execution Monitor is able to produce informative report for all standard C++ exceptions and intrinsic types. All other exceptions are reported as unknown.
+/// If you prefer different message for your exception type or need to perform any action, the Execution Monitor supports custom exception translators.
+/// There are several other parameters of the monitored environment can be configured by setting appropriate properties of the Execution Monitor.
+///
+/// All symbols in the Execution Monitor implementation are located in the namespace boost. To use the Execution Monitor you need to:
+/// -# include @c boost/test/execution_monitor.hpp
+/// -# Make an instance of execution_monitor.
+/// -# Optionally register custom exception translators for exception classes which require special processing.
+///
+/// @subsection FuncExec Monitored function execution
+///
+/// The class execution_monitor can monitor functions with the following signatures:
+/// - int ()
+/// - void ()
+///
+/// This function is expected to be self sufficient part of your application. You can't pass any arguments to this function directly. Instead you
+/// should bind them into executable nullary function using bind function (either standard or boost variant). Neither you can return any other value,
+/// but an integer result code. If necessary you can bind output parameters by reference or use some other more complicated nullary functor, which
+/// maintains state. This includes class methods, static class methods etc.
+///
+/// To start the monitored function, invoke the method execution_monitor::execute and pass the monitored function as an argument. If the call succeeds,
+/// the method returns the result code produced by the monitored function. If any of the following conditions occur:
+/// - Uncaught C++ exception
+/// - Hardware or software signal, trap, or other exception
+/// - Timeout reached
+/// - Debug assert event occurred (under Microsoft Visual C++ or compatible compiler)
+///
+/// then the method throws the execution_exception. The exception contains unique error_code value identifying the error condition and the detailed message
+/// that can be used to report the error.
+///
+/// @subsection Reporting Errors reporting and translation
+///
+/// If you need to report an error inside monitored function execution you have to throw an exception. Do not use the execution_exception - it's not intended
+/// to be used for this purpose. The simplest choice is to use one of the following C++ types as an exception:
+/// - C string
+/// - std:string
+/// - any exception class in std::exception hierarchy
+/// - boost::exception
+///
+/// execution_monitor will catch and report these types of exceptions. If exception is thrown which is unknown to execution_monitor, it can only
+/// report the fact of the exception. So in case if you prefer to use your own exception types or can't govern what exceptions are generated by monitored
+/// function and would like to see proper error message in a report, execution_monitor can be configured with custom "translator" routine, which will have
+/// a chance to either record the fact of the exception itself or translate it into one of standard exceptions and rethrow (or both). The translator routine
+/// is registered per exception type and is invoked when exception of this class (or one inherited from it) is thrown inside monitored routine. You can
+/// register as many independent translators as you like. See execution_monitor::register_exception_translator specification for requirements on translator
+/// function.
+///
+/// Finally, if you need to abort the monitored function execution without reporting any errors, you can throw an exception execution_aborted. As a result
+/// the execution is aborted and zero result code is produced by the method execution_monitor::execute.
+///
+/// @subsection Parameters Supported parameters
+///
+/// The Execution Monitor behavior is configurable through the set of parameters (properties) associated with the instance of the monitor. See execution_monitor
+/// specification for a list of supported parameters and their semantic.
// ************************************************************************** //
-// ************** detail::translate_exception_base ************** //
+// ************** detail::translator_holder_base ************** //
// ************************************************************************** //
-class BOOST_TEST_DECL translate_exception_base {
+namespace detail {
+
+class translator_holder_base;
+typedef boost::shared_ptr<translator_holder_base> translator_holder_base_ptr;
+
+class BOOST_TEST_DECL translator_holder_base {
+protected:
+ typedef boost::unit_test::const_string const_string;
public:
// Constructor
- explicit translate_exception_base( boost::scoped_ptr<translate_exception_base>& next )
+ translator_holder_base( translator_holder_base_ptr next, const_string tag )
+ : m_next( next )
+ , m_tag( std::string() + tag )
{
- next.swap( m_next );
}
// Destructor
- virtual ~translate_exception_base() {}
+ virtual ~translator_holder_base() {}
- virtual int operator()( unit_test::callback0<int> const& F ) = 0;
+ // translator holder interface
+ // invokes the function F inside the try/catch guarding against specific exception
+ virtual int operator()( boost::function<int ()> const& F ) = 0;
+
+ // erases specific translator holder from the chain
+ translator_holder_base_ptr erase( translator_holder_base_ptr this_, const_string tag )
+ {
+ if( m_next )
+ m_next = m_next->erase( m_next, tag );
+
+ return m_tag == tag ? m_next : this_;
+ }
+#ifndef BOOST_NO_RTTI
+ virtual translator_holder_base_ptr erase( translator_holder_base_ptr this_, std::type_info const& ) = 0;
+ template<typename ExceptionType>
+ translator_holder_base_ptr erase( translator_holder_base_ptr this_, boost::type<ExceptionType>* = 0 )
+ {
+ if( m_next )
+ m_next = m_next->erase<ExceptionType>( m_next );
+
+ return erase( this_, typeid(ExceptionType) );
+ }
+#endif
protected:
// Data members
- boost::scoped_ptr<translate_exception_base> m_next;
+ translator_holder_base_ptr m_next;
+ std::string m_tag;
};
} // namespace detail
// ************************************************************************** //
-// ************** execution_exception ************** //
+/// @class execution_exception
+/// @brief This class is used to report any kind of an failure during execution of a monitored function inside of execution_monitor
+///
+/// The instance of this class is thrown out of execution_monitor::execute invocation when failure is detected. Regardless of a kind of failure occurred
+/// the instance will provide a uniform way to catch and report it.
+///
+/// One important design rationale for this class is that we should be ready to work after fatal memory corruptions or out of memory conditions. To facilitate
+/// this class never allocates any memory and assumes that strings it refers to are either some constants or live in a some kind of persistent (preallocated) memory.
// ************************************************************************** //
-
-// design rationale: fear of being out (or nearly out) of memory.
-
+
class BOOST_TEST_DECL execution_exception {
typedef boost::unit_test::const_string const_string;
public:
+ /// These values are sometimes used as program return codes.
+ /// The particular values have been chosen to avoid conflicts with
+ /// commonly used program return codes: values < 100 are often user
+ /// assigned, values > 255 are sometimes used to report system errors.
+ /// Gaps in values allow for orderly expansion.
+ ///
+ /// @note(1) Only uncaught C++ exceptions are treated as errors.
+ /// If a function catches a C++ exception, it never reaches
+ /// the execution_monitor.
+ ///
+ /// The implementation decides what is a system_fatal_error and what is
+ /// just a system_exception. Fatal errors are so likely to have corrupted
+ /// machine state (like a stack overflow or addressing exception) that it
+ /// is unreasonable to continue execution.
+ ///
+ /// @note(2) These errors include Unix signals and Windows structured
+ /// exceptions. They are often initiated by hardware traps.
enum error_code {
- // These values are sometimes used as program return codes.
- // The particular values have been chosen to avoid conflicts with
- // commonly used program return codes: values < 100 are often user
- // assigned, values > 255 are sometimes used to report system errors.
- // Gaps in values allow for orderly expansion.
-
- no_error = 0, // for completeness only; never returned
- user_error = 200, // user reported non-fatal error
- cpp_exception_error = 205, // see note (1) below
- system_error = 210, // see note (2) below
- timeout_error = 215, // only detectable on certain platforms
- user_fatal_error = 220, // user reported fatal error
- system_fatal_error = 225 // see note (2) below
-
- // Note 1: Only uncaught C++ exceptions are treated as errors.
- // If the application catches a C++ exception, it will never reach
- // the execution_monitor.
-
- // Note 2: These errors include Unix signals and Windows structured
- // exceptions. They are often initiated by hardware traps.
- //
- // The implementation decides what is a fatal_system_exception and what is
- // just a system_exception. Fatal errors are so likely to have corrupted
- // machine state (like a stack overflow or addressing exception) that it
- // is unreasonable to continue execution.
+ no_error = 0, ///< for completeness only; never returned
+ user_error = 200, ///< user reported non-fatal error
+ cpp_exception_error = 205, ///< see note (1) above
+ system_error = 210, ///< see note (2) above
+ timeout_error = 215, ///< only detectable on certain platforms
+ user_fatal_error = 220, ///< user reported fatal error
+ system_fatal_error = 225 ///< see note (2) above
};
-
+
+ /// Simple model for the location of failure in a source code
struct BOOST_TEST_DECL location {
explicit location( char const* file_name = 0, size_t line_num = 0, char const* func = 0 );
- const_string m_file_name;
- size_t m_line_num;
- const_string m_function;
+ const_string m_file_name; ///< File name
+ size_t m_line_num; ///< Line number
+ const_string m_function; ///< Function name
};
- // Constructor
- execution_exception( error_code ec_, const_string what_msg_, location const& location_ ); // max length 256 inc '\0'
+ /// @name Constructors
+
+ /// Constructs instance based on message, location and error code
+
+ /// @param[in] ec error code
+ /// @param[in] what_msg error message
+ /// @param[in] location error location
+ execution_exception( error_code ec, const_string what_msg, location const& location );
- // Access methods
+ /// @name Access methods
+
+ /// Exception error code
error_code code() const { return m_error_code; }
+ /// Exception message
const_string what() const { return m_what; }
+ /// Exception location
location const& where() const { return m_location; }
+ ///@}
private:
// Data members
@@ -137,86 +276,159 @@ private:
}; // execution_exception
// ************************************************************************** //
-// ************** execution_monitor ************** //
+/// Function execution monitor
+
+/// This class is used to uniformly detect and report an occurrence of several types of signals and exceptions, reducing various
+/// errors to a uniform execution_exception that is returned to a caller.
+///
+/// The executiom_monitor behavior can be customized through a set of public parameters (properties) associated with the execution_monitor instance.
+/// All parameters are implemented as public unit_test::readwrite_property data members of the class execution_monitor.
// ************************************************************************** //
class BOOST_TEST_DECL execution_monitor {
+ typedef boost::unit_test::const_string const_string;
public:
- // Constructor
- execution_monitor()
- : p_catch_system_errors( true )
- , p_auto_start_dbg( false )
- , p_timeout( 0 )
- , p_use_alt_stack( true )
- , p_detect_fp_exceptions( false )
- {}
-
- // Public properties
-
- // The p_catch_system_errors parameter specifies whether the monitor should
- // try to catch system errors/exceptions that would cause program to crash
- // in regular case
- unit_test::readwrite_property<bool> p_catch_system_errors;
- // The p_auto_start_dbg parameter specifies whether the monitor should
- // try to attach debugger in case of caught system error
+
+ /// Default constructor initializes all execution monitor properties
+ execution_monitor();
+
+ /// Should monitor catch system errors.
+ ///
+ /// The @em p_catch_system_errors property is a boolean flag (default value is true) specifying whether or not execution_monitor should trap system
+ /// errors/system level exceptions/signals, which would cause program to crash in a regular case (without execution_monitor).
+ /// Set this property to false, for example, if you wish to force coredump file creation. The Unit Test Framework provides a
+ /// runtime parameter @c \-\-catch_system_errors=yes to alter the behavior in monitored test cases.
+ unit_test::readwrite_property<bool> p_catch_system_errors;
+
+ /// Should monitor try to attach debugger in case of caught system error.
+ ///
+ /// The @em p_auto_start_dbg property is a boolean flag (default value is false) specifying whether or not execution_monitor should try to attach debugger
+ /// in case system error is caught.
unit_test::readwrite_property<bool> p_auto_start_dbg;
- // The p_timeout parameter specifies the seconds that elapse before
- // a timer_error occurs. May be ignored on some platforms.
- unit_test::readwrite_property<int> p_timeout;
- // The p_use_alt_stack parameter specifies whether the monitor should
- // use alternative stack for the signal catching
+
+
+ /// Specifies the seconds that elapse before a timer_error occurs.
+ ///
+ /// The @em p_timeout property is an integer timeout (in seconds) for monitored function execution. Use this parameter to monitor code with possible deadlocks
+ /// or indefinite loops. This feature is only available for some operating systems (not yet Microsoft Windows).
+ unit_test::readwrite_property<unsigned> p_timeout;
+
+ /// Should monitor use alternative stack for the signal catching.
+ ///
+ /// The @em p_use_alt_stack property is a boolean flag (default value is false) specifying whether or not execution_monitor should use an alternative stack
+ /// for the sigaction based signal catching. When enabled the signals are delivered to the execution_monitor on a stack different from current execution
+ /// stack, which is safer in case if it is corrupted by monitored function. For more details on alternative stack handling see appropriate manuals.
unit_test::readwrite_property<bool> p_use_alt_stack;
- // The p_detect_fp_exceptions parameter specifies whether the monitor should
- // try to detect hardware floating point exceptions
- unit_test::readwrite_property<bool> p_detect_fp_exceptions;
-
- int execute( unit_test::callback0<int> const& F );
- // Returns: Value returned by function call F().
- //
- // Effects: Calls executes supplied function F inside a try/catch block which also may
- // include other unspecified platform dependent error detection code.
- //
- // Throws: execution_exception on an uncaught C++ exception,
- // a hardware or software signal, trap, or other exception.
- //
- // Note: execute() doesn't consider it an error for F to return a non-zero value.
-
- // register custom (user supplied) exception translator
- template<typename Exception, typename ExceptionTranslator>
- void register_exception_translator( ExceptionTranslator const& tr, boost::type<Exception>* = 0 );
+
+ /// Should monitor try to detect hardware floating point exceptions (!= 0), and which specific exception to catch.
+ ///
+ /// The @em p_detect_fp_exceptions property is a boolean flag (default value is false) specifying whether or not execution_monitor should install hardware
+ /// traps for the floating point exception on platforms where it's supported.
+ unit_test::readwrite_property<unsigned> p_detect_fp_exceptions;
+
+
+ // @name Monitoring entry points
+
+ /// @brief Execution monitor entry point for functions returning integer value
+ ///
+ /// This method executes supplied function F inside a try/catch block and also may include other unspecified platform dependent error detection code.
+ ///
+ /// This method throws an execution_exception on an uncaught C++ exception, a hardware or software signal, trap, or other user exception.
+ ///
+ /// @note execute() doesn't consider it an error for F to return a non-zero value.
+ /// @param[in] F Function to monitor
+ /// @returns value returned by function call F().
+ /// @see vexecute
+ int execute( boost::function<int ()> const& F );
+
+ /// @brief Execution monitor entry point for functions returning void
+ ///
+ /// This method is semantically identical to execution_monitor::execute, but des't produce any result code.
+ /// @param[in] F Function to monitor
+ /// @see execute
+ void vexecute( boost::function<void ()> const& F );
+ // @}
+
+ // @name Exception translator registration
+
+ /// @brief Registers custom (user supplied) exception translator
+
+ /// This method template registers a translator for an exception type specified as a first template argument. For example
+ /// @code
+ /// void myExceptTr( MyException const& ex ) { /*do something with the exception here*/}
+ /// em.register_exception_translator<MyException>( myExceptTr );
+ /// @endcode
+ /// The translator should be any unary function/functor object which accepts MyException const&. This can be free standing function
+ /// or bound class method. The second argument is an optional string tag you can associate with this translator routine. The only reason
+ /// to specify the tag is if you plan to erase the translator eventually. This can be useful in scenario when you reuse the same
+ /// execution_monitor instance to monitor different routines and need to register a translator specific to the routine being monitored.
+ /// While it is possible to erase the translator based on an exception type it was registered for, tag string provides simpler way of doing this.
+ /// @tparam ExceptionType type of the exception we register a translator for
+ /// @tparam ExceptionTranslator type of the translator we register for this exception
+ /// @param[in] tr translator function object with the signature <em> void (ExceptionType const&)</em>
+ /// @param[in] tag tag associated with this translator
+ template<typename ExceptionType, typename ExceptionTranslator>
+ void register_exception_translator( ExceptionTranslator const& tr, const_string tag = const_string(), boost::type<ExceptionType>* = 0 );
+
+ /// @brief Erases custom exception translator based on a tag
+
+ /// Use the same tag as the one used during translator registration
+ /// @param[in] tag tag associated with translator you wants to erase
+ void erase_exception_translator( const_string tag )
+ {
+ m_custom_translators = m_custom_translators->erase( m_custom_translators, tag );
+ }
+#ifndef BOOST_NO_RTTI
+ /// @brief Erases custom exception translator based on an exception type
+ ///
+ /// tparam ExceptionType Exception type for which you want to erase the translator
+ template<typename ExceptionType>
+ void erase_exception_translator( boost::type<ExceptionType>* = 0 )
+ {
+ m_custom_translators = m_custom_translators->erase<ExceptionType>( m_custom_translators );
+ }
+ //@}
+#endif
private:
// implementation helpers
- int catch_signals( unit_test::callback0<int> const& F );
+ int catch_signals( boost::function<int ()> const& F );
// Data members
- boost::scoped_ptr<detail::translate_exception_base> m_custom_translators;
- boost::scoped_array<char> m_alt_stack;
+ detail::translator_holder_base_ptr m_custom_translators;
+ boost::scoped_array<char> m_alt_stack;
}; // execution_monitor
-namespace detail {
-
// ************************************************************************** //
-// ************** detail::translate_exception ************** //
+// ************** detail::translator_holder ************** //
// ************************************************************************** //
-template<typename Exception, typename ExceptionTranslator>
-class translate_exception : public translate_exception_base
+namespace detail {
+
+template<typename ExceptionType, typename ExceptionTranslator>
+class translator_holder : public translator_holder_base
{
- typedef boost::scoped_ptr<translate_exception_base> base_ptr;
public:
- explicit translate_exception( ExceptionTranslator const& tr, base_ptr& next )
- : translate_exception_base( next ), m_translator( tr ) {}
+ explicit translator_holder( ExceptionTranslator const& tr, translator_holder_base_ptr& next, const_string tag = const_string() )
+ : translator_holder_base( next, tag ), m_translator( tr ) {}
- int operator()( unit_test::callback0<int> const& F )
+ // translator holder interface
+ virtual int operator()( boost::function<int ()> const& F )
{
- try {
+ BOOST_TEST_IMPL_TRY {
return m_next ? (*m_next)( F ) : F();
- } catch( Exception const& e ) {
+ }
+ BOOST_TEST_IMPL_CATCH( ExceptionType, e ) {
m_translator( e );
return boost::exit_exception_failure;
}
}
+#ifndef BOOST_NO_RTTI
+ virtual translator_holder_base_ptr erase( translator_holder_base_ptr this_, std::type_info const& ti )
+ {
+ return ti == typeid(ExceptionType) ? m_next : this_;
+ }
+#endif
private:
// Data members
@@ -225,16 +437,17 @@ private:
} // namespace detail
-template<typename Exception, typename ExceptionTranslator>
+template<typename ExceptionType, typename ExceptionTranslator>
void
-execution_monitor::register_exception_translator( ExceptionTranslator const& tr, boost::type<Exception>* )
+execution_monitor::register_exception_translator( ExceptionTranslator const& tr, const_string tag, boost::type<ExceptionType>* )
{
- m_custom_translators.reset(
- new detail::translate_exception<Exception,ExceptionTranslator>( tr,m_custom_translators ) );
+ m_custom_translators.reset(
+ new detail::translator_holder<ExceptionType,ExceptionTranslator>( tr, m_custom_translators, tag ) );
}
// ************************************************************************** //
-// ************** execution_aborted ************** //
+/// @class execution_aborted
+/// @brief This is a trivial default constructible class. Use it to report graceful abortion of a monitored function execution.
// ************************************************************************** //
struct execution_aborted {};
@@ -248,16 +461,60 @@ public:
// Constructor
explicit system_error( char const* exp );
- unit_test::readonly_property<long> p_errno;
- unit_test::readonly_property<char const*> p_failed_exp;
+ unit_test::readonly_property<long> p_errno;
+ unit_test::readonly_property<char const*> p_failed_exp;
};
-#define BOOST_TEST_SYS_ASSERT( exp ) if( (exp) ) ; else throw ::boost::system_error( BOOST_STRINGIZE( exp ) )
+#define BOOST_TEST_SYS_ASSERT( exp ) \
+ if( (exp) ) ; \
+ else BOOST_TEST_IMPL_THROW( ::boost::system_error( BOOST_STRINGIZE( exp ) ) )
-} // namespace boost
+// ************************************************************************** //
+// **************Floating point exception management interface ************** //
+// ************************************************************************** //
+
+namespace fpe {
+
+enum masks {
+ BOOST_FPE_OFF = 0,
+
+#ifdef BOOST_SEH_BASED_SIGNAL_HANDLING
+ BOOST_FPE_DIVBYZERO = EM_ZERODIVIDE,
+ BOOST_FPE_INEXACT = EM_INEXACT,
+ BOOST_FPE_INVALID = EM_INVALID,
+ BOOST_FPE_OVERFLOW = EM_OVERFLOW,
+ BOOST_FPE_UNDERFLOW = EM_UNDERFLOW|EM_DENORMAL,
+
+ BOOST_FPE_ALL = MCW_EM,
+#elif defined(BOOST_NO_FENV_H) || defined(BOOST_CLANG)
+ BOOST_FPE_ALL = 1,
+#else
+ BOOST_FPE_DIVBYZERO = FE_DIVBYZERO,
+ BOOST_FPE_INEXACT = FE_INEXACT,
+ BOOST_FPE_INVALID = FE_INVALID,
+ BOOST_FPE_OVERFLOW = FE_OVERFLOW,
+ BOOST_FPE_UNDERFLOW = FE_UNDERFLOW,
+
+ BOOST_FPE_ALL = FE_ALL_EXCEPT,
+#endif
+ BOOST_FPE_INV = BOOST_FPE_ALL+1
+};
//____________________________________________________________________________//
+// return the previous set of enabled exceptions when successful, and BOOST_FPE_INV otherwise
+unsigned BOOST_TEST_DECL enable( unsigned mask );
+unsigned BOOST_TEST_DECL disable( unsigned mask );
+
+//____________________________________________________________________________//
+
+} // namespace fpe
+
+///@}
+
+} // namespace boost
+
+
#include <boost/test/detail/enable_warnings.hpp>
#endif
diff --git a/boost/test/floating_point_comparison.hpp b/boost/test/floating_point_comparison.hpp
index 5a5a3269cc..8475520f32 100644
--- a/boost/test/floating_point_comparison.hpp
+++ b/boost/test/floating_point_comparison.hpp
@@ -1,286 +1,14 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2011-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : defines algoirthms for comparing 2 floating point values
+//! @file
+//! @brief Deprecated header
+//! @deprecated Use boost/test/tools/floating_point_comparison.hpp instead
// ***************************************************************************
-#ifndef BOOST_TEST_FLOATING_POINT_COMPARISON_HPP_071894GER
-#define BOOST_TEST_FLOATING_POINT_COMPARISON_HPP_071894GER
-
// Boost.Test
-#include <boost/test/detail/global_typedef.hpp>
-#include <boost/test/utils/class_properties.hpp>
-#include <boost/test/predicate_result.hpp>
-
-// Boost
-#include <boost/limits.hpp> // for std::numeric_limits
-#include <boost/numeric/conversion/conversion_traits.hpp> // for numeric::conversion_traits
-#include <boost/static_assert.hpp>
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-//____________________________________________________________________________//
-
-namespace boost {
-
-namespace test_tools {
-
-using unit_test::readonly_property;
-
-// ************************************************************************** //
-// ************** floating_point_comparison_type ************** //
-// ************************************************************************** //
-
-enum floating_point_comparison_type {
- FPC_STRONG, // "Very close" - equation 1' in docs, the default
- FPC_WEAK // "Close enough" - equation 2' in docs.
-
-};
-
-// ************************************************************************** //
-// ************** details ************** //
-// ************************************************************************** //
-
-namespace tt_detail {
-
-// FPT is Floating-Point Type: float, double, long double or User-Defined.
-template<typename FPT>
-inline FPT
-fpt_abs( FPT fpv )
-{
- return fpv < static_cast<FPT>(0) ? -fpv : fpv;
-}
-
-//____________________________________________________________________________//
-
-template<typename FPT>
-struct fpt_limits {
- static FPT min_value()
- {
- return std::numeric_limits<FPT>::is_specialized
- ? (std::numeric_limits<FPT>::min)()
- : 0;
- }
- static FPT max_value()
- {
- return std::numeric_limits<FPT>::is_specialized
- ? (std::numeric_limits<FPT>::max)()
- : static_cast<FPT>(1000000); // for the our purpuses it doesn't really matter what value is returned here
- }
-};
-
-//____________________________________________________________________________//
-
-// both f1 and f2 are unsigned here
-template<typename FPT>
-inline FPT
-safe_fpt_division( FPT f1, FPT f2 )
-{
- // Avoid overflow.
- if( (f2 < static_cast<FPT>(1)) && (f1 > f2*fpt_limits<FPT>::max_value()) )
- return fpt_limits<FPT>::max_value();
-
- // Avoid underflow.
- if( (f1 == static_cast<FPT>(0)) ||
- ((f2 > static_cast<FPT>(1)) && (f1 < f2*fpt_limits<FPT>::min_value())) )
- return static_cast<FPT>(0);
-
- return f1/f2;
-}
-
-//____________________________________________________________________________//
-
-} // namespace tt_detail
-
-// ************************************************************************** //
-// ************** tolerance presentation types ************** //
-// ************************************************************************** //
-
-template<typename FPT>
-struct percent_tolerance_t {
- explicit percent_tolerance_t( FPT v ) : m_value( v ) {}
-
- FPT m_value;
-};
-
-//____________________________________________________________________________//
-
-template<typename Out,typename FPT>
-Out& operator<<( Out& out, percent_tolerance_t<FPT> t )
-{
- return out << t.m_value;
-}
-
-//____________________________________________________________________________//
-
-template<typename FPT>
-inline percent_tolerance_t<FPT>
-percent_tolerance( FPT v )
-{
- return percent_tolerance_t<FPT>( v );
-}
-
-//____________________________________________________________________________//
-
-template<typename FPT>
-struct fraction_tolerance_t {
- explicit fraction_tolerance_t( FPT v ) : m_value( v ) {}
-
- FPT m_value;
-};
-
-//____________________________________________________________________________//
-
-template<typename Out,typename FPT>
-Out& operator<<( Out& out, fraction_tolerance_t<FPT> t )
-{
- return out << t.m_value;
-}
-
-//____________________________________________________________________________//
-
-template<typename FPT>
-inline fraction_tolerance_t<FPT>
-fraction_tolerance( FPT v )
-{
- return fraction_tolerance_t<FPT>( v );
-}
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** close_at_tolerance ************** //
-// ************************************************************************** //
-
-template<typename FPT>
-class close_at_tolerance {
-public:
- // Public typedefs
- typedef bool result_type;
-
- // Constructor
- template<typename ToleranceBaseType>
- explicit close_at_tolerance( percent_tolerance_t<ToleranceBaseType> tolerance,
- floating_point_comparison_type fpc_type = FPC_STRONG )
- : p_fraction_tolerance( tt_detail::fpt_abs( static_cast<FPT>(0.01)*tolerance.m_value ) )
- , p_strong_or_weak( fpc_type == FPC_STRONG )
- , m_report_modifier( 100. )
- {}
- template<typename ToleranceBaseType>
- explicit close_at_tolerance( fraction_tolerance_t<ToleranceBaseType> tolerance,
- floating_point_comparison_type fpc_type = FPC_STRONG )
- : p_fraction_tolerance( tt_detail::fpt_abs( tolerance.m_value ) )
- , p_strong_or_weak( fpc_type == FPC_STRONG )
- , m_report_modifier( 1. )
- {}
-
- predicate_result operator()( FPT left, FPT right ) const
- {
- FPT diff = tt_detail::fpt_abs( left - right );
- FPT d1 = tt_detail::safe_fpt_division( diff, tt_detail::fpt_abs( right ) );
- FPT d2 = tt_detail::safe_fpt_division( diff, tt_detail::fpt_abs( left ) );
-
- predicate_result res( p_strong_or_weak
- ? (d1 <= p_fraction_tolerance.get() && d2 <= p_fraction_tolerance.get())
- : (d1 <= p_fraction_tolerance.get() || d2 <= p_fraction_tolerance.get()) );
-
- if( !res )
- res.message() << (( d1 <= p_fraction_tolerance.get() ? d2 : d1 ) * m_report_modifier);
-
- return res;
- }
-
- // Public properties
- readonly_property<FPT> p_fraction_tolerance;
- readonly_property<bool> p_strong_or_weak;
-private:
- // Data members
- FPT m_report_modifier;
-};
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** check_is_close ************** //
-// ************************************************************************** //
-
-struct BOOST_TEST_DECL check_is_close_t {
- // Public typedefs
- typedef bool result_type;
-
- template<typename FPT1, typename FPT2, typename ToleranceBaseType>
- predicate_result
- operator()( FPT1 left, FPT2 right, percent_tolerance_t<ToleranceBaseType> tolerance,
- floating_point_comparison_type fpc_type = FPC_STRONG ) const
- {
- // deduce "better" type from types of arguments being compared
- // if one type is floating and the second integral we use floating type and
- // value of integral type is promoted to the floating. The same for float and double
- // But we don't want to compare two values of integral types using this tool.
- typedef typename numeric::conversion_traits<FPT1,FPT2>::supertype FPT;
- BOOST_STATIC_ASSERT( !is_integral<FPT>::value );
-
- close_at_tolerance<FPT> pred( tolerance, fpc_type );
-
- return pred( left, right );
- }
- template<typename FPT1, typename FPT2, typename ToleranceBaseType>
- predicate_result
- operator()( FPT1 left, FPT2 right, fraction_tolerance_t<ToleranceBaseType> tolerance,
- floating_point_comparison_type fpc_type = FPC_STRONG ) const
- {
- // same as in a comment above
- typedef typename numeric::conversion_traits<FPT1,FPT2>::supertype FPT;
- BOOST_STATIC_ASSERT( !is_integral<FPT>::value );
-
- close_at_tolerance<FPT> pred( tolerance, fpc_type );
-
- return pred( left, right );
- }
-};
-
-namespace {
-check_is_close_t const& check_is_close = unit_test::ut_detail::static_constant<check_is_close_t>::value;
-}
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** check_is_small ************** //
-// ************************************************************************** //
-
-struct BOOST_TEST_DECL check_is_small_t {
- // Public typedefs
- typedef bool result_type;
-
- template<typename FPT>
- bool
- operator()( FPT fpv, FPT tolerance ) const
- {
- return tt_detail::fpt_abs( fpv ) < tt_detail::fpt_abs( tolerance );
- }
-};
-
-namespace {
-check_is_small_t const& check_is_small = unit_test::ut_detail::static_constant<check_is_small_t>::value;
-}
-
-//____________________________________________________________________________//
-
-} // namespace test_tools
-
-} // namespace boost
-
-//____________________________________________________________________________//
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // BOOST_FLOATING_POINT_COMAPARISON_HPP_071894GER
+#include <boost/test/tools/floating_point_comparison.hpp>
diff --git a/boost/test/framework.hpp b/boost/test/framework.hpp
index 7f6fd2aecc..92716a0be0 100644
--- a/boost/test/framework.hpp
+++ b/boost/test/framework.hpp
@@ -1,15 +1,13 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : defines framework interface
+//!@file
+//!@brief Defines Unit Test Framework mono-state interfaces.
+//! The framework interfaces are based on Monostate design pattern.
// ***************************************************************************
#ifndef BOOST_TEST_FRAMEWORK_HPP_020805GER
@@ -18,6 +16,8 @@
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/fwd_decl.hpp>
+#include <boost/test/detail/throw_exception.hpp>
+
#include <boost/test/utils/trivial_singleton.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
@@ -29,12 +29,16 @@
namespace boost {
+/// Main namespace for the Unit Test Framework interfaces and implementation
namespace unit_test {
// ************************************************************************** //
// ************** init_unit_test_func ************** //
// ************************************************************************** //
+/// Test module initialization routine signature
+
+/// Different depending on whether BOOST_TEST_ALTERNATIVE_INIT_API is defined or not
#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
typedef bool (*init_unit_test_func)();
#else
@@ -45,67 +49,225 @@ typedef test_suite* (*init_unit_test_func)( int, char* [] );
// ************** framework ************** //
// ************************************************************************** //
+/// Namespace of the Unit Test Framework mono-state
namespace framework {
-// initialization
-BOOST_TEST_DECL void init( init_unit_test_func init_func, int argc, char* argv[] );
-BOOST_TEST_DECL bool is_initialized();
+/// @name Unit Test Framework initialization and shutdown
+/// @{
+
+/// @brief This function performs initialization of the framework mono-state.
+///
+/// It needs to be called every time before the test is started.
+/// @param[in] init_func test module initialization routine
+/// @param[in] argc command line arguments collection
+/// @param[in] argv command line arguments collection
+BOOST_TEST_DECL void init( init_unit_test_func init_func, int argc, char* argv[] );
+
+/// This function applies all the decorators and figures out default run status. This argument facilitates an
+/// ability of the test cases to prepare some other test units (primarily used internally for self testing).
+/// @param[in] tu Optional id of the test unit representing root of test tree. If absent, master test suite is used
+BOOST_TEST_DECL void finalize_setup_phase( test_unit_id tu = INV_TEST_UNIT_ID);
+
+/// This function returns true when testing is in progress (setup is finished).
+BOOST_TEST_DECL bool test_in_progress();
+
+/// This function shuts down the framework and clears up its mono-state.
+///
+/// It needs to be at the very end of test module execution
+BOOST_TEST_DECL void shutdown();
+/// @}
+
+/// @name Test unit registration
+/// @{
+
+/// Provides both read and write access to current "leaf" auto test suite during the test unit registration phase.
+///
+/// During auto-registration phase the framework maintain a FIFO queue of test units being registered. New test units become children
+/// of the current "leaf" test suite and if this is test suite it is pushed back into queue and becomes a new leaf.
+/// When test suite registration is completed, a test suite is popped from the back of the queue. Only automatically registered test suites
+/// should be added to this queue. Master test suite is always a zero element in this queue, so if no other test suites are registered
+/// all test cases are added to master test suite.
+
+/// This function facilitates all three possible actions:
+/// - if no argument are provided it returns the current queue leaf test suite
+/// - if test suite is provided and no second argument are set, test suite is added to the queue
+/// - if no test suite are provided and last argument is false, the semantic of this function is similar to queue pop: last element is popped from the queue
+/// @param[in] ts test suite to push back to the queue
+/// @param[in] push_or_pop should we push ts to the queue or pop leaf test suite instead
+/// @returns a reference to the currently active/"leaf" test suite
+BOOST_TEST_DECL test_suite& current_auto_test_suite( test_suite* ts = 0, bool push_or_pop = true );
+
+/// This function add new test case into the global collection of test units the framework aware of.
+
+/// This function also assignes unique test unit id for every test case. Later on one can use this id to locate
+/// the test case if necessary. This is the way for the framework to maintain weak references between test units.
+/// @param[in] tc test case to register
+BOOST_TEST_DECL void register_test_unit( test_case* tc );
+
+/// This function add new test suite into the global collection of test units the framework aware of.
+
+/// This function also assignes unique test unit id for every test suite. Later on one can use this id to locate
+/// the test case if necessary. This is the way for the framework to maintain weak references between test units.
+/// @param[in] ts test suite to register
+BOOST_TEST_DECL void register_test_unit( test_suite* ts );
+
+/// This function removes the test unit from the collection of known test units and destroys the test unit object.
+
+/// This function also assigns unique test unit id for every test case. Later on one can use this id to located
+/// the test case if necessary. This is the way for the framework to maintain weak references between test units.
+/// @param[in] tu test unit to deregister
+BOOST_TEST_DECL void deregister_test_unit( test_unit* tu );
+
+// This function clears up the framework mono-state.
+
+/// Afer this call the framework can be reinitialized to perform a second test run during the same program lifetime.
+BOOST_TEST_DECL void clear();
+/// @}
+
+/// @name Test observer registration
+/// @{
+/// Adds new test execution observer object into the framework's list of test observers.
+
+/// Observer lifetime should exceed the the testing execution timeframe
+/// @param[in] to test observer object to add
+BOOST_TEST_DECL void register_observer( test_observer& to );
+
+/// Excldes the observer object form the framework's list of test observers
+/// @param[in] to test observer object to exclude
+BOOST_TEST_DECL void deregister_observer( test_observer& to );
+
+/// @}
+
+/// @name Assertion/uncaught exception context support
+/// @{
+/// Context accessor
+struct BOOST_TEST_DECL context_generator {
+ context_generator() : m_curr_frame( 0 ) {}
+
+ /// Is there any context?
+ bool is_empty() const;
+
+ /// Give me next frame; empty - last frame
+ const_string next() const;
+
+private:
+ // Data members
+ mutable unsigned m_curr_frame;
+};
+
+/// Records context frame message.
-// mutation access methods
-BOOST_TEST_DECL void register_test_unit( test_case* tc );
-BOOST_TEST_DECL void register_test_unit( test_suite* ts );
-BOOST_TEST_DECL void deregister_test_unit( test_unit* tu );
-BOOST_TEST_DECL void clear();
+/// Some context frames are sticky - they can only explicitly cleared by specifying context id. Other (non sticky) context frames cleared after every assertion.
+/// @param[in] context_descr context frame message
+/// @param[in] sticky is this sticky frame or not
+/// @returns id of the newly created frame
+BOOST_TEST_DECL int add_context( lazy_ostream const& context_descr, bool sticky );
+/// Erases context frame (when test exits context scope)
-BOOST_TEST_DECL void register_observer( test_observer& );
-BOOST_TEST_DECL void deregister_observer( test_observer& );
-BOOST_TEST_DECL void reset_observers();
+/// If context_id is passed clears that specific context frame identified by this id, otherwise clears all non sticky contexts.
+BOOST_TEST_DECL void clear_context( int context_id = -1 );
+/// Produces an instance of small "delegate" object, which facilitates access to collected context.
+BOOST_TEST_DECL context_generator get_context();
+/// @}
+/// @name Access to registered test units.
+/// @{
+/// This function provides access to the master test suite.
+
+/// There is only only master test suite per test module.
+/// @returns a reference the master test suite instance
BOOST_TEST_DECL master_test_suite_t& master_test_suite();
-// constant access methods
+/// This function provides an access to the test case currently being executed.
+
+/// This function is only valid during test execution phase.
+/// @see current_test_case_id
BOOST_TEST_DECL test_case const& current_test_case();
-BOOST_TEST_DECL test_unit& get( test_unit_id, test_unit_type );
+/// This function provides an access to an id of the test case currently being executed.
+
+/// This function safer than current_test_case, cause if wont throw if no test case is being executed.
+/// @see current_test_case
+BOOST_TEST_DECL test_unit_id current_test_case_id(); /* safe version of above */
+
+/// This function provides access to a test unit by id and type combination. It will throw if no test unit located.
+/// @param[in] tu_id id of a test unit to locate
+/// @param[in] tu_type type of a test unit to locate
+/// @returns located test unit
+BOOST_TEST_DECL test_unit& get( test_unit_id tu_id, test_unit_type tu_type );
+
+/// This function template provides access to a typed test unit by id
+
+/// It will throw if you specify incorrect test unit type
+/// @tparam UnitType compile time type of test unit to get (test_suite or test_case)
+/// @param id id of test unit to get
template<typename UnitType>
-UnitType& get( test_unit_id id )
+inline UnitType& get( test_unit_id id )
{
return static_cast<UnitType&>( get( id, static_cast<test_unit_type>(UnitType::type) ) );
}
-
-// test initiation
-BOOST_TEST_DECL void run( test_unit_id = INV_TEST_UNIT_ID, bool continue_test = true );
-BOOST_TEST_DECL void run( test_unit const*, bool continue_test = true );
-
-// public test events dispatchers
-BOOST_TEST_DECL void assertion_result( bool passed );
-BOOST_TEST_DECL void exception_caught( execution_exception const& );
-BOOST_TEST_DECL void test_unit_aborted( test_unit const& );
+///@}
+
+/// @name Test initiation interface
+/// @{
+
+/// Initiates test execution
+
+/// This function is used to start the test execution from a specific "root" test unit.
+/// If no root provided, test is started from master test suite. This second argument facilitates an ability of the test cases to
+/// start some other test units (primarily used internally for self testing).
+/// @param[in] tu Optional id of the test unit or test unit itself from which the test is started. If absent, master test suite is used
+/// @param[in] continue_test true == continue test if it was already started, false == restart the test from scratch regardless
+BOOST_TEST_DECL void run( test_unit_id tu = INV_TEST_UNIT_ID, bool continue_test = true );
+/// Initiates test execution. Same as other overload
+BOOST_TEST_DECL void run( test_unit const* tu, bool continue_test = true );
+/// @}
+
+/// @name Test events dispatchers
+/// @{
+/// Reports results of assertion to all test observers
+BOOST_TEST_DECL void assertion_result( unit_test::assertion_result ar );
+/// Reports uncaught exception to all test observers
+BOOST_TEST_DECL void exception_caught( execution_exception const& );
+/// Reports aborted test unit to all test observers
+BOOST_TEST_DECL void test_unit_aborted( test_unit const& );
+/// @}
+
+namespace impl {
+// exclusively for self test
+BOOST_TEST_DECL void setup_for_execution( test_unit const& );
+} // namespace impl
// ************************************************************************** //
// ************** framework errors ************** //
// ************************************************************************** //
-struct internal_error : std::runtime_error {
+/// This exception type is used to report internal Boost.Test framework errors.
+struct BOOST_TEST_DECL internal_error : public std::runtime_error {
internal_error( const_string m ) : std::runtime_error( std::string( m.begin(), m.size() ) ) {}
};
-struct setup_error : std::runtime_error {
+//____________________________________________________________________________//
+
+/// This exception type is used to report test module setup errors.
+struct BOOST_TEST_DECL setup_error : public std::runtime_error {
setup_error( const_string m ) : std::runtime_error( std::string( m.begin(), m.size() ) ) {}
};
-#define BOOST_TEST_SETUP_ASSERT( cond, msg ) if( cond ) {} else throw unit_test::framework::setup_error( msg )
+#define BOOST_TEST_SETUP_ASSERT( cond, msg ) \
+ if( cond ) {} \
+ else BOOST_TEST_IMPL_THROW( unit_test::framework::setup_error( msg ) )
+
+//____________________________________________________________________________//
struct nothing_to_test {}; // not really an error
-} // namespace framework
+//____________________________________________________________________________//
+} // namespace framework
} // unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_FRAMEWORK_HPP_020805GER
diff --git a/boost/test/impl/compiler_log_formatter.ipp b/boost/test/impl/compiler_log_formatter.ipp
index 8fc08ccf44..c1ed944ab1 100644
--- a/boost/test/impl/compiler_log_formatter.ipp
+++ b/boost/test/impl/compiler_log_formatter.ipp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -16,11 +16,14 @@
#define BOOST_TEST_COMPILER_LOG_FORMATTER_IPP_020105GER
// Boost.Test
-#include <boost/test/output/compiler_log_formatter.hpp>
-#include <boost/test/unit_test_suite_impl.hpp>
#include <boost/test/framework.hpp>
+#include <boost/test/execution_monitor.hpp>
+#include <boost/test/tree/test_unit.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/test/utils/lazy_ostream.hpp>
+#include <boost/test/utils/setcolor.hpp>
+#include <boost/test/output/compiler_log_formatter.hpp>
+#include <boost/test/unit_test_parameters.hpp>
// Boost
#include <boost/version.hpp>
@@ -33,9 +36,7 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
-
namespace output {
// ************************************************************************** //
@@ -44,12 +45,10 @@ namespace output {
namespace {
-const_string
+std::string
test_phase_identifier()
{
- return framework::is_initialized()
- ? const_string( framework::current_test_case().p_name.get() )
- : BOOST_TEST_L( "Test setup" );
+ return framework::test_in_progress() ? framework::current_test_case().full_name() : std::string( "Test setup" );
}
} // local namespace
@@ -90,6 +89,10 @@ compiler_log_formatter::log_build_info( std::ostream& output )
void
compiler_log_formatter::test_unit_start( std::ostream& output, test_unit const& tu )
{
+ BOOST_TEST_SCOPE_SETCOLOR( output, term_attr::BRIGHT, term_color::BLUE );
+
+ print_prefix( output, tu.p_file_name, tu.p_line_num );
+
output << "Entering test " << tu.p_type_name << " \"" << tu.p_name << "\"" << std::endl;
}
@@ -98,6 +101,10 @@ compiler_log_formatter::test_unit_start( std::ostream& output, test_unit const&
void
compiler_log_formatter::test_unit_finish( std::ostream& output, test_unit const& tu, unsigned long elapsed )
{
+ BOOST_TEST_SCOPE_SETCOLOR( output, term_attr::BRIGHT, term_color::BLUE );
+
+ print_prefix( output, tu.p_file_name, tu.p_line_num );
+
output << "Leaving test " << tu.p_type_name << " \"" << tu.p_name << "\"";
if( elapsed > 0 ) {
@@ -105,7 +112,7 @@ compiler_log_formatter::test_unit_finish( std::ostream& output, test_unit const&
if( elapsed % 1000 == 0 )
output << elapsed/1000 << "ms";
else
- output << elapsed << "mks";
+ output << elapsed << "us";
}
output << std::endl;
@@ -114,31 +121,48 @@ compiler_log_formatter::test_unit_finish( std::ostream& output, test_unit const&
//____________________________________________________________________________//
void
-compiler_log_formatter::test_unit_skipped( std::ostream& output, test_unit const& tu )
+compiler_log_formatter::test_unit_skipped( std::ostream& output, test_unit const& tu, const_string reason )
{
- output << "Test " << tu.p_type_name << " \"" << tu.p_name << "\"" << "is skipped" << std::endl;
+ BOOST_TEST_SCOPE_SETCOLOR( output, term_attr::BRIGHT, term_color::YELLOW );
+
+ print_prefix( output, tu.p_file_name, tu.p_line_num );
+
+ output << "Test " << tu.p_type_name << " \"" << tu.full_name() << "\"" << " is skipped because " << reason << std::endl;
}
-
+
//____________________________________________________________________________//
void
-compiler_log_formatter::log_exception( std::ostream& output, log_checkpoint_data const& checkpoint_data, execution_exception const& ex )
+compiler_log_formatter::log_exception_start( std::ostream& output, log_checkpoint_data const& checkpoint_data, execution_exception const& ex )
{
execution_exception::location const& loc = ex.where();
+
print_prefix( output, loc.m_file_name, loc.m_line_num );
- output << "fatal error in \"" << (loc.m_function.is_empty() ? test_phase_identifier() : loc.m_function ) << "\": ";
+ {
+ BOOST_TEST_SCOPE_SETCOLOR( output, term_attr::BLINK, term_color::RED );
- output << ex.what();
+ output << "fatal error: in \"" << (loc.m_function.is_empty() ? test_phase_identifier() : loc.m_function ) << "\": "
+ << ex.what();
+ }
if( !checkpoint_data.m_file_name.is_empty() ) {
output << '\n';
print_prefix( output, checkpoint_data.m_file_name, checkpoint_data.m_line_num );
+
+ BOOST_TEST_SCOPE_SETCOLOR( output, term_attr::BRIGHT, term_color::CYAN );
+
output << "last checkpoint";
if( !checkpoint_data.m_message.empty() )
output << ": " << checkpoint_data.m_message;
}
-
+}
+
+//____________________________________________________________________________//
+
+void
+compiler_log_formatter::log_exception_finish( std::ostream& output )
+{
output << std::endl;
}
@@ -150,21 +174,31 @@ compiler_log_formatter::log_entry_start( std::ostream& output, log_entry_data co
switch( let ) {
case BOOST_UTL_ET_INFO:
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
+ if( runtime_config::color_output() )
+ output << setcolor( term_attr::BRIGHT, term_color::GREEN );
output << "info: ";
break;
case BOOST_UTL_ET_MESSAGE:
+ if( runtime_config::color_output() )
+ output << setcolor( term_attr::BRIGHT, term_color::CYAN );
break;
case BOOST_UTL_ET_WARNING:
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
- output << "warning in \"" << test_phase_identifier() << "\": ";
+ if( runtime_config::color_output() )
+ output << setcolor( term_attr::BRIGHT, term_color::YELLOW );
+ output << "warning: in \"" << test_phase_identifier() << "\": ";
break;
case BOOST_UTL_ET_ERROR:
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
- output << "error in \"" << test_phase_identifier() << "\": ";
+ if( runtime_config::color_output() )
+ output << setcolor( term_attr::BRIGHT, term_color::RED );
+ output << "error: in \"" << test_phase_identifier() << "\": ";
break;
case BOOST_UTL_ET_FATAL_ERROR:
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
- output << "fatal error in \"" << test_phase_identifier() << "\": ";
+ if( runtime_config::color_output() )
+ output << setcolor( term_attr::BLINK, term_color::RED );
+ output << "fatal error: in \"" << test_phase_identifier() << "\": ";
break;
}
}
@@ -190,33 +224,60 @@ compiler_log_formatter::log_entry_value( std::ostream& output, lazy_ostream cons
void
compiler_log_formatter::log_entry_finish( std::ostream& output )
{
+ if( runtime_config::color_output() )
+ output << setcolor();
+
output << std::endl;
}
+
//____________________________________________________________________________//
void
-compiler_log_formatter::print_prefix( std::ostream& output, const_string file, std::size_t line )
+compiler_log_formatter::print_prefix( std::ostream& output, const_string file_name, std::size_t line_num )
{
+ if( !file_name.empty() )
+ {
#ifdef __APPLE_CC__
- // Xcode-compatible logging format, idea by Richard Dingwall at
- // <http://richarddingwall.name/2008/06/01/using-the-boost-unit-test-framework-with-xcode-3/>.
- output << file << ':' << line << ": ";
+ // Xcode-compatible logging format, idea by Richard Dingwall at
+ // <http://richarddingwall.name/2008/06/01/using-the-boost-unit-test-framework-with-xcode-3/>.
+ output << file_name << ':' << line_num << ": ";
#else
- output << file << '(' << line << "): ";
+ output << file_name << '(' << line_num << "): ";
#endif
+ }
}
//____________________________________________________________________________//
-} // namespace output
+void
+compiler_log_formatter::entry_context_start( std::ostream& output, log_level l )
+{
+ output << (l == log_successful_tests ? "\nAssertion" : "\nFailure" ) << " occurred in a following context:";
+}
-} // namespace unit_test
+//____________________________________________________________________________//
-} // namespace boost
+void
+compiler_log_formatter::entry_context_finish( std::ostream& output )
+{
+ output.flush();
+}
//____________________________________________________________________________//
+void
+compiler_log_formatter::log_entry_context( std::ostream& output, const_string context_descr )
+{
+ output << "\n " << context_descr;
+}
+
+//____________________________________________________________________________//
+
+} // namespace output
+} // namespace unit_test
+} // namespace boost
+
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_COMPILER_LOG_FORMATTER_IPP_020105GER
diff --git a/boost/test/impl/cpp_main.ipp b/boost/test/impl/cpp_main.ipp
index 23d19e2f31..5cab0f4274 100644
--- a/boost/test/impl/cpp_main.ipp
+++ b/boost/test/impl/cpp_main.ipp
@@ -1,7 +1,7 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// (C) Copyright Beman Dawes 1995-2001.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -41,18 +41,18 @@ namespace std { using ::getenv; using ::strerror; }
namespace {
struct cpp_main_caller {
- cpp_main_caller( int (*cpp_main_func)( int argc, char* argv[] ), int argc, char** argv )
+ cpp_main_caller( int (*cpp_main_func)( int argc, char* argv[] ), int argc, char** argv )
: m_cpp_main_func( cpp_main_func )
, m_argc( argc )
, m_argv( argv ) {}
-
- int operator()() { return (*m_cpp_main_func)( m_argc, m_argv ); }
-
+
+ int operator()() { return (*m_cpp_main_func)( m_argc, m_argv ); }
+
private:
- // Data members
- int (*m_cpp_main_func)( int argc, char* argv[] );
- int m_argc;
- char** m_argv;
+ // Data members
+ int (*m_cpp_main_func)( int argc, char* argv[] );
+ int m_argc;
+ char** m_argv;
};
} // local namespace
@@ -68,15 +68,14 @@ prg_exec_monitor_main( int (*cpp_main)( int argc, char* argv[] ), int argc, char
{
int result = 0;
- try {
+ BOOST_TEST_IMPL_TRY {
boost::unit_test::const_string p( std::getenv( "BOOST_TEST_CATCH_SYSTEM_ERRORS" ) );
::boost::execution_monitor ex_mon;
ex_mon.p_catch_system_errors.value = p != "no";
-
- result = ex_mon.execute(
- ::boost::unit_test::callback0<int>( cpp_main_caller( cpp_main, argc, argv ) ) );
-
+
+ result = ex_mon.execute( cpp_main_caller( cpp_main, argc, argv ) );
+
if( result == 0 )
result = ::boost::exit_success;
else if( result != ::boost::exit_success ) {
@@ -84,13 +83,13 @@ prg_exec_monitor_main( int (*cpp_main)( int argc, char* argv[] ), int argc, char
result = ::boost::exit_failure;
}
}
- catch( ::boost::execution_exception const& exex ) {
+ BOOST_TEST_IMPL_CATCH( ::boost::execution_exception, exex ) {
std::cout << "\n**** exception(" << exex.code() << "): " << exex.what() << std::endl;
result = ::boost::exit_exception_failure;
}
- catch( ::boost::system_error const& ex ) {
+ BOOST_TEST_IMPL_CATCH( ::boost::system_error, ex ) {
std::cout << "\n**** failed to initialize execution monitor."
- << "\n**** expression at fault: " << ex.p_failed_exp
+ << "\n**** expression at fault: " << ex.p_failed_exp
<< "\n**** error(" << ex.p_errno << "): " << std::strerror( ex.p_errno ) << std::endl;
result = ::boost::exit_exception_failure;
}
@@ -104,8 +103,8 @@ prg_exec_monitor_main( int (*cpp_main)( int argc, char* argv[] ), int argc, char
// line argument modifications; for use in production programs
// that's a no-no in some organizations.
::boost::unit_test::const_string p( std::getenv( "BOOST_PRG_MON_CONFIRM" ) );
- if( p != "no" ) {
- std::cerr << std::flush << "no errors detected" << std::endl;
+ if( p != "no" ) {
+ std::cerr << std::flush << "no errors detected" << std::endl;
}
}
@@ -132,8 +131,6 @@ main( int argc, char* argv[] )
#endif // !BOOST_TEST_DYN_LINK && !BOOST_TEST_NO_MAIN
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_CPP_MAIN_IPP_012205GER
diff --git a/boost/test/impl/debug.ipp b/boost/test/impl/debug.ipp
index 78c3aa8e38..90e9d7ff2f 100644
--- a/boost/test/impl/debug.ipp
+++ b/boost/test/impl/debug.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2006-2008.
+// (C) Copyright Gennadiy Rozental 2006-2014.
// Use, modification, and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// http://www.boost.org/LICENSE_1_0.txt)
@@ -40,10 +40,6 @@
# endif
-# if BOOST_WORKAROUND( BOOST_MSVC, <1300)
-# define snprintf _snprintf
-# endif
-
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::memset; using ::sprintf; }
# endif
@@ -113,7 +109,6 @@ namespace std { using ::memset; using ::sprintf; }
//____________________________________________________________________________//
namespace boost {
-
namespace debug {
using unit_test::const_string;
@@ -210,10 +205,11 @@ private:
#if defined(BOOST_SUN_BASED_DEBUG)
struct psinfo m_psi;
+ char m_binary_path_buff[500+1]; // !! ??
#elif defined(BOOST_LINUX_BASED_DEBUG)
char m_stat_line[BOOST_TEST_STAT_LINE_MAX+1];
-#endif
char m_binary_path_buff[500+1]; // !! ??
+#endif
};
//____________________________________________________________________________//
@@ -239,12 +235,12 @@ process_info::process_info( int pid )
m_binary_name.assign( m_psi.pr_fname );
//-------------------------- //
-
+
::snprintf( fname_buff, sizeof(fname_buff), "/proc/%d/as", pid );
fd_holder as_fd( ::open( fname_buff, O_RDONLY ) );
uintptr_t binary_name_pos;
-
+
// !! ?? could we avoid reading whole m_binary_path_buff?
if( as_fd == -1 ||
::lseek( as_fd, m_psi.pr_argv, SEEK_SET ) == -1 ||
@@ -252,9 +248,9 @@ process_info::process_info( int pid )
::lseek( as_fd, binary_name_pos, SEEK_SET ) == -1 ||
::read ( as_fd, m_binary_path_buff, sizeof(m_binary_path_buff) ) == -1 )
return;
-
+
m_binary_path.assign( m_binary_path_buff );
-
+
#elif defined(BOOST_LINUX_BASED_DEBUG)
char fname_buff[30];
@@ -377,8 +373,10 @@ safe_execlp( char const* file, ... )
va_start( args, file );
while( !!(arg = va_arg( args, char const* )) ) {
printf( "!! %s\n", arg );
- if( !(*argv_it++ = copy_arg( work_buff, arg )) )
+ if( !(*argv_it++ = copy_arg( work_buff, arg )) ) {
+ va_end( args );
return false;
+ }
}
va_end( args );
@@ -440,7 +438,7 @@ prepare_gdb_cmnd_file( dbg_startup_info const& dsi )
WRITE_CSTR( "\ncont" );
if( dsi.break_or_continue )
WRITE_CSTR( "\nup 4" );
-
+
WRITE_CSTR( "\necho \\n" ); // !! ??
WRITE_CSTR( "\nlist -" );
WRITE_CSTR( "\nlist" );
@@ -513,9 +511,9 @@ prepare_dbx_cmd_line( dbg_startup_info const& dsi, bool list_source = true )
{
static char cmd_line_buff[500]; // !! ??
- ::snprintf( cmd_line_buff, sizeof(cmd_line_buff), "unlink %s;cont;%s%s",
- dsi.init_done_lock.begin(),
- dsi.break_or_continue ? "up 2;": "",
+ ::snprintf( cmd_line_buff, sizeof(cmd_line_buff), "unlink %s;cont;%s%s",
+ dsi.init_done_lock.begin(),
+ dsi.break_or_continue ? "up 2;": "",
list_source ? "echo \" \";list -w3;" : "" );
return cmd_line_buff;
@@ -543,8 +541,8 @@ start_dbx_in_xterm( dbg_startup_info const& dsi )
char pid_buff[16]; // !! ??
::snprintf( pid_buff, sizeof(pid_buff), "%ld", dsi.pid );
-
- safe_execlp( "xterm", "-T", title, "-display", dsi.display.begin(),
+
+ safe_execlp( "xterm", "-T", title, "-display", dsi.display.begin(),
"-bg", "black", "-fg", "white", "-geometry", "88x30+10+10", "-fn", "9x15", "-e",
"dbx", "-q", "-c", prepare_dbx_cmd_line( dsi ), dsi.binary_path.begin(), pid_buff, 0 );
}
@@ -580,7 +578,7 @@ start_dbx_in_ddd( dbg_startup_info const& dsi )
char pid_buff[16]; // !! ??
::snprintf( pid_buff, sizeof(pid_buff), "%ld", dsi.pid );
-
+
safe_execlp( "ddd", "-display", dsi.display.begin(),
"--dbx", "-q", "-c", prepare_dbx_cmd_line( dsi, false ), dsi.binary_path.begin(), pid_buff, 0 );
}
@@ -597,7 +595,7 @@ static struct info_t {
// Public properties
unit_test::readwrite_property<std::string> p_dbg;
-
+
// Data members
std::map<std::string,dbg_starter> m_dbg_starter_reg;
} s_info;
@@ -609,7 +607,7 @@ info_t::info_t()
p_dbg.value = ::getenv( "DISPLAY" )
? std::string( BOOST_STRINGIZE( BOOST_TEST_GUI_DBG ) )
: std::string( BOOST_STRINGIZE( BOOST_TEST_CNL_DBG ) );
-
+
m_dbg_starter_reg[std::string("gdb")] = &start_gdb_in_console;
m_dbg_starter_reg[std::string("gdb-emacs")] = &start_gdb_in_emacs;
m_dbg_starter_reg[std::string("gdb-xterm")] = &start_gdb_in_xterm;
@@ -679,8 +677,7 @@ debugger_break()
#if defined(BOOST_WIN32_BASED_DEBUG) // *********************** WIN32
-#if BOOST_WORKAROUND(BOOST_MSVC, >= 1300) || \
- BOOST_WORKAROUND(__GNUC__, >= 3) && !defined(__MINGW32__) || \
+#if defined(__GNUC__) && !defined(__MINGW32__) || \
defined(__INTEL_COMPILER)
# define BOOST_DEBUG_BREAK __debugbreak
#else
@@ -734,7 +731,7 @@ set_debugger( unit_test::const_string dbg_id, dbg_starter s )
assign_op( s_info.p_dbg.value, dbg_id, 0 );
if( !!s )
- s_info.m_dbg_starter_reg[s_info.p_dbg] = s;
+ s_info.m_dbg_starter_reg[s_info.p_dbg.get()] = s;
return old;
}
@@ -864,7 +861,7 @@ attach_debugger( bool break_or_continue )
if( init_done_lock_fd == -1 )
return false;
-
+
pid_t child_pid = fork();
if( child_pid == -1 )
@@ -872,7 +869,7 @@ attach_debugger( bool break_or_continue )
if( child_pid != 0 ) { // parent process - here we will start the debugger
dbg_startup_info dsi;
-
+
process_info pi( child_pid );
if( pi.binary_path().is_empty() )
::exit( -1 );
@@ -882,7 +879,7 @@ attach_debugger( bool break_or_continue )
dsi.binary_path = pi.binary_path();
dsi.display = ::getenv( "DISPLAY" );
dsi.init_done_lock = init_done_lock_fn;
-
+
dbg_starter starter = s_info.m_dbg_starter_reg[s_info.p_dbg];
if( !!starter )
starter( dsi );
@@ -922,7 +919,7 @@ attach_debugger( bool break_or_continue )
// ************************************************************************** //
void
-detect_memory_leaks( bool on_off )
+detect_memory_leaks( bool on_off, unit_test::const_string report_file )
{
unit_test::ut_detail::ignore_unused_variable_warning( on_off );
@@ -934,10 +931,19 @@ detect_memory_leaks( bool on_off )
else {
flags |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
- _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
+
+ if( report_file.is_empty() )
+ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
+ else {
+ HANDLE hreport_f = ::CreateFileA( report_file.begin(),
+ GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ _CrtSetReportFile(_CRT_WARN, hreport_f );
+ }
}
_CrtSetDbgFlag ( flags );
+#else
+ unit_test::ut_detail::ignore_unused_variable_warning( report_file );
#endif // BOOST_MS_CRT_BASED_DEBUG
}
@@ -954,16 +960,17 @@ break_memory_alloc( long mem_alloc_order_num )
unit_test::ut_detail::ignore_unused_variable_warning( mem_alloc_order_num );
#ifdef BOOST_MS_CRT_BASED_DEBUG
- _CrtSetBreakAlloc( mem_alloc_order_num );
+ // only set the value if one was supplied (do not use default used by UTF just as a indicator to enable leak detection)
+ if( mem_alloc_order_num > 1 )
+ _CrtSetBreakAlloc( mem_alloc_order_num );
#endif // BOOST_MS_CRT_BASED_DEBUG
}
-} // namespace debug
+//____________________________________________________________________________//
+} // namespace debug
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_DEBUG_API_IPP_112006GER
diff --git a/boost/test/impl/decorator.ipp b/boost/test/impl/decorator.ipp
new file mode 100644
index 0000000000..bf17907881
--- /dev/null
+++ b/boost/test/impl/decorator.ipp
@@ -0,0 +1,202 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision$
+//
+// Description : unit test decorators implementation
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TREE_DECORATOR_IPP_091911GER
+#define BOOST_TEST_TREE_DECORATOR_IPP_091911GER
+
+// Boost.Test
+#include <boost/test/tree/decorator.hpp>
+#include <boost/test/tree/test_unit.hpp>
+
+#include <boost/test/framework.hpp>
+#if BOOST_TEST_SUPPORT_TOKEN_ITERATOR
+#include <boost/test/utils/iterator/token_iterator.hpp>
+#endif
+
+#include <boost/test/detail/throw_exception.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace decorator {
+
+// ************************************************************************** //
+// ************** decorator::collector ************** //
+// ************************************************************************** //
+
+collector&
+collector::operator*( base const& d )
+{
+ m_tu_decorators.push_back( d.clone() );
+
+ return *this;
+}
+
+//____________________________________________________________________________//
+
+void
+collector::store_in( test_unit& tu )
+{
+ tu.p_decorators.value.insert( tu.p_decorators.value.end(), m_tu_decorators.begin(), m_tu_decorators.end() );
+}
+
+//____________________________________________________________________________//
+
+void
+collector::reset()
+{
+ m_tu_decorators.clear();
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** decorator::base ************** //
+// ************************************************************************** //
+
+collector&
+base::operator*() const
+{
+ return collector::instance() * *this;
+}
+
+// ************************************************************************** //
+// ************** decorator::label ************** //
+// ************************************************************************** //
+
+void
+label::apply( test_unit& tu )
+{
+ tu.add_label( m_label );
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** decorator::expected_failures ************** //
+// ************************************************************************** //
+
+void
+expected_failures::apply( test_unit& tu )
+{
+ tu.increase_exp_fail( m_exp_fail );
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** decorator::timeout ************** //
+// ************************************************************************** //
+
+void
+timeout::apply( test_unit& tu )
+{
+ tu.p_timeout.value = m_timeout;
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** decorator::description ************** //
+// ************************************************************************** //
+
+void
+description::apply( test_unit& tu )
+{
+ tu.p_description.value += m_description;
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** decorator::depends_on ************** //
+// ************************************************************************** //
+
+void
+depends_on::apply( test_unit& tu )
+{
+#if !BOOST_TEST_SUPPORT_TOKEN_ITERATOR
+ BOOST_TEST_SETUP_ASSERT( false, "depends_on decorator is not supported on this platform" );
+#else
+ string_token_iterator tit( m_dependency, (dropped_delimeters = "/", kept_delimeters = dt_none) );
+
+ test_unit* dep = &framework::master_test_suite();
+ while( tit != string_token_iterator() ) {
+ BOOST_TEST_SETUP_ASSERT( dep->p_type == TUT_SUITE, std::string( "incorrect dependency specification " ) + m_dependency );
+
+ test_unit_id next_id = static_cast<test_suite*>(dep)->get( *tit );
+
+ BOOST_TEST_SETUP_ASSERT( next_id != INV_TEST_UNIT_ID,
+ std::string( "incorrect dependency specification " ) + m_dependency );
+
+ dep = &framework::get( next_id, TUT_ANY );
+ ++tit;
+ }
+
+ tu.depends_on( dep );
+#endif
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** decorator::enable_if/enabled/disabled ************** //
+// ************************************************************************** //
+
+void
+enable_if_impl::apply_impl( test_unit& tu, bool condition )
+{
+ BOOST_TEST_SETUP_ASSERT(tu.p_default_status == test_unit::RS_INHERIT,
+ "Can't apply multiple enabled/disabled decorators "
+ "to the same test unit " + tu.full_name());
+
+ tu.p_default_status.value = condition ? test_unit::RS_ENABLED : test_unit::RS_DISABLED;
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** decorator::fixture ************** //
+// ************************************************************************** //
+
+void
+fixture_t::apply( test_unit& tu )
+{
+ tu.p_fixtures.value.push_back( m_impl );
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** decorator::depends_on ************** //
+// ************************************************************************** //
+
+void
+precondition::apply( test_unit& tu )
+{
+ tu.add_precondition( m_precondition );
+}
+
+//____________________________________________________________________________//
+
+} // namespace decorator
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TREE_DECORATOR_IPP_091911GER
diff --git a/boost/test/impl/exception_safety.ipp b/boost/test/impl/exception_safety.ipp
deleted file mode 100644
index 7f0afcb457..0000000000
--- a/boost/test/impl/exception_safety.ipp
+++ /dev/null
@@ -1,537 +0,0 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
-// http://www.boost.org/LICENSE_1_0.txt)
-
-// See http://www.boost.org/libs/test for the library home page.
-//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : Facilities to perform exception safety tests
-// ***************************************************************************
-
-#ifndef BOOST_TEST_EXECUTION_SAFETY_IPP_112005GER
-#define BOOST_TEST_EXECUTION_SAFETY_IPP_112005GER
-
-// Boost.Test
-#include <boost/test/detail/config.hpp>
-
-#if BOOST_TEST_SUPPORT_INTERACTION_TESTING
-
-#include <boost/test/detail/global_typedef.hpp>
-#include <boost/test/detail/unit_test_parameters.hpp>
-
-#include <boost/test/utils/callback.hpp>
-#include <boost/test/utils/wrap_stringstream.hpp>
-#include <boost/test/utils/iterator/token_iterator.hpp>
-
-#include <boost/test/interaction_based.hpp>
-#include <boost/test/test_tools.hpp>
-#include <boost/test/unit_test_log.hpp>
-#include <boost/test/framework.hpp>
-#include <boost/test/test_observer.hpp>
-#include <boost/test/debug.hpp>
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-// Boost
-#include <boost/lexical_cast.hpp>
-
-// STL
-#include <vector>
-#include <cstdlib>
-#include <map>
-#include <iomanip>
-#include <cctype>
-#include <boost/limits.hpp>
-
-//____________________________________________________________________________//
-
-namespace boost {
-
-using namespace ::boost::unit_test;
-
-namespace itest {
-
-// ************************************************************************** //
-// ************** execution_path_point ************** //
-// ************************************************************************** //
-
-enum exec_path_point_type { EPP_SCOPE, EPP_EXCEPT, EPP_DECISION, EPP_ALLOC };
-
-struct execution_path_point {
- execution_path_point( exec_path_point_type t, const_string file, std::size_t line_num )
- : m_type( t )
- , m_file_name( file )
- , m_line_num( line_num )
- {}
-
- exec_path_point_type m_type;
- const_string m_file_name;
- std::size_t m_line_num;
-
- // Execution path point specific
- struct decision_data {
- bool value;
- unsigned forced_exception_point;
- };
- struct scope_data {
- unsigned size;
- char const* name;
- };
- struct except_data {
- char const* description;
- };
- struct alloc_data {
- void* ptr;
- std::size_t size;
- };
-
- union {
- struct decision_data m_decision;
- struct scope_data m_scope;
- struct except_data m_except;
- struct alloc_data m_alloc;
- };
-};
-
-// ************************************************************************** //
-// ************** exception safety test implementation ************** //
-// ************************************************************************** //
-
-struct exception_safety_tester : itest::manager, test_observer {
- // helpers types
- struct unique_exception {};
-
- // Constructor
- explicit exception_safety_tester( const_string test_name );
- ~exception_safety_tester();
-
- // check last run and prepare for next
- bool next_execution_path();
-
- // memory tracking
-
- // manager interface implementation
- virtual void exception_point( const_string file, std::size_t line_num, const_string description );
- virtual bool decision_point( const_string file, std::size_t line_num );
- virtual unsigned enter_scope( const_string file, std::size_t line_num, const_string scope_name );
- virtual void leave_scope( unsigned enter_scope_point );
- virtual void allocated( const_string file, std::size_t line_num, void* p, std::size_t s );
- virtual void freed( void* p );
-
- // test observer interface
- virtual void assertion_result( bool passed );
- virtual int priority() { return (std::numeric_limits<int>::max)(); } // we want this observer to run the last
-
-private:
- void failure_point();
- void report_error();
-
- typedef std::vector<execution_path_point> exec_path;
- typedef std::map<void*,unsigned> registry;
-
- // Data members
- bool m_internal_activity;
-
- unsigned m_exception_point_counter;
- unsigned m_forced_exception_point;
-
- unsigned m_exec_path_point;
- exec_path m_execution_path;
-
- unsigned m_exec_path_counter;
- unsigned m_break_exec_path;
-
- bool m_invairant_failed;
- registry m_memory_in_use;
-};
-
-//____________________________________________________________________________//
-
-struct activity_guard {
- bool& m_v;
-
- activity_guard( bool& v ) : m_v( v ) { m_v = true; }
- ~activity_guard() { m_v = false; }
-};
-
-//____________________________________________________________________________//
-
-exception_safety_tester::exception_safety_tester( const_string test_name )
-: m_internal_activity( true )
-, m_exception_point_counter( 0 )
-, m_forced_exception_point( 1 )
-, m_exec_path_point( 0 )
-, m_exec_path_counter( 1 )
-, m_break_exec_path( static_cast<unsigned>(-1) )
-, m_invairant_failed( false )
-{
- framework::register_observer( *this );
-
- if( !runtime_config::break_exec_path().is_empty() ) {
- using namespace unit_test;
-
- string_token_iterator tit( runtime_config::break_exec_path(),
- (dropped_delimeters = ":",kept_delimeters = " ") );
-
- const_string test_to_break = *tit;
-
- if( test_to_break == test_name ) {
- ++tit;
-
- m_break_exec_path = lexical_cast<unsigned>( *tit );
- }
- }
-
- m_internal_activity = false;
-}
-
-//____________________________________________________________________________//
-
-exception_safety_tester::~exception_safety_tester()
-{
- m_internal_activity = true;
-
- framework::deregister_observer( *this );
-}
-
-//____________________________________________________________________________//
-
-bool
-exception_safety_tester::next_execution_path()
-{
- activity_guard ag( m_internal_activity );
-
- // check memory usage
- if( m_execution_path.size() > 0 ) {
- bool errors_detected = m_invairant_failed || (m_memory_in_use.size() != 0);
- framework::assertion_result( !errors_detected );
-
- if( errors_detected )
- report_error();
-
- m_memory_in_use.clear();
- }
-
- m_exec_path_point = 0;
- m_exception_point_counter = 0;
- m_invairant_failed = false;
- ++m_exec_path_counter;
-
- while( m_execution_path.size() > 0 ) {
- switch( m_execution_path.back().m_type ) {
- case EPP_SCOPE:
- case EPP_ALLOC:
- m_execution_path.pop_back();
- break;
-
- case EPP_DECISION:
- if( !m_execution_path.back().m_decision.value ) {
- m_execution_path.pop_back();
- break;
- }
-
- m_execution_path.back().m_decision.value = false;
- m_forced_exception_point = m_execution_path.back().m_decision.forced_exception_point;
- return true;
-
- case EPP_EXCEPT:
- m_execution_path.pop_back();
- ++m_forced_exception_point;
- return true;
- }
- }
-
- BOOST_TEST_MESSAGE( "Total tested " << --m_exec_path_counter << " execution path" );
-
- return false;
-}
-
-//____________________________________________________________________________//
-
-void
-exception_safety_tester::exception_point( const_string file, std::size_t line_num, const_string description )
-{
- activity_guard ag( m_internal_activity );
-
- if( ++m_exception_point_counter == m_forced_exception_point ) {
- m_execution_path.push_back(
- execution_path_point( EPP_EXCEPT, file, line_num ) );
-
- m_execution_path.back().m_except.description = description.begin();
-
- ++m_exec_path_point;
-
- failure_point();
- }
-}
-
-//____________________________________________________________________________//
-
-bool
-exception_safety_tester::decision_point( const_string file, std::size_t line_num )
-{
- activity_guard ag( m_internal_activity );
-
- if( m_exec_path_point < m_execution_path.size() ) {
- BOOST_REQUIRE_MESSAGE( m_execution_path[m_exec_path_point].m_type == EPP_DECISION &&
- m_execution_path[m_exec_path_point].m_file_name == file &&
- m_execution_path[m_exec_path_point].m_line_num == line_num,
- "Function under test exibit non-deterministic behavior" );
- }
- else {
- m_execution_path.push_back(
- execution_path_point( EPP_DECISION, file, line_num ) );
-
- m_execution_path.back().m_decision.value = true;
- m_execution_path.back().m_decision.forced_exception_point = m_forced_exception_point;
- }
-
- return m_execution_path[m_exec_path_point++].m_decision.value;
-}
-
-//____________________________________________________________________________//
-
-unsigned
-exception_safety_tester::enter_scope( const_string file, std::size_t line_num, const_string scope_name )
-{
- activity_guard ag( m_internal_activity );
-
- if( m_exec_path_point < m_execution_path.size() ) {
- BOOST_REQUIRE_MESSAGE( m_execution_path[m_exec_path_point].m_type == EPP_SCOPE &&
- m_execution_path[m_exec_path_point].m_file_name == file &&
- m_execution_path[m_exec_path_point].m_line_num == line_num,
- "Function under test exibit non-deterministic behavior" );
- }
- else {
- m_execution_path.push_back(
- execution_path_point( EPP_SCOPE, file, line_num ) );
- }
-
- m_execution_path[m_exec_path_point].m_scope.size = 0;
- m_execution_path[m_exec_path_point].m_scope.name = scope_name.begin();
-
- return m_exec_path_point++;
-}
-
-//____________________________________________________________________________//
-
-void
-exception_safety_tester::leave_scope( unsigned enter_scope_point )
-{
- activity_guard ag( m_internal_activity );
-
- BOOST_REQUIRE_MESSAGE( m_execution_path[enter_scope_point].m_type == EPP_SCOPE,
- "Function under test exibit non-deterministic behavior" );
-
- m_execution_path[enter_scope_point].m_scope.size = m_exec_path_point - enter_scope_point;
-}
-
-//____________________________________________________________________________//
-
-void
-exception_safety_tester::allocated( const_string file, std::size_t line_num, void* p, std::size_t s )
-{
- if( m_internal_activity )
- return;
-
- activity_guard ag( m_internal_activity );
-
- if( m_exec_path_point < m_execution_path.size() )
- BOOST_REQUIRE_MESSAGE( m_execution_path[m_exec_path_point].m_type == EPP_ALLOC,
- "Function under test exibit non-deterministic behavior" );
- else
- m_execution_path.push_back(
- execution_path_point( EPP_ALLOC, file, line_num ) );
-
- m_execution_path[m_exec_path_point].m_alloc.ptr = p;
- m_execution_path[m_exec_path_point].m_alloc.size = s;
-
- m_memory_in_use.insert( std::make_pair( p, m_exec_path_point++ ) );
-}
-
-//____________________________________________________________________________//
-
-void
-exception_safety_tester::freed( void* p )
-{
- if( m_internal_activity )
- return;
-
- activity_guard ag( m_internal_activity );
-
- registry::iterator it = m_memory_in_use.find( p );
- if( it != m_memory_in_use.end() ) {
- m_execution_path[it->second].m_alloc.ptr = 0;
- m_memory_in_use.erase( it );
- }
-}
-
-//____________________________________________________________________________//
-
-void
-exception_safety_tester::assertion_result( bool passed )
-{
- if( !m_internal_activity && !passed ) {
- m_invairant_failed = true;
-
- failure_point();
- }
-}
-
-//____________________________________________________________________________//
-
-void
-exception_safety_tester::failure_point()
-{
- if( m_exec_path_counter == m_break_exec_path )
- debug::debugger_break();
-
- throw unique_exception();
-}
-
-//____________________________________________________________________________//
-
-namespace {
-
-inline void
-format_location( wrap_stringstream& formatter, execution_path_point const& /*p*/, unsigned indent )
-{
- if( indent )
- formatter << std::left << std::setw( indent ) << "";
-
-// !! ?? optional if( p.m_file_name )
-// formatter << p.m_file_name << '(' << p.m_line_num << "): ";
-}
-
-//____________________________________________________________________________//
-
-template<typename ExecPathIt>
-inline void
-format_execution_path( wrap_stringstream& formatter, ExecPathIt it, ExecPathIt end, unsigned indent = 0 )
-{
- while( it != end ) {
- switch( it->m_type ) {
- case EPP_SCOPE:
- format_location( formatter, *it, indent );
- formatter << "> \"" << it->m_scope.name << "\"\n";
- format_execution_path( formatter, it+1, it + it->m_scope.size, indent + 2 );
- format_location( formatter, *it, indent );
- formatter << "< \"" << it->m_scope.name << "\"\n";
- it += it->m_scope.size;
- break;
-
- case EPP_DECISION:
- format_location( formatter, *it, indent );
- formatter << "Decision made as " << std::boolalpha << it->m_decision.value << '\n';
- ++it;
- break;
-
- case EPP_EXCEPT:
- format_location( formatter, *it, indent );
- formatter << "Forced failure";
- if( it->m_except.description )
- formatter << ": " << it->m_except.description;
- formatter << "\n";
- ++it;
- break;
-
- case EPP_ALLOC:
- if( it->m_alloc.ptr ) {
- format_location( formatter, *it, indent );
- formatter << "Allocated memory block 0x" << std::uppercase << it->m_alloc.ptr
- << ", " << it->m_alloc.size << " bytes long: <";
-
- unsigned i;
- for( i = 0; i < std::min<std::size_t>( it->m_alloc.size, 8 ); i++ ) {
- unsigned char c = static_cast<unsigned char*>(it->m_alloc.ptr)[i];
- if( (std::isprint)( c ) )
- formatter << c;
- else
- formatter << '.';
- }
-
- formatter << "> ";
-
- for( i = 0; i < std::min<std::size_t>( it->m_alloc.size, 8 ); i++ ) {
- unsigned c = static_cast<unsigned char*>(it->m_alloc.ptr)[i];
- formatter << std::hex << std::uppercase << c << ' ';
- }
-
- formatter << "\n";
- }
- ++it;
- break;
- }
- }
-}
-
-//____________________________________________________________________________//
-
-} // local namespace
-
-void
-exception_safety_tester::report_error()
-{
- activity_guard ag( m_internal_activity );
-
- unit_test_log << unit_test::log::begin( m_execution_path.back().m_file_name,
- m_execution_path.back().m_line_num )
- << log_all_errors;
-
- wrap_stringstream formatter;
-
- if( m_invairant_failed )
- formatter << "Failed invariant";
-
- if( m_memory_in_use.size() != 0 ) {
- if( m_invairant_failed )
- formatter << " and ";
-
- formatter << static_cast<unsigned int>(m_memory_in_use.size()) << " memory leak";
- if( m_memory_in_use.size() > 1 )
- formatter << 's';
- }
- formatter << " detected in the execution path " << m_exec_path_counter << ":\n";
-
- format_execution_path( formatter, m_execution_path.begin(), m_execution_path.end() );
-
- unit_test_log << const_string( formatter.str() ) << unit_test::log::end();
-}
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** exception safety test ************** //
-// ************************************************************************** //
-
-void BOOST_TEST_DECL
-exception_safety( callback0<> const& F, const_string test_name )
-{
- exception_safety_tester est( test_name );
-
- do {
- try {
- F();
- }
- catch( exception_safety_tester::unique_exception const& ) {}
-
- } while( est.next_execution_path() );
-}
-
-//____________________________________________________________________________//
-
-} // namespace itest
-
-} // namespace boost
-
-//____________________________________________________________________________//
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // non-ancient compiler
-
-#endif // BOOST_TEST_EXECUTION_SAFETY_IPP_112005GER
diff --git a/boost/test/impl/execution_monitor.ipp b/boost/test/impl/execution_monitor.ipp
index 07484b19d9..9929f74b53 100644
--- a/boost/test/impl/execution_monitor.ipp
+++ b/boost/test/impl/execution_monitor.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// (C) Copyright Beman Dawes and Ullrich Koethe 1995-2001.
// Use, modification, and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
@@ -27,14 +27,18 @@
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/workaround.hpp>
+#include <boost/test/detail/throw_exception.hpp>
#include <boost/test/execution_monitor.hpp>
#include <boost/test/debug.hpp>
// Boost
#include <boost/cstdlib.hpp> // for exit codes
#include <boost/config.hpp> // for workarounds
+#include <boost/core/ignore_unused.hpp> // for ignore_unused
+#ifndef BOOST_NO_EXCEPTION
#include <boost/exception/get_error_info.hpp> // for get_error_info
#include <boost/exception/current_exception_cast.hpp> // for current_exception_cast
+#endif
// STL
#include <string> // for std::string
@@ -48,6 +52,8 @@
#include <cstdio> // for vsnprintf
#include <cstdarg> // for varargs
+#include <iostream> // for varargs
+
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::strerror; using ::strlen; using ::strncat; }
#endif
@@ -59,17 +65,12 @@ namespace std { using ::strerror; using ::strlen; using ::strncat; }
using std::va_list;
#endif
-// to use vsnprintf
-#if defined(__QNXNTO__)
-# include <stdio.h>
+// to use vsnprintf
+#if defined(__QNXNTO__)
+# include <stdio.h>
#endif
-#if defined(_WIN32) && !defined(BOOST_DISABLE_WIN32) && \
- (!defined(__COMO__) && !defined(__MWERKS__) && !defined(__GNUC__) || \
- BOOST_WORKAROUND(__MWERKS__, >= 0x3000))
-
-# define BOOST_SEH_BASED_SIGNAL_HANDLING
-
+#ifdef BOOST_SEH_BASED_SIGNAL_HANDLING
# include <windows.h>
# if defined(__MWERKS__) || (defined(_MSC_VER) && !defined(UNDER_CE))
@@ -84,37 +85,12 @@ using std::va_list;
typedef unsigned uintptr_t;
# endif
-# if BOOST_WORKAROUND(_MSC_VER, < 1300 ) || defined(UNDER_CE)
-typedef void* uintptr_t;
+# if defined(UNDER_CE) && BOOST_WORKAROUND(_MSC_VER, < 1500 )
+ typedef void* uintptr_t;
+# elif defined(UNDER_CE)
+# include <crtdefs.h>
# endif
-// for the FP control routines
-#include <float.h>
-
-#ifndef EM_INVALID
-#define EM_INVALID _EM_INVALID
-#endif
-
-#ifndef EM_DENORMAL
-#define EM_DENORMAL _EM_DENORMAL
-#endif
-
-#ifndef EM_ZERODIVIDE
-#define EM_ZERODIVIDE _EM_ZERODIVIDE
-#endif
-
-#ifndef EM_OVERFLOW
-#define EM_OVERFLOW _EM_OVERFLOW
-#endif
-
-#ifndef EM_UNDERFLOW
-#define EM_UNDERFLOW _EM_UNDERFLOW
-#endif
-
-#ifndef MCW_EM
-#define MCW_EM _MCW_EM
-#endif
-
# if !defined(NDEBUG) && defined(_MSC_VER) && !defined(UNDER_CE)
# include <crtdbg.h>
# define BOOST_TEST_CRT_HOOK_TYPE _CRT_REPORT_HOOK
@@ -128,7 +104,8 @@ typedef void* uintptr_t;
# define BOOST_TEST_CRT_SET_HOOK(H) (void*)(H)
# endif
-# if !BOOST_WORKAROUND(_MSC_VER, >= 1400 ) || defined(UNDER_CE)
+# if (!BOOST_WORKAROUND(_MSC_VER, >= 1400 ) && \
+ !defined(BOOST_COMO)) || defined(UNDER_CE)
typedef void* _invalid_parameter_handler;
@@ -154,7 +131,9 @@ namespace { void _set_se_translator( void* ) {} }
# include <signal.h>
# include <setjmp.h>
-# if defined(__FreeBSD__)
+# if defined(__FreeBSD__)
+
+# include <osreldate.h>
# ifndef SIGPOLL
# define SIGPOLL SIGIO
@@ -168,13 +147,17 @@ namespace { void _set_se_translator( void* ) {} }
# define ILL_COPROC ILL_FPOP_FAULT
# define BOOST_TEST_LIMITED_SIGNAL_DETAILS
-# define BOOST_TEST_IGNORE_SIGCHLD
-# endif
-# endif
+# endif
+# endif
+
+# if defined(__ANDROID__)
+# include <android/api-level.h>
+# endif
-# if !defined(__CYGWIN__) && !defined(__QNXNTO__)
-# define BOOST_TEST_USE_ALT_STACK
+# if !defined(__CYGWIN__) && !defined(__QNXNTO__) && !defined(__bgq__) && \
+ (!defined(__ANDROID__) || __ANDROID_API__ >= 8)
+# define BOOST_TEST_USE_ALT_STACK
# endif
# if defined(SIGPOLL) && !defined(__CYGWIN__) && \
@@ -188,6 +171,7 @@ namespace { void _set_se_translator( void* ) {} }
# define BOOST_TEST_ALT_STACK_SIZE SIGSTKSZ
# endif
+
#else
# define BOOST_NO_SIGNAL_HANDLING
@@ -198,6 +182,10 @@ namespace { void _set_se_translator( void* ) {} }
#include <errno.h>
#endif
+#if defined(__GNUC__) && !defined(BOOST_NO_TYPEID)
+# include <cxxabi.h>
+#endif
+
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
@@ -205,6 +193,14 @@ namespace { void _set_se_translator( void* ) {} }
namespace boost {
// ************************************************************************** //
+// ************** throw_exception ************** //
+// ************************************************************************** //
+
+#ifdef BOOST_NO_EXCEPTION
+void throw_exception( std::exception const & e ) { abort(); }
+#endif
+
+// ************************************************************************** //
// ************** report_error ************** //
// ************************************************************************** //
@@ -220,6 +216,8 @@ namespace detail {
# define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) vsnprintf( (a1), (a2), (a3), (a4) )
#endif
+#ifndef BOOST_NO_EXCEPTION
+
template <typename ErrorInfo>
typename ErrorInfo::value_type
extract( boost::exception const* ex )
@@ -237,39 +235,41 @@ extract( boost::exception const* ex )
static void
report_error( execution_exception::error_code ec, boost::exception const* be, char const* format, va_list* args )
{
- static const int REPORT_ERROR_BUFFER_SIZE = 512;
+ static const int REPORT_ERROR_BUFFER_SIZE = 4096;
static char buf[REPORT_ERROR_BUFFER_SIZE];
- BOOST_TEST_VSNPRINTF( buf, sizeof(buf)-1, format, *args );
+ BOOST_TEST_VSNPRINTF( buf, sizeof(buf)-1, format, *args );
buf[sizeof(buf)-1] = 0;
va_end( *args );
- throw execution_exception( ec, buf, execution_exception::location( extract<throw_file>( be ),
- extract<throw_line>( be ),
+ throw execution_exception( ec, buf, execution_exception::location( extract<throw_file>( be ),
+ (size_t)extract<throw_line>( be ),
extract<throw_function>( be ) ) );
}
//____________________________________________________________________________//
static void
-report_error( execution_exception::error_code ec, char const* format, ... )
+report_error( execution_exception::error_code ec, boost::exception const* be, char const* format, ... )
{
va_list args;
va_start( args, format );
- report_error( ec, 0, format, &args );
+ report_error( ec, be, format, &args );
}
+#endif
+
//____________________________________________________________________________//
static void
-report_error( execution_exception::error_code ec, boost::exception const* be, char const* format, ... )
+report_error( execution_exception::error_code ec, char const* format, ... )
{
va_list args;
va_start( args, format );
- report_error( ec, be, format, &args );
+ report_error( ec, 0, format, &args );
}
//____________________________________________________________________________//
@@ -283,6 +283,47 @@ do_invoke( Tr const& tr, Functor const& F )
//____________________________________________________________________________//
+struct fpe_except_guard {
+ explicit fpe_except_guard( unsigned detect_fpe )
+ : m_detect_fpe( detect_fpe )
+ {
+ // prepare fp exceptions control
+ m_previosly_enabled = fpe::disable( fpe::BOOST_FPE_ALL );
+ if( m_previosly_enabled != fpe::BOOST_FPE_INV && detect_fpe != fpe::BOOST_FPE_OFF )
+ fpe::enable( detect_fpe );
+ }
+ ~fpe_except_guard()
+ {
+ if( m_detect_fpe != fpe::BOOST_FPE_OFF )
+ fpe::disable( m_detect_fpe );
+ if( m_previosly_enabled != fpe::BOOST_FPE_INV )
+ fpe::enable( m_previosly_enabled );
+ }
+
+ unsigned m_detect_fpe;
+ unsigned m_previosly_enabled;
+};
+
+#ifndef BOOST_NO_TYPEID
+
+// ************************************************************************** //
+// ************** typeid_name ************** //
+// ************************************************************************** //
+
+template<typename T>
+char const*
+typeid_name( T const& t )
+{
+#ifdef __GNUC__
+ int status;
+
+ return abi::__cxa_demangle( typeid(t).name(), 0, 0, &status );
+#else
+ return typeid(t).name();
+#endif
+}
+#endif
+
} // namespace detail
#if defined(BOOST_SIGACTION_BASED_SIGNAL_HANDLING)
@@ -398,10 +439,10 @@ system_signal_exception::report() const
"signal: co-processor error; address of failing instruction: 0x%08lx",
m_sig_info->si_addr );
break;
- default:
- report_error( execution_exception::system_fatal_error,
- "signal: SIGILL, si_code: %d (illegal instruction; address of failing instruction: 0x%08lx)",
- m_sig_info->si_addr, m_sig_info->si_code );
+ default:
+ report_error( execution_exception::system_fatal_error,
+ "signal: SIGILL, si_code: %d (illegal instruction; address of failing instruction: 0x%08lx)",
+ m_sig_info->si_addr, m_sig_info->si_code );
break;
}
break;
@@ -505,48 +546,6 @@ system_signal_exception::report() const
}
break;
- case SIGCHLD:
- switch( m_sig_info->si_code ) {
-#ifndef BOOST_TEST_LIMITED_SIGNAL_DETAILS
- case CLD_EXITED:
- report_error( execution_exception::system_error,
- "child has exited; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
- break;
- case CLD_KILLED:
- report_error( execution_exception::system_error,
- "child was killed; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
- break;
- case CLD_DUMPED:
- report_error( execution_exception::system_error,
- "child terminated abnormally; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
- break;
- case CLD_TRAPPED:
- report_error( execution_exception::system_error,
- "traced child has trapped; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
- break;
- case CLD_STOPPED:
- report_error( execution_exception::system_error,
- "child has stopped; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
- break;
- case CLD_CONTINUED:
- report_error( execution_exception::system_error,
- "stopped child had continued; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
- break;
-#endif
- default:
- report_error( execution_exception::system_error,
- "signal: SIGCHLD, si_code: %d (child process has terminated; pid: %d; uid: %d; exit value: %d)",
- (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status, m_sig_info->si_code );
- break;
- }
- break;
-
#if defined(BOOST_TEST_CATCH_SIGPOLL)
case SIGPOLL:
@@ -585,11 +584,11 @@ system_signal_exception::report() const
break;
#endif
#endif
- default:
- report_error( execution_exception::system_error,
- "signal: SIGPOLL, si_code: %d (asynchronous I/O event occured; band event %d)",
- (int)m_sig_info->si_band, m_sig_info->si_code );
- break;
+ default:
+ report_error( execution_exception::system_error,
+ "signal: SIGPOLL, si_code: %d (asynchronous I/O event occurred; band event %d)",
+ (int)m_sig_info->si_band, m_sig_info->si_code );
+ break;
}
break;
@@ -606,7 +605,8 @@ system_signal_exception::report() const
break;
default:
- report_error( execution_exception::system_error, "unrecognized signal" );
+ report_error( execution_exception::system_error,
+ "unrecognized signal %d", m_sig_info->si_signo );
}
}
@@ -618,8 +618,8 @@ system_signal_exception::report() const
// Forward declaration
extern "C" {
-static void execution_monitor_jumping_signal_handler( int sig, siginfo_t* info, void* context );
-static void execution_monitor_attaching_signal_handler( int sig, siginfo_t* info, void* context );
+static void boost_execution_monitor_jumping_signal_handler( int sig, siginfo_t* info, void* context );
+static void boost_execution_monitor_attaching_signal_handler( int sig, siginfo_t* info, void* context );
}
class signal_action {
@@ -663,8 +663,8 @@ signal_action::signal_action( int sig, bool install, bool attach_dbg, char* alt_
}
m_new_action.sa_flags |= SA_SIGINFO;
- m_new_action.sa_sigaction = attach_dbg ? &execution_monitor_attaching_signal_handler
- : &execution_monitor_jumping_signal_handler;
+ m_new_action.sa_sigaction = attach_dbg ? &boost_execution_monitor_attaching_signal_handler
+ : &boost_execution_monitor_jumping_signal_handler;
BOOST_TEST_SYS_ASSERT( sigemptyset( &m_new_action.sa_mask ) != -1 );
#ifdef BOOST_TEST_USE_ALT_STACK
@@ -692,7 +692,7 @@ signal_action::~signal_action()
class signal_handler {
public:
// Constructor
- explicit signal_handler( bool catch_system_errors, int timeout, bool attach_dbg, char* alt_stack );
+ explicit signal_handler( bool catch_system_errors, bool detect_fpe, unsigned timeout, bool attach_dbg, char* alt_stack );
// Destructor
~signal_handler();
@@ -715,8 +715,9 @@ public:
private:
// Data members
signal_handler* m_prev_handler;
- int m_timeout;
+ unsigned m_timeout;
+ // Note: We intentionality do not catch SIGCHLD. Users have to deal with it themselves
signal_action m_ILL_action;
signal_action m_FPE_action;
signal_action m_SEGV_action;
@@ -738,16 +739,13 @@ signal_handler* signal_handler::s_active_handler = signal_handler_ptr();
//____________________________________________________________________________//
-signal_handler::signal_handler( bool catch_system_errors, int timeout, bool attach_dbg, char* alt_stack )
+signal_handler::signal_handler( bool catch_system_errors, bool detect_fpe, unsigned timeout, bool attach_dbg, char* alt_stack )
: m_prev_handler( s_active_handler )
, m_timeout( timeout )
, m_ILL_action ( SIGILL , catch_system_errors, attach_dbg, alt_stack )
-, m_FPE_action ( SIGFPE , catch_system_errors, attach_dbg, alt_stack )
+, m_FPE_action ( SIGFPE , detect_fpe , attach_dbg, alt_stack )
, m_SEGV_action( SIGSEGV, catch_system_errors, attach_dbg, alt_stack )
, m_BUS_action ( SIGBUS , catch_system_errors, attach_dbg, alt_stack )
-#ifndef BOOST_TEST_IGNORE_SIGCHLD
-, m_CHLD_action( SIGCHLD, catch_system_errors, attach_dbg, alt_stack )
-#endif
#ifdef BOOST_TEST_CATCH_SIGPOLL
, m_POLL_action( SIGPOLL, catch_system_errors, attach_dbg, alt_stack )
#endif
@@ -799,7 +797,12 @@ signal_handler::~signal_handler()
sigstk.ss_size = MINSIGSTKSZ;
sigstk.ss_flags = SS_DISABLE;
- BOOST_TEST_SYS_ASSERT( ::sigaltstack( &sigstk, 0 ) != -1 );
+ if( ::sigaltstack( &sigstk, 0 ) == -1 ) {
+ int error_n = errno;
+ std::cerr << "******** errors disabling the alternate stack:" << std::endl
+ << "\t#error:" << error_n << std::endl
+ << "\t" << std::strerror( error_n ) << std::endl;
+ }
#endif
s_active_handler = m_prev_handler;
@@ -813,26 +816,8 @@ signal_handler::~signal_handler()
extern "C" {
-static bool ignore_sigchild( siginfo_t* info )
-{
- return info->si_signo == SIGCHLD
-#ifndef BOOST_TEST_LIMITED_SIGNAL_DETAILS
- && info->si_code == CLD_EXITED
-#endif
-#ifdef BOOST_TEST_IGNORE_NON_ZERO_CHILD_CODE
- ;
-#else
- && (int)info->si_status == 0;
-#endif
-}
-
-//____________________________________________________________________________//
-
-static void execution_monitor_jumping_signal_handler( int sig, siginfo_t* info, void* context )
+static void boost_execution_monitor_jumping_signal_handler( int sig, siginfo_t* info, void* context )
{
- if( ignore_sigchild( info ) )
- return;
-
signal_handler::sys_sig()( info, context );
siglongjmp( signal_handler::jump_buffer(), sig );
@@ -840,13 +825,10 @@ static void execution_monitor_jumping_signal_handler( int sig, siginfo_t* info,
//____________________________________________________________________________//
-static void execution_monitor_attaching_signal_handler( int sig, siginfo_t* info, void* context )
+static void boost_execution_monitor_attaching_signal_handler( int sig, siginfo_t* info, void* context )
{
- if( ignore_sigchild( info ) )
- return;
-
if( !debug::attach_debugger( false ) )
- execution_monitor_jumping_signal_handler( sig, info, context );
+ boost_execution_monitor_jumping_signal_handler( sig, info, context );
// debugger attached; it will handle the signal
BOOST_TEST_SYS_ASSERT( ::signal( sig, SIG_DFL ) != SIG_ERR );
@@ -863,7 +845,7 @@ static void execution_monitor_attaching_signal_handler( int sig, siginfo_t* info
// ************************************************************************** //
int
-execution_monitor::catch_signals( unit_test::callback0<int> const& F )
+execution_monitor::catch_signals( boost::function<int ()> const& F )
{
using namespace detail;
@@ -878,13 +860,16 @@ execution_monitor::catch_signals( unit_test::callback0<int> const& F )
p_use_alt_stack.value = false;
#endif
- signal_handler local_signal_handler( p_catch_system_errors, p_timeout, p_auto_start_dbg,
+ signal_handler local_signal_handler( p_catch_system_errors,
+ p_catch_system_errors || (p_detect_fp_exceptions != fpe::BOOST_FPE_OFF),
+ p_timeout,
+ p_auto_start_dbg,
!p_use_alt_stack ? 0 : m_alt_stack.get() );
if( !sigsetjmp( signal_handler::jump_buffer(), 1 ) )
return detail::do_invoke( m_custom_translators , F );
else
- throw local_signal_handler.sys_sig();
+ return BOOST_TEST_IMPL_THROW( local_signal_handler.sys_sig() );
}
//____________________________________________________________________________//
@@ -916,37 +901,64 @@ public:
{}
void report() const;
- int operator()( unsigned int id, _EXCEPTION_POINTERS* exps );
+ int operator()( unsigned id, _EXCEPTION_POINTERS* exps );
private:
// Data members
execution_monitor* m_em;
- unsigned int m_se_id;
+ unsigned m_se_id;
void* m_fault_address;
bool m_dir;
};
+//____________________________________________________________________________//
+
+#if BOOST_WORKAROUND( BOOST_MSVC, <= 1310)
static void
-seh_catch_preventer( unsigned int /* id */, _EXCEPTION_POINTERS* /* exps */ )
+seh_catch_preventer( unsigned /* id */, _EXCEPTION_POINTERS* /* exps */ )
{
throw;
}
+#endif
//____________________________________________________________________________//
int
-system_signal_exception::operator()( unsigned int id, _EXCEPTION_POINTERS* exps )
+system_signal_exception::operator()( unsigned id, _EXCEPTION_POINTERS* exps )
{
- const unsigned int MSFT_CPP_EXCEPT = 0xE06d7363; // EMSC
+ const unsigned MSFT_CPP_EXCEPT = 0xE06d7363; // EMSC
- if( !m_em->p_catch_system_errors || (id == MSFT_CPP_EXCEPT) )
+ // C++ exception - allow to go through
+ if( id == MSFT_CPP_EXCEPT )
return EXCEPTION_CONTINUE_SEARCH;
+ // FPE detection is enabled, while system exception detection is not - check if this is actually FPE
+ if( !m_em->p_catch_system_errors ) {
+ if( !m_em->p_detect_fp_exceptions )
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ switch( id ) {
+ case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+ case EXCEPTION_FLT_STACK_CHECK:
+ case EXCEPTION_FLT_DENORMAL_OPERAND:
+ case EXCEPTION_FLT_INEXACT_RESULT:
+ case EXCEPTION_FLT_OVERFLOW:
+ case EXCEPTION_FLT_UNDERFLOW:
+ case EXCEPTION_FLT_INVALID_OPERATION:
+ case STATUS_FLOAT_MULTIPLE_FAULTS:
+ case STATUS_FLOAT_MULTIPLE_TRAPS:
+ break;
+ default:
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+ }
+
if( !!m_em->p_auto_start_dbg && debug::attach_debugger( false ) ) {
m_em->p_catch_system_errors.value = false;
+#if BOOST_WORKAROUND( BOOST_MSVC, <= 1310)
_set_se_translator( &seh_catch_preventer );
-
+#endif
return EXCEPTION_CONTINUE_EXECUTION;
}
@@ -1031,12 +1043,10 @@ system_signal_exception::report() const
"operand of floating point operation is denormal" );
break;
-# if 0 // !! ??
case EXCEPTION_FLT_INEXACT_RESULT:
detail::report_error( execution_exception::system_error,
"result of a floating-point operation cannot be represented exactly" );
break;
-#endif
case EXCEPTION_FLT_OVERFLOW:
detail::report_error( execution_exception::system_error,
@@ -1052,6 +1062,14 @@ system_signal_exception::report() const
detail::report_error( execution_exception::system_error, "floating point error" );
break;
+ case STATUS_FLOAT_MULTIPLE_FAULTS:
+ detail::report_error( execution_exception::system_error, "multiple floating point errors" );
+ break;
+
+ case STATUS_FLOAT_MULTIPLE_TRAPS:
+ detail::report_error( execution_exception::system_error, "multiple floating point errors" );
+ break;
+
case EXCEPTION_BREAKPOINT:
detail::report_error( execution_exception::system_error, "breakpoint encountered" );
break;
@@ -1071,59 +1089,28 @@ system_signal_exception::report() const
int BOOST_TEST_CALL_DECL
assert_reporting_function( int reportType, char* userMessage, int* )
{
- switch( reportType ) {
- case BOOST_TEST_CRT_ASSERT:
- detail::report_error( execution_exception::user_error, userMessage );
+ // write this way instead of switch to avoid unreachable statements
+ if( reportType == BOOST_TEST_CRT_ASSERT || reportType == BOOST_TEST_CRT_ERROR )
+ detail::report_error( reportType == BOOST_TEST_CRT_ASSERT ? execution_exception::user_error : execution_exception::system_error, userMessage );
- return 1; // return value and retVal are not important since we never reach this line
- case BOOST_TEST_CRT_ERROR:
- detail::report_error( execution_exception::system_error, userMessage );
-
- return 1; // return value and retVal are not important since we never reach this line
- default:
- return 0; // use usual reporting method
- }
+ return 0;
} // assert_reporting_function
//____________________________________________________________________________//
void BOOST_TEST_CALL_DECL
-invalid_param_handler( wchar_t const* /* expr */,
- wchar_t const* /* func */,
- wchar_t const* /* file */,
- unsigned int /* line */,
+invalid_param_handler( wchar_t const* /* expr */,
+ wchar_t const* /* func */,
+ wchar_t const* /* file */,
+ unsigned /* line */,
uintptr_t /* reserved */)
{
- detail::report_error( execution_exception::user_error,
+ detail::report_error( execution_exception::user_error,
"Invalid parameter detected by C runtime library" );
}
//____________________________________________________________________________//
-void BOOST_TEST_CALL_DECL
-switch_fp_exceptions( bool on_off )
-{
- if( !on_off )
- _clearfp();
-
- int cw = ::_controlfp( 0, 0 );
-
- int exceptions_mask = EM_INVALID|EM_DENORMAL|EM_ZERODIVIDE|EM_OVERFLOW|EM_UNDERFLOW;
-
- if( on_off )
- cw &= ~exceptions_mask; // Set the exception masks on, turn exceptions off
- else
- cw |= exceptions_mask; // Set the exception masks off, turn exceptions on
-
- if( on_off )
- _clearfp();
-
- // Set the control word
- ::_controlfp( cw, MCW_EM );
-}
-
-//____________________________________________________________________________//
-
} // namespace detail
// ************************************************************************** //
@@ -1131,25 +1118,24 @@ switch_fp_exceptions( bool on_off )
// ************************************************************************** //
int
-execution_monitor::catch_signals( unit_test::callback0<int> const& F )
+execution_monitor::catch_signals( boost::function<int ()> const& F )
{
_invalid_parameter_handler old_iph = _invalid_parameter_handler();
BOOST_TEST_CRT_HOOK_TYPE old_crt_hook = 0;
- if( !p_catch_system_errors )
- _set_se_translator( &detail::seh_catch_preventer );
- else {
- if( !!p_detect_fp_exceptions )
- detail::switch_fp_exceptions( true );
-
- old_crt_hook = BOOST_TEST_CRT_SET_HOOK( &detail::assert_reporting_function );
+ if( p_catch_system_errors ) {
+ old_crt_hook = BOOST_TEST_CRT_SET_HOOK( &detail::assert_reporting_function );
- old_iph = _set_invalid_parameter_handler(
- reinterpret_cast<_invalid_parameter_handler>( &detail::invalid_param_handler ) );
+ old_iph = _set_invalid_parameter_handler(
+ reinterpret_cast<_invalid_parameter_handler>( &detail::invalid_param_handler ) );
+ } else if( !p_detect_fp_exceptions ) {
+#if BOOST_WORKAROUND( BOOST_MSVC, <= 1310)
+ _set_se_translator( &detail::seh_catch_preventer );
+#endif
}
detail::system_signal_exception SSE( this );
-
+
int ret_val = 0;
__try {
@@ -1161,10 +1147,7 @@ execution_monitor::catch_signals( unit_test::callback0<int> const& F )
}
}
__finally {
- if( !!p_catch_system_errors ) {
- if( !!p_detect_fp_exceptions )
- detail::switch_fp_exceptions( false );
-
+ if( p_catch_system_errors ) {
BOOST_TEST_CRT_SET_HOOK( old_crt_hook );
_set_invalid_parameter_handler( old_iph );
@@ -1188,7 +1171,7 @@ public:
} // namespace detail
int
-execution_monitor::catch_signals( unit_test::callback0<int> const& F )
+execution_monitor::catch_signals( boost::function<int ()> const& F )
{
return detail::do_invoke( m_custom_translators , F );
}
@@ -1198,19 +1181,34 @@ execution_monitor::catch_signals( unit_test::callback0<int> const& F )
#endif // choose signal handler
// ************************************************************************** //
-// ************** execution_monitor::execute ************** //
+// ************** execution_monitor ************** //
// ************************************************************************** //
+execution_monitor::execution_monitor()
+: p_catch_system_errors( true )
+, p_auto_start_dbg( false )
+, p_timeout( 0 )
+, p_use_alt_stack( true )
+, p_detect_fp_exceptions( fpe::BOOST_FPE_OFF )
+{}
+
+//____________________________________________________________________________//
+
int
-execution_monitor::execute( unit_test::callback0<int> const& F )
+execution_monitor::execute( boost::function<int ()> const& F )
{
if( debug::under_debugger() )
p_catch_system_errors.value = false;
- try {
+ BOOST_TEST_IMPL_TRY {
+ detail::fpe_except_guard G( p_detect_fp_exceptions );
+ unit_test::ut_detail::ignore_unused_variable_warning( G );
+
return catch_signals( F );
}
+#ifndef BOOST_NO_EXCEPTION
+
// Catch-clause reference arguments are a bit different from function
// arguments (ISO 15.3 paragraphs 18 & 19). Apparently const isn't
// required. Programmers ask for const anyhow, so we supply it. That's
@@ -1220,89 +1218,61 @@ execution_monitor::execute( unit_test::callback0<int> const& F )
{ detail::report_error( execution_exception::cpp_exception_error,
"C string: %s", ex ); }
catch( std::string const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
+ { detail::report_error( execution_exception::cpp_exception_error,
"std::string: %s", ex.c_str() ); }
// std:: exceptions
+#ifdef BOOST_NO_TYPEID
+#define CATCH_AND_REPORT_STD_EXCEPTION( ex_name ) \
+ catch( ex_name const& ex ) \
+ { detail::report_error( execution_exception::cpp_exception_error, \
+ current_exception_cast<boost::exception const>(), \
+ #ex_name ": %s", ex.what() ); } \
+/**/
+#else
+#define CATCH_AND_REPORT_STD_EXCEPTION( ex_name ) \
+ catch( ex_name const& ex ) \
+ { detail::report_error( execution_exception::cpp_exception_error, \
+ current_exception_cast<boost::exception const>(), \
+ "%s: %s", detail::typeid_name(ex), ex.what() ); } \
+/**/
+#endif
- catch( std::bad_alloc const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::bad_alloc: %s", ex.what() ); }
+ CATCH_AND_REPORT_STD_EXCEPTION( std::bad_alloc )
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
- catch( std::bad_cast const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::bad_cast" ); }
- catch( std::bad_typeid const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::bad_typeid" ); }
+ CATCH_AND_REPORT_STD_EXCEPTION( std::bad_cast )
+ CATCH_AND_REPORT_STD_EXCEPTION( std::bad_typeid )
#else
- catch( std::bad_cast const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::bad_cast: %s", ex.what() ); }
- catch( std::bad_typeid const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::bad_typeid: %s", ex.what() ); }
+ CATCH_AND_REPORT_STD_EXCEPTION( std::bad_cast )
+ CATCH_AND_REPORT_STD_EXCEPTION( std::bad_typeid )
#endif
- catch( std::bad_exception const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::bad_exception: %s", ex.what() ); }
- catch( std::domain_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::domain_error: %s", ex.what() ); }
- catch( std::invalid_argument const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::invalid_argument: %s", ex.what() ); }
- catch( std::length_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::length_error: %s", ex.what() ); }
- catch( std::out_of_range const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::out_of_range: %s", ex.what() ); }
- catch( std::range_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::range_error: %s", ex.what() ); }
- catch( std::overflow_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::overflow_error: %s", ex.what() ); }
- catch( std::underflow_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::underflow_error: %s", ex.what() ); }
- catch( std::logic_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::logic_error: %s", ex.what() ); }
- catch( std::runtime_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::runtime_error: %s", ex.what() ); }
- catch( std::exception const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- current_exception_cast<boost::exception const>(),
- "std::exception: %s", ex.what() ); }
+ CATCH_AND_REPORT_STD_EXCEPTION( std::bad_exception )
+ CATCH_AND_REPORT_STD_EXCEPTION( std::domain_error )
+ CATCH_AND_REPORT_STD_EXCEPTION( std::invalid_argument )
+ CATCH_AND_REPORT_STD_EXCEPTION( std::length_error )
+ CATCH_AND_REPORT_STD_EXCEPTION( std::out_of_range )
+ CATCH_AND_REPORT_STD_EXCEPTION( std::range_error )
+ CATCH_AND_REPORT_STD_EXCEPTION( std::overflow_error )
+ CATCH_AND_REPORT_STD_EXCEPTION( std::underflow_error )
+ CATCH_AND_REPORT_STD_EXCEPTION( std::logic_error )
+ CATCH_AND_REPORT_STD_EXCEPTION( std::runtime_error )
+ CATCH_AND_REPORT_STD_EXCEPTION( std::exception )
+#undef CATCH_AND_REPORT_STD_EXCEPTION
catch( boost::exception const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
- &ex,
- "unknown boost::exception" ); }
+ { detail::report_error( execution_exception::cpp_exception_error,
+ &ex,
+#ifdef BOOST_NO_TYPEID
+ "unknown boost::exception" ); }
+#else
+ typeid(ex).name() ); }
+#endif
// system errors
catch( system_error const& ex )
- { detail::report_error( execution_exception::cpp_exception_error,
+ { detail::report_error( execution_exception::cpp_exception_error,
"system_error produced by: %s: %s", ex.p_failed_exp.get(), std::strerror( ex.p_errno ) ); }
catch( detail::system_signal_exception const& ex )
{ ex.report(); }
@@ -1319,11 +1289,30 @@ execution_monitor::execute( unit_test::callback0<int> const& F )
catch( ... )
{ detail::report_error( execution_exception::cpp_exception_error, "unknown type" ); }
+#endif // !BOOST_NO_EXCEPTION
+
return 0; // never reached; supplied to quiet compiler warnings
} // execute
//____________________________________________________________________________//
+namespace detail {
+
+struct forward {
+ explicit forward( boost::function<void ()> const& F ) : m_F( F ) {}
+
+ int operator()() { m_F(); return 0; }
+
+ boost::function<void ()> const& m_F;
+};
+
+} // namespace detail
+void
+execution_monitor::vexecute( boost::function<void ()> const& F )
+{
+ execute( detail::forward( F ) );
+}
+
// ************************************************************************** //
// ************** system_error ************** //
// ************************************************************************** //
@@ -1359,6 +1348,88 @@ execution_exception::location::location( char const* file_name, size_t line_num,
//____________________________________________________________________________//
+// ************************************************************************** //
+// **************Floating point exception management interface ************** //
+// ************************************************************************** //
+
+namespace fpe {
+
+unsigned
+enable( unsigned mask )
+{
+ boost::ignore_unused(mask);
+
+#if defined(UNDER_CE)
+ /* Not Implemented in Windows CE */
+ return 0;
+#elif defined(BOOST_SEH_BASED_SIGNAL_HANDLING)
+ _clearfp();
+
+#if BOOST_WORKAROUND( BOOST_MSVC, <= 1310)
+ unsigned old_cw = ::_controlfp( 0, 0 );
+ ::_controlfp( old_cw & ~mask, BOOST_FPE_ALL );
+#else
+ unsigned old_cw;
+ if( ::_controlfp_s( &old_cw, 0, 0 ) != 0 )
+ return BOOST_FPE_INV;
+
+ // Set the control word
+ if( ::_controlfp_s( 0, old_cw & ~mask, BOOST_FPE_ALL ) != 0 )
+ return BOOST_FPE_INV;
+#endif
+
+ return ~old_cw & BOOST_FPE_ALL;
+#elif defined(__GLIBC__) && defined(__USE_GNU) && !defined(BOOST_CLANG) && !defined(BOOST_NO_FENV_H)
+ ::feclearexcept(BOOST_FPE_ALL);
+ int res = ::feenableexcept( mask );
+ return res == -1 ? (unsigned)BOOST_FPE_INV : (unsigned)res;
+#else
+ /* Not Implemented */
+ return 0;
+#endif
+}
+
+//____________________________________________________________________________//
+
+unsigned
+disable( unsigned mask )
+{
+ boost::ignore_unused(mask);
+
+#if defined(UNDER_CE)
+ /* Not Implemented in Windows CE */
+ return 0;
+#elif defined(BOOST_SEH_BASED_SIGNAL_HANDLING)
+ _clearfp();
+
+#if BOOST_WORKAROUND( BOOST_MSVC, <= 1310)
+ unsigned old_cw = ::_controlfp( 0, 0 );
+ ::_controlfp( old_cw | mask, BOOST_FPE_ALL );
+#else
+ unsigned old_cw;
+ if( ::_controlfp_s( &old_cw, 0, 0 ) != 0 )
+ return BOOST_FPE_INV;
+
+ // Set the control word
+ if( ::_controlfp_s( 0, old_cw | mask, BOOST_FPE_ALL ) != 0 )
+ return BOOST_FPE_INV;
+#endif
+
+ return ~old_cw & BOOST_FPE_ALL;
+#elif defined(__GLIBC__) && defined(__USE_GNU) && !defined(BOOST_CLANG) && !defined(BOOST_NO_FENV_H)
+ ::feclearexcept(BOOST_FPE_ALL);
+ int res = ::fedisableexcept( mask );
+ return res == -1 ? (unsigned)BOOST_FPE_INV : (unsigned)res;
+#else
+ /* Not Implemented */
+ return BOOST_FPE_INV;
+#endif
+}
+
+//____________________________________________________________________________//
+
+} // namespace fpe
+
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
diff --git a/boost/test/impl/framework.ipp b/boost/test/impl/framework.ipp
index a1e98b3771..a69d95cd2d 100644
--- a/boost/test/impl/framework.ipp
+++ b/boost/test/impl/framework.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 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)
@@ -19,24 +19,36 @@
#include <boost/test/framework.hpp>
#include <boost/test/execution_monitor.hpp>
#include <boost/test/debug.hpp>
-#include <boost/test/unit_test_suite_impl.hpp>
+#include <boost/test/unit_test_parameters.hpp>
+
#include <boost/test/unit_test_log.hpp>
#include <boost/test/unit_test_monitor.hpp>
-#include <boost/test/test_observer.hpp>
#include <boost/test/results_collector.hpp>
#include <boost/test/progress_monitor.hpp>
#include <boost/test/results_reporter.hpp>
-#include <boost/test/test_tools.hpp>
-#include <boost/test/detail/unit_test_parameters.hpp>
-#include <boost/test/detail/global_typedef.hpp>
+#include <boost/test/tree/observer.hpp>
+#include <boost/test/tree/test_unit.hpp>
+#include <boost/test/tree/visitor.hpp>
+#include <boost/test/tree/traverse.hpp>
+#include <boost/test/tree/test_case_counter.hpp>
+
+#if BOOST_TEST_SUPPORT_TOKEN_ITERATOR
+#include <boost/test/utils/iterator/token_iterator.hpp>
+#endif
#include <boost/test/utils/foreach.hpp>
+#include <boost/test/utils/basic_cstring/io.hpp>
+
+#include <boost/test/detail/global_typedef.hpp>
+#include <boost/test/detail/throw_exception.hpp>
// Boost
#include <boost/timer.hpp>
+#include <boost/bind.hpp>
// STL
+#include <limits>
#include <map>
#include <set>
#include <cstdlib>
@@ -51,148 +63,672 @@ namespace std { using ::time; using ::srand; }
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
+namespace framework {
+namespace impl {
// ************************************************************************** //
-// ************** test_start calls wrapper ************** //
+// ************** order detection helpers ************** //
// ************************************************************************** //
-namespace ut_detail {
+struct order_info {
+ order_info() : depth(-1) {}
-struct test_start_caller {
- test_start_caller( test_observer* to, counter_t tc_amount )
- : m_to( to )
- , m_tc_amount( tc_amount )
- {}
+ int depth;
+ std::vector<test_unit_id> dependant_siblings;
+};
- int operator()()
- {
- m_to->test_start( m_tc_amount );
+typedef std::set<test_unit_id> tu_id_set;
+typedef std::map<test_unit_id,order_info> order_info_per_tu; // !! ?? unordered map
+
+//____________________________________________________________________________//
+
+static test_unit_id
+get_tu_parent( test_unit_id tu_id )
+{
+ return framework::get( tu_id, TUT_ANY ).p_parent_id;
+}
+
+//____________________________________________________________________________//
+
+static int
+tu_depth( test_unit_id tu_id, test_unit_id master_tu_id, order_info_per_tu& tuoi )
+{
+ if( tu_id == master_tu_id )
return 0;
+
+ order_info& info = tuoi[tu_id];
+
+ if( info.depth == -1 )
+ info.depth = tu_depth( get_tu_parent( tu_id ), master_tu_id, tuoi ) + 1;
+
+ return info.depth;
+}
+
+//____________________________________________________________________________//
+
+static void
+collect_dependant_siblings( test_unit_id from, test_unit_id to, test_unit_id master_tu_id, order_info_per_tu& tuoi )
+{
+ int from_depth = tu_depth( from, master_tu_id, tuoi );
+ int to_depth = tu_depth( to, master_tu_id, tuoi );
+
+ while(from_depth > to_depth) {
+ from = get_tu_parent( from );
+ --from_depth;
+ }
+
+ while(from_depth < to_depth) {
+ to = get_tu_parent( to );
+ --to_depth;
+ }
+
+ while(true) {
+ test_unit_id from_parent = get_tu_parent( from );
+ test_unit_id to_parent = get_tu_parent( to );
+ if( from_parent == to_parent )
+ break;
+ from = from_parent;
+ to = to_parent;
+ }
+
+ tuoi[from].dependant_siblings.push_back( to );
+}
+
+//____________________________________________________________________________//
+
+static counter_t
+assign_sibling_rank( test_unit_id tu_id, order_info_per_tu& tuoi )
+{
+ test_unit& tu = framework::get( tu_id, TUT_ANY );
+
+ BOOST_TEST_SETUP_ASSERT( tu.p_sibling_rank != (std::numeric_limits<counter_t>::max)(),
+ "Cyclic dependency detected involving test unit \"" + tu.full_name() + "\"" );
+
+ if( tu.p_sibling_rank != 0 )
+ return tu.p_sibling_rank;
+
+ order_info const& info = tuoi[tu_id];
+
+ // indicate in progress
+ tu.p_sibling_rank.value = (std::numeric_limits<counter_t>::max)();
+
+ counter_t new_rank = 1;
+ BOOST_TEST_FOREACH( test_unit_id, sibling_id, info.dependant_siblings )
+ new_rank = (std::max)(new_rank, assign_sibling_rank( sibling_id, tuoi ) + 1);
+
+ return tu.p_sibling_rank.value = new_rank;
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** test_init call wrapper ************** //
+// ************************************************************************** //
+
+static void
+invoke_init_func( init_unit_test_func init_func )
+{
+#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
+ if( !(*init_func)() )
+ BOOST_TEST_IMPL_THROW( std::runtime_error( "test module initialization failed" ) );
+#else
+ test_suite* manual_test_units = (*init_func)( framework::master_test_suite().argc, framework::master_test_suite().argv );
+
+ if( manual_test_units )
+ framework::master_test_suite().add( manual_test_units );
+#endif
+}
+
+// ************************************************************************** //
+// ************** name_filter ************** //
+// ************************************************************************** //
+
+class name_filter : public test_tree_visitor {
+ struct component {
+ component( const_string name ) // has to be implicit
+ {
+ if( name == "*" )
+ m_kind = SFK_ALL;
+ else if( first_char( name ) == '*' && last_char( name ) == '*' ) {
+ m_kind = SFK_SUBSTR;
+ m_name = name.substr( 1, name.size()-1 );
+ }
+ else if( first_char( name ) == '*' ) {
+ m_kind = SFK_TRAILING;
+ m_name = name.substr( 1 );
+ }
+ else if( last_char( name ) == '*' ) {
+ m_kind = SFK_LEADING;
+ m_name = name.substr( 0, name.size()-1 );
+ }
+ else {
+ m_kind = SFK_MATCH;
+ m_name = name;
+ }
+ }
+
+ bool pass( test_unit const& tu ) const
+ {
+ const_string name( tu.p_name );
+
+ switch( m_kind ) {
+ default:
+ case SFK_ALL:
+ return true;
+ case SFK_LEADING:
+ return name.substr( 0, m_name.size() ) == m_name;
+ case SFK_TRAILING:
+ return name.size() >= m_name.size() && name.substr( name.size() - m_name.size() ) == m_name;
+ case SFK_SUBSTR:
+ return name.find( m_name ) != const_string::npos;
+ case SFK_MATCH:
+ return m_name == tu.p_name.get();
+ }
+ }
+ enum kind { SFK_ALL, SFK_LEADING, SFK_TRAILING, SFK_SUBSTR, SFK_MATCH };
+
+ kind m_kind;
+ const_string m_name;
+ };
+
+public:
+ // Constructor
+ name_filter( test_unit_id_list& targ_list, const_string filter_expr ) : m_targ_list( targ_list ), m_depth( 0 )
+ {
+#ifdef BOOST_TEST_SUPPORT_TOKEN_ITERATOR
+ string_token_iterator tit( filter_expr, (dropped_delimeters = "/", kept_delimeters = dt_none) );
+
+ while( tit != string_token_iterator() ) {
+ m_components.push_back( std::vector<component>( string_token_iterator( *tit, (dropped_delimeters = ",", kept_delimeters = dt_none) ),
+ string_token_iterator() ) );
+
+ ++tit;
+ }
+#endif
}
private:
+ bool filter_unit( test_unit const& tu )
+ {
+ // skip master test suite
+ if( m_depth == 0 )
+ return true;
+
+ // corresponding name filters are at level m_depth-1
+ std::vector<component> const& filters = m_components[m_depth-1];
+
+ // look for match
+ return std::find_if( filters.begin(), filters.end(), bind( &component::pass, _1, boost::ref(tu) ) ) != filters.end();
+ }
+
+ // test_tree_visitor interface
+ virtual void visit( test_case const& tc )
+ {
+ // make sure we only accept test cases if we match last component of the filter
+ if( m_depth == m_components.size() && filter_unit( tc ) )
+ m_targ_list.push_back( tc.p_id ); // found a test case
+ }
+ virtual bool test_suite_start( test_suite const& ts )
+ {
+ if( !filter_unit( ts ) )
+ return false;
+
+ if( m_depth < m_components.size() ) {
+ ++m_depth;
+ return true;
+ }
+
+ m_targ_list.push_back( ts.p_id ); // found a test suite
+
+ return false;
+ }
+ virtual void test_suite_finish( test_suite const& /*ts*/ )
+ {
+ --m_depth;
+ }
+
// Data members
- test_observer* m_to;
- counter_t m_tc_amount;
+ typedef std::vector<std::vector<component> > components_per_level;
+
+ components_per_level m_components;
+ test_unit_id_list& m_targ_list;
+ unsigned m_depth;
};
-//____________________________________________________________________________//
+// ************************************************************************** //
+// ************** label_filter ************** //
+// ************************************************************************** //
-struct test_init_caller {
- explicit test_init_caller( init_unit_test_func init_func )
- : m_init_func( init_func )
+class label_filter : public test_tree_visitor {
+public:
+ label_filter( test_unit_id_list& targ_list, const_string label )
+ : m_targ_list( targ_list )
+ , m_label( label )
{}
- int operator()()
+
+private:
+ // test_tree_visitor interface
+ virtual bool visit( test_unit const& tu )
{
-#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
- if( !(*m_init_func)() )
- throw std::runtime_error( "test module initialization failed" );
-#else
- test_suite* manual_test_units = (*m_init_func)( framework::master_test_suite().argc, framework::master_test_suite().argv );
+ if( tu.has_label( m_label ) ) {
+ // found a test unit; add it to list of tu to enable with children and stop recursion in case of suites
+ m_targ_list.push_back( tu.p_id );
+ return false;
+ }
- if( manual_test_units )
- framework::master_test_suite().add( manual_test_units );
-#endif
- return 0;
+ return true;
+ }
+
+ // Data members
+ test_unit_id_list& m_targ_list;
+ const_string m_label;
+};
+
+// ************************************************************************** //
+// ************** set_run_status ************** //
+// ************************************************************************** //
+
+class set_run_status : public test_tree_visitor {
+public:
+ explicit set_run_status( test_unit::run_status rs, test_unit_id_list* dep_collector = 0 )
+ : m_new_status( rs )
+ , m_dep_collector( dep_collector )
+ {}
+
+private:
+ // test_tree_visitor interface
+ virtual bool visit( test_unit const& tu )
+ {
+ const_cast<test_unit&>(tu).p_run_status.value = m_new_status == test_unit::RS_INVALID ? tu.p_default_status : m_new_status;
+
+ if( m_dep_collector ) {
+ BOOST_TEST_FOREACH( test_unit_id, dep_id, tu.p_dependencies.get() ) {
+ test_unit const& dep = framework::get( dep_id, TUT_ANY );
+
+ if( dep.p_run_status == tu.p_run_status )
+ continue;
+
+ BOOST_TEST_MESSAGE( "Including test " << dep.p_type_name << ' ' << dep.full_name() <<
+ " as a dependency of test " << tu.p_type_name << ' ' << tu.full_name() );
+
+ m_dep_collector->push_back( dep_id );
+ }
+ }
+ return true;
}
// Data members
- init_unit_test_func m_init_func;
+ test_unit::run_status m_new_status;
+ test_unit_id_list* m_dep_collector;
};
+// ************************************************************************** //
+// ************** parse_filters ************** //
+// ************************************************************************** //
+
+static void
+add_filtered_test_units( test_unit_id master_tu_id, const_string filter, test_unit_id_list& targ )
+{
+ // Choose between two kinds of filters
+ if( filter[0] == '@' ) {
+ filter.trim_left( 1 );
+ label_filter lf( targ, filter );
+ traverse_test_tree( master_tu_id, lf, true );
+ }
+ else {
+ name_filter nf( targ, filter );
+ traverse_test_tree( master_tu_id, nf, true );
+ }
}
+//____________________________________________________________________________//
+
+static bool
+parse_filters( test_unit_id master_tu_id, test_unit_id_list& tu_to_enable, test_unit_id_list& tu_to_disable )
+{
+ // 10. collect tu to enable and disable based on filters
+ bool had_selector_filter = false;
+
+ BOOST_TEST_FOREACH( const_string, filter, runtime_config::test_to_run() ) {
+ BOOST_TEST_SETUP_ASSERT( !filter.is_empty(), "Invalid filter specification" );
+
+ enum { SELECTOR, ENABLER, DISABLER } filter_type = SELECTOR;
+
+ // 11. Deduce filter type
+ if( filter[0] == '!' || filter[0] == '+' ) {
+ filter_type = filter[0] == '+' ? ENABLER : DISABLER;
+ filter.trim_left( 1 );
+ BOOST_TEST_SETUP_ASSERT( !filter.is_empty(), "Invalid filter specification" );
+ }
+
+ had_selector_filter |= filter_type == SELECTOR;
+
+ // 12. Add test units to corresponding list
+ switch( filter_type ) {
+ case SELECTOR:
+ case ENABLER: add_filtered_test_units( master_tu_id, filter, tu_to_enable ); break;
+ case DISABLER: add_filtered_test_units( master_tu_id, filter, tu_to_disable ); break;
+ }
+ }
+
+ return had_selector_filter;
+}
+
+//____________________________________________________________________________//
+
+} // namespace impl
+
// ************************************************************************** //
-// ************** framework ************** //
+// ************** framework::state ************** //
// ************************************************************************** //
-class framework_impl : public test_tree_visitor {
+unsigned const TIMEOUT_EXCEEDED = static_cast<unsigned>( -1 );
+
+class state {
public:
- framework_impl()
- : m_master_test_suite( 0 )
- , m_curr_test_case( INV_TEST_UNIT_ID )
+ state()
+ : m_curr_test_case( INV_TEST_UNIT_ID )
, m_next_test_case_id( MIN_TEST_CASE_ID )
, m_next_test_suite_id( MIN_TEST_SUITE_ID )
- , m_is_initialized( false )
, m_test_in_progress( false )
- {}
+ , m_context_idx( 0 )
+ {
+ }
- ~framework_impl() { clear(); }
+ ~state() { clear(); }
void clear()
{
while( !m_test_units.empty() ) {
test_unit_store::value_type const& tu = *m_test_units.begin();
- test_unit* tu_ptr = tu.second;
+ test_unit const* tu_ptr = tu.second;
// the delete will erase this element from map
- if( ut_detail::test_id_2_unit_type( tu.second->p_id ) == tut_suite )
- delete (test_suite const*)tu_ptr;
+ if( ut_detail::test_id_2_unit_type( tu.second->p_id ) == TUT_SUITE )
+ delete static_cast<test_suite const*>(tu_ptr);
else
- delete (test_case const*)tu_ptr;
+ delete static_cast<test_case const*>(tu_ptr);
}
}
void set_tu_id( test_unit& tu, test_unit_id id ) { tu.p_id.value = id; }
- // test_tree_visitor interface implementation
- void visit( test_case const& tc )
+ //////////////////////////////////////////////////////////////////
+
+ // Validates the dependency graph and deduces the sibling dependency rank for each child
+ void deduce_siblings_order( test_unit_id tu_id, test_unit_id master_tu_id, impl::order_info_per_tu& tuoi )
{
- if( !tc.check_dependencies() ) {
- BOOST_TEST_FOREACH( test_observer*, to, m_observers )
- to->test_unit_skipped( tc );
+ test_unit& tu = framework::get( tu_id, TUT_ANY );
+
+ // collect all sibling dependancy from tu own list
+ BOOST_TEST_FOREACH( test_unit_id, dep_id, tu.p_dependencies.get() )
+ collect_dependant_siblings( tu_id, dep_id, master_tu_id, tuoi );
+ if( tu.p_type != TUT_SUITE )
return;
+
+ test_suite& ts = static_cast<test_suite&>(tu);
+
+ // recursive call to children first
+ BOOST_TEST_FOREACH( test_unit_id, chld_id, ts.m_children )
+ deduce_siblings_order( chld_id, master_tu_id, tuoi );
+
+ BOOST_TEST_FOREACH( test_unit_id, chld_id, ts.m_children ) {
+ counter_t rank = assign_sibling_rank( chld_id, tuoi );
+ ts.m_ranked_children.insert( std::make_pair( rank, chld_id ) );
}
+ }
- BOOST_TEST_FOREACH( test_observer*, to, m_observers )
- to->test_unit_start( tc );
+ //////////////////////////////////////////////////////////////////
- boost::timer tc_timer;
- test_unit_id bkup = m_curr_test_case;
- m_curr_test_case = tc.p_id;
- unit_test_monitor_t::error_level run_result = unit_test_monitor.execute_and_translate( tc );
+ // Finalize default run status:
+ // 1) inherit run status from parent where applicable
+ // 2) if any of test units in test suite enabled enable it as well
+ bool finalize_default_run_status( test_unit_id tu_id, test_unit::run_status parent_status )
+ {
+ test_unit& tu = framework::get( tu_id, TUT_ANY );
- unsigned long elapsed = static_cast<unsigned long>( tc_timer.elapsed() * 1e6 );
+ if( tu.p_default_status == test_suite::RS_INHERIT )
+ tu.p_default_status.value = parent_status;
- if( unit_test_monitor.is_critical_error( run_result ) ) {
- BOOST_TEST_FOREACH( test_observer*, to, m_observers )
- to->test_aborted();
+ // go through list of children
+ if( tu.p_type == TUT_SUITE ) {
+ bool has_enabled_child = false;
+ BOOST_TEST_FOREACH( test_unit_id, chld_id, static_cast<test_suite const&>(tu).m_children )
+ has_enabled_child |= finalize_default_run_status( chld_id, tu.p_default_status );
+
+ tu.p_default_status.value = has_enabled_child ? test_suite::RS_ENABLED : test_suite::RS_DISABLED;
}
- BOOST_TEST_FOREACH( test_observer*, to, m_observers )
- to->test_unit_finish( tc, elapsed );
+ return tu.p_default_status == test_suite::RS_ENABLED;
+ }
- m_curr_test_case = bkup;
+ //////////////////////////////////////////////////////////////////
+
+ bool finalize_run_status( test_unit_id tu_id )
+ {
+ test_unit& tu = framework::get( tu_id, TUT_ANY );
+
+ // go through list of children
+ if( tu.p_type == TUT_SUITE ) {
+ bool has_enabled_child = false;
+ BOOST_TEST_FOREACH( test_unit_id, chld_id, static_cast<test_suite const&>(tu).m_children)
+ has_enabled_child |= finalize_run_status( chld_id );
+
+ tu.p_run_status.value = has_enabled_child ? test_suite::RS_ENABLED : test_suite::RS_DISABLED;
+ }
- if( unit_test_monitor.is_critical_error( run_result ) )
- throw test_being_aborted();
+ return tu.is_enabled();
}
- bool test_suite_start( test_suite const& ts )
+ //////////////////////////////////////////////////////////////////
+
+ void deduce_run_status( test_unit_id master_tu_id )
{
- if( !ts.check_dependencies() ) {
- BOOST_TEST_FOREACH( test_observer*, to, m_observers )
- to->test_unit_skipped( ts );
+ using namespace framework::impl;
+ test_unit_id_list tu_to_enable;
+ test_unit_id_list tu_to_disable;
- return false;
+ // 10. If there are any filters supplied, figure out lists of test units to enable/disable
+ bool had_selector_filter = !runtime_config::test_to_run().empty() &&
+ parse_filters( master_tu_id, tu_to_enable, tu_to_disable );
+
+ // 20. Set the stage: either use default run status or disable all test units
+ set_run_status setter( had_selector_filter ? test_unit::RS_DISABLED : test_unit::RS_INVALID );
+ traverse_test_tree( master_tu_id, setter, true );
+
+ // 30. Apply all selectors and enablers.
+ while( !tu_to_enable.empty() ) {
+ test_unit& tu = framework::get( tu_to_enable.back(), TUT_ANY );
+
+ tu_to_enable.pop_back();
+
+ // 35. Ignore test units which already enabled
+ if( tu.is_enabled() )
+ continue;
+
+ // set new status and add all dependencies into tu_to_enable
+ set_run_status setter( test_unit::RS_ENABLED, &tu_to_enable );
+ traverse_test_tree( tu.p_id, setter, true );
}
- BOOST_TEST_FOREACH( test_observer*, to, m_observers )
- to->test_unit_start( ts );
+ // 40. Apply all disablers
+ while( !tu_to_disable.empty() ) {
+ test_unit const& tu = framework::get( tu_to_disable.back(), TUT_ANY );
- return true;
+ tu_to_disable.pop_back();
+
+ // 35. Ignore test units which already disabled
+ if( !tu.is_enabled() )
+ continue;
+
+ set_run_status setter( test_unit::RS_DISABLED );
+ traverse_test_tree( tu.p_id, setter, true );
+ }
+
+ // 50. Make sure parents of enabled test units are also enabled
+ finalize_run_status( master_tu_id );
}
- void test_suite_finish( test_suite const& ts )
+ //////////////////////////////////////////////////////////////////
+
+ typedef unit_test_monitor_t::error_level execution_result;
+
+ // Executed the test tree with the root at specified test unit
+ execution_result execute_test_tree( test_unit_id tu_id, unsigned timeout = 0 )
{
+ test_unit const& tu = framework::get( tu_id, TUT_ANY );
+
+ execution_result result = unit_test_monitor_t::test_ok;
+
+ if( !tu.is_enabled() )
+ return result;
+
+ // 10. Check preconditions, including zero time left for execution and
+ // successful execution of all dependencies
+ if( timeout == TIMEOUT_EXCEEDED ) {
+ // notify all observers about skipped test unit
+ BOOST_TEST_FOREACH( test_observer*, to, m_observers )
+ to->test_unit_skipped( tu, "timeout for the test unit is exceeded" );
+
+ return unit_test_monitor_t::os_timeout;
+ }
+ else if( timeout == 0 || timeout > tu.p_timeout ) // deduce timeout for this test unit
+ timeout = tu.p_timeout;
+
+ test_tools::assertion_result const precondition_res = tu.check_preconditions();
+ if( !precondition_res ) {
+ // notify all observers about skipped test unit
+ BOOST_TEST_FOREACH( test_observer*, to, m_observers )
+ to->test_unit_skipped( tu, precondition_res.message() );
+
+ return unit_test_monitor_t::precondition_failure;
+ }
+
+ // 20. Notify all observers about the start of the test unit
BOOST_TEST_FOREACH( test_observer*, to, m_observers )
- to->test_unit_finish( ts, 0 );
+ to->test_unit_start( tu );
+
+ // 30. Execute setup fixtures if any; any failure here leads to test unit abortion
+ BOOST_TEST_FOREACH( test_unit_fixture_ptr, F, tu.p_fixtures.get() ) {
+ result = unit_test_monitor.execute_and_translate( boost::bind( &test_unit_fixture::setup, F ) );
+ if( result != unit_test_monitor_t::test_ok )
+ break;
+ }
+
+ // This is the time we are going to spend executing the test unit
+ unsigned long elapsed = 0;
+
+ if( result == unit_test_monitor_t::test_ok ) {
+ // 40. We are going to time the execution
+ boost::timer tu_timer;
+
+ if( tu.p_type == TUT_SUITE ) {
+ test_suite const& ts = static_cast<test_suite const&>( tu );
+
+ if( runtime_config::random_seed() == 0 ) {
+ typedef std::pair<counter_t,test_unit_id> value_type;
+
+ BOOST_TEST_FOREACH( value_type, chld, ts.m_ranked_children ) {
+ unsigned chld_timeout = child_timeout( timeout, tu_timer.elapsed() );
+
+ result = (std::min)( result, execute_test_tree( chld.second, chld_timeout ) );
+
+ if( unit_test_monitor.is_critical_error( result ) )
+ break;
+ }
+ }
+ else {
+ // Go through ranges of chldren with the same dependency rank and shuffle them
+ // independently. Execute each subtree in this order
+ test_unit_id_list children_with_the_same_rank;
+
+ typedef test_suite::children_per_rank::const_iterator it_type;
+ it_type it = ts.m_ranked_children.begin();
+ while( it != ts.m_ranked_children.end() ) {
+ children_with_the_same_rank.clear();
+
+ std::pair<it_type,it_type> range = ts.m_ranked_children.equal_range( it->first );
+ it = range.first;
+ while( it != range.second ) {
+ children_with_the_same_rank.push_back( it->second );
+ it++;
+ }
+
+ std::random_shuffle( children_with_the_same_rank.begin(), children_with_the_same_rank.end() );
+
+ BOOST_TEST_FOREACH( test_unit_id, chld, children_with_the_same_rank ) {
+ unsigned chld_timeout = child_timeout( timeout, tu_timer.elapsed() );
+
+ result = (std::min)( result, execute_test_tree( chld, chld_timeout ) );
+
+ if( unit_test_monitor.is_critical_error( result ) )
+ break;
+ }
+ }
+ }
+
+ elapsed = static_cast<unsigned long>( tu_timer.elapsed() * 1e6 );
+ }
+ else { // TUT_CASE
+ test_case const& tc = static_cast<test_case const&>( tu );
+
+ // setup contexts
+ m_context_idx = 0;
+
+ // setup current test case
+ test_unit_id bkup = m_curr_test_case;
+ m_curr_test_case = tc.p_id;
+
+ // execute the test case body
+ result = unit_test_monitor.execute_and_translate( tc.p_test_func, timeout );
+ elapsed = static_cast<unsigned long>( tu_timer.elapsed() * 1e6 );
+
+ // cleanup leftover context
+ m_context.clear();
+
+ // restore state and abort if necessary
+ m_curr_test_case = bkup;
+ }
+ }
+
+ // if run error is critical skip teardown, who knows what the state of the program at this point
+ if( !unit_test_monitor.is_critical_error( result ) ) {
+ // execute teardown fixtures if any in reverse order
+ BOOST_TEST_REVERSE_FOREACH( test_unit_fixture_ptr, F, tu.p_fixtures.get() ) {
+ result = (std::min)( result, unit_test_monitor.execute_and_translate( boost::bind( &test_unit_fixture::teardown, F ), 0 ) );
+
+ if( unit_test_monitor.is_critical_error( result ) )
+ break;
+ }
+ }
+
+ // notify all observers about abortion
+ if( unit_test_monitor.is_critical_error( result ) ) {
+ BOOST_TEST_FOREACH( test_observer*, to, m_observers )
+ to->test_aborted();
+ }
+
+ // notify all observers about completion
+ BOOST_TEST_REVERSE_FOREACH( test_observer*, to, m_observers )
+ to->test_unit_finish( tu, elapsed );
+
+ return result;
}
//////////////////////////////////////////////////////////////////
+
+ unsigned child_timeout( unsigned tu_timeout, double elapsed )
+ {
+ if( tu_timeout == 0U )
+ return 0U;
+
+ unsigned elpsed_sec = static_cast<unsigned>(elapsed); // rounding to number of whole seconds
+
+ return tu_timeout > elpsed_sec ? tu_timeout - elpsed_sec : TIMEOUT_EXCEEDED;
+ }
+
struct priority_order {
bool operator()( test_observer* lhs, test_observer* rhs ) const
{
@@ -200,226 +736,467 @@ public:
}
};
+ // Data members
typedef std::map<test_unit_id,test_unit*> test_unit_store;
typedef std::set<test_observer*,priority_order> observer_store;
+ struct context_frame {
+ context_frame( std::string const& d, int id, bool sticky )
+ : descr( d )
+ , frame_id( id )
+ , is_sticky( sticky )
+ {}
+
+ std::string descr;
+ int frame_id;
+ bool is_sticky;
+ };
+ typedef std::vector<context_frame> context_data;
master_test_suite_t* m_master_test_suite;
+ std::vector<test_suite*> m_auto_test_suites;
+
test_unit_id m_curr_test_case;
test_unit_store m_test_units;
test_unit_id m_next_test_case_id;
test_unit_id m_next_test_suite_id;
- bool m_is_initialized;
bool m_test_in_progress;
observer_store m_observers;
+ context_data m_context;
+ int m_context_idx;
+
+ boost::execution_monitor m_aux_em;
};
//____________________________________________________________________________//
+namespace impl {
namespace {
#if defined(__CYGWIN__)
-framework_impl& s_frk_impl() { static framework_impl* the_inst = 0; if(!the_inst) the_inst = new framework_impl; return *the_inst; }
+framework::state& s_frk_state() { static framework::state* the_inst = 0; if(!the_inst) the_inst = new framework::state; return *the_inst; }
#else
-framework_impl& s_frk_impl() { static framework_impl the_inst; return the_inst; }
+framework::state& s_frk_state() { static framework::state the_inst; return the_inst; }
#endif
} // local namespace
+void
+setup_for_execution( test_unit const& tu )
+{
+ s_frk_state().deduce_run_status( tu.p_id );
+}
+
//____________________________________________________________________________//
-namespace framework {
+} // namespace impl
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** framework::init ************** //
+// ************************************************************************** //
void
init( init_unit_test_func init_func, int argc, char* argv[] )
{
+ // 10. Set up runtime parameters
runtime_config::init( argc, argv );
- // set the log level and format
+ // 20. Set the desired log level and format
unit_test_log.set_threshold_level( runtime_config::log_level() );
unit_test_log.set_format( runtime_config::log_format() );
- // set the report level and format
+ // 30. Set the desired report level and format
results_reporter::set_level( runtime_config::report_level() );
results_reporter::set_format( runtime_config::report_format() );
+ // 40. Register default test observers
register_observer( results_collector );
register_observer( unit_test_log );
if( runtime_config::show_progress() )
register_observer( progress_monitor );
+ // 50. Set up memory leak detection
if( runtime_config::detect_memory_leaks() > 0 ) {
- debug::detect_memory_leaks( true );
+ debug::detect_memory_leaks( true, runtime_config::memory_leaks_report_file() );
debug::break_memory_alloc( runtime_config::detect_memory_leaks() );
}
- // init master unit test suite
+ // 60. Initialize master unit test suite
master_test_suite().argc = argc;
master_test_suite().argv = argv;
- try {
- boost::execution_monitor em;
-
- ut_detail::test_init_caller tic( init_func );
+ using namespace impl;
- em.execute( tic );
+ // 70. Invoke test module initialization routine
+ BOOST_TEST_IMPL_TRY {
+ s_frk_state().m_aux_em.vexecute( boost::bind( &impl::invoke_init_func, init_func ) );
}
- catch( execution_exception const& ex ) {
- throw setup_error( ex.what() );
+ BOOST_TEST_IMPL_CATCH( execution_exception, ex ) {
+ BOOST_TEST_SETUP_ASSERT( false, ex.what() );
}
-
- s_frk_impl().m_is_initialized = true;
}
//____________________________________________________________________________//
+void
+finalize_setup_phase( test_unit_id master_tu_id )
+{
+ if( master_tu_id == INV_TEST_UNIT_ID )
+ master_tu_id = master_test_suite().p_id;
+
+ // 10. Apply all decorators to the auto test units
+ class apply_decorators : public test_tree_visitor {
+ private:
+ // test_tree_visitor interface
+ virtual bool visit( test_unit const& tu )
+ {
+ BOOST_TEST_FOREACH( decorator::base_ptr, d, tu.p_decorators.get() )
+ d->apply( const_cast<test_unit&>(tu) );
+
+ return true;
+ }
+ } ad;
+ traverse_test_tree( master_tu_id, ad, true );
+
+ // 20. Finalize setup phase
+ impl::order_info_per_tu tuoi;
+ impl::s_frk_state().deduce_siblings_order( master_tu_id, master_tu_id, tuoi );
+ impl::s_frk_state().finalize_default_run_status( master_tu_id, test_unit::RS_INVALID );
+}
+
+// ************************************************************************** //
+// ************** test_in_progress ************** //
+// ************************************************************************** //
+
bool
-is_initialized()
+test_in_progress()
+{
+ return impl::s_frk_state().m_test_in_progress;
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** framework::shutdown ************** //
+// ************************************************************************** //
+
+void
+shutdown()
{
- return s_frk_impl().m_is_initialized;
+ // eliminating some fake memory leak reports. See for more details:
+ // http://connect.microsoft.com/VisualStudio/feedback/details/106937/memory-leaks-reported-by-debug-crt-inside-typeinfo-name
+
+# if BOOST_WORKAROUND(BOOST_MSVC, <= 1600 ) && !defined(_DLL) && defined(_DEBUG)
+# if BOOST_WORKAROUND(BOOST_MSVC, < 1600 )
+#define _Next next
+#define _MemPtr memPtr
+#endif
+ __type_info_node* pNode = __type_info_root_node._Next;
+ __type_info_node* tmpNode = &__type_info_root_node;
+
+ for( ; pNode!=NULL; pNode = tmpNode ) {
+ tmpNode = pNode->_Next;
+ delete pNode->_MemPtr;
+ delete pNode;
+ }
+# if BOOST_WORKAROUND(BOOST_MSVC, < 1600 )
+#undef _Next
+#undef _MemPtr
+#endif
+# endif
}
//____________________________________________________________________________//
+// ************************************************************************** //
+// ************** register_test_unit ************** //
+// ************************************************************************** //
+
void
register_test_unit( test_case* tc )
{
BOOST_TEST_SETUP_ASSERT( tc->p_id == INV_TEST_UNIT_ID, BOOST_TEST_L( "test case already registered" ) );
- test_unit_id new_id = s_frk_impl().m_next_test_case_id;
+ test_unit_id new_id = impl::s_frk_state().m_next_test_case_id;
BOOST_TEST_SETUP_ASSERT( new_id != MAX_TEST_CASE_ID, BOOST_TEST_L( "too many test cases" ) );
- typedef framework_impl::test_unit_store::value_type map_value_type;
+ typedef state::test_unit_store::value_type map_value_type;
- s_frk_impl().m_test_units.insert( map_value_type( new_id, tc ) );
- s_frk_impl().m_next_test_case_id++;
+ impl::s_frk_state().m_test_units.insert( map_value_type( new_id, tc ) );
+ impl::s_frk_state().m_next_test_case_id++;
- s_frk_impl().set_tu_id( *tc, new_id );
+ impl::s_frk_state().set_tu_id( *tc, new_id );
}
//____________________________________________________________________________//
+// ************************************************************************** //
+// ************** register_test_unit ************** //
+// ************************************************************************** //
+
void
register_test_unit( test_suite* ts )
{
BOOST_TEST_SETUP_ASSERT( ts->p_id == INV_TEST_UNIT_ID, BOOST_TEST_L( "test suite already registered" ) );
- test_unit_id new_id = s_frk_impl().m_next_test_suite_id;
+ test_unit_id new_id = impl::s_frk_state().m_next_test_suite_id;
BOOST_TEST_SETUP_ASSERT( new_id != MAX_TEST_SUITE_ID, BOOST_TEST_L( "too many test suites" ) );
- typedef framework_impl::test_unit_store::value_type map_value_type;
- s_frk_impl().m_test_units.insert( map_value_type( new_id, ts ) );
- s_frk_impl().m_next_test_suite_id++;
+ typedef state::test_unit_store::value_type map_value_type;
+
+ impl::s_frk_state().m_test_units.insert( map_value_type( new_id, ts ) );
+ impl::s_frk_state().m_next_test_suite_id++;
- s_frk_impl().set_tu_id( *ts, new_id );
+ impl::s_frk_state().set_tu_id( *ts, new_id );
}
//____________________________________________________________________________//
+// ************************************************************************** //
+// ************** deregister_test_unit ************** //
+// ************************************************************************** //
+
void
deregister_test_unit( test_unit* tu )
{
- s_frk_impl().m_test_units.erase( tu->p_id );
+ impl::s_frk_state().m_test_units.erase( tu->p_id );
}
//____________________________________________________________________________//
+// ************************************************************************** //
+// ************** clear ************** //
+// ************************************************************************** //
+
void
clear()
{
- s_frk_impl().clear();
+ impl::s_frk_state().clear();
}
//____________________________________________________________________________//
+// ************************************************************************** //
+// ************** register_observer ************** //
+// ************************************************************************** //
+
void
register_observer( test_observer& to )
{
- s_frk_impl().m_observers.insert( &to );
+ impl::s_frk_state().m_observers.insert( &to );
}
//____________________________________________________________________________//
+// ************************************************************************** //
+// ************** deregister_observer ************** //
+// ************************************************************************** //
+
void
deregister_observer( test_observer& to )
{
- s_frk_impl().m_observers.erase( &to );
+ impl::s_frk_state().m_observers.erase( &to );
}
//____________________________________________________________________________//
+// ************************************************************************** //
+// ************** add_context ************** //
+// ************************************************************************** //
+
+int
+add_context( ::boost::unit_test::lazy_ostream const& context_descr, bool sticky )
+{
+ std::stringstream buffer;
+ context_descr( buffer );
+ int res_idx = impl::s_frk_state().m_context_idx++;
+
+ impl::s_frk_state().m_context.push_back( state::context_frame( buffer.str(), res_idx, sticky ) );
+
+ return res_idx;
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** clear_context ************** //
+// ************************************************************************** //
+
+struct frame_with_id {
+ explicit frame_with_id( int id ) : m_id( id ) {}
+
+ bool operator()( state::context_frame const& f )
+ {
+ return f.frame_id == m_id;
+ }
+ int m_id;
+};
+
+//____________________________________________________________________________//
+
void
-reset_observers()
+clear_context( int frame_id )
+{
+ if( frame_id == -1 ) { // clear all non sticky frames
+ for( int i=static_cast<int>(impl::s_frk_state().m_context.size())-1; i>=0; i-- )
+ if( !impl::s_frk_state().m_context[i].is_sticky )
+ impl::s_frk_state().m_context.erase( impl::s_frk_state().m_context.begin()+i );
+ }
+
+ else { // clear specific frame
+ state::context_data::iterator it =
+ std::find_if( impl::s_frk_state().m_context.begin(), impl::s_frk_state().m_context.end(), frame_with_id( frame_id ) );
+
+ if( it != impl::s_frk_state().m_context.end() ) // really an internal error if this is not true
+ impl::s_frk_state().m_context.erase( it );
+ }
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** get_context ************** //
+// ************************************************************************** //
+
+context_generator
+get_context()
+{
+ return context_generator();
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** context_generator ************** //
+// ************************************************************************** //
+
+bool
+context_generator::is_empty() const
{
- s_frk_impl().m_observers.clear();
+ return impl::s_frk_state().m_context.empty();
}
//____________________________________________________________________________//
+const_string
+context_generator::next() const
+{
+ return m_curr_frame < impl::s_frk_state().m_context.size() ? impl::s_frk_state().m_context[m_curr_frame++].descr : const_string();
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** master_test_suite ************** //
+// ************************************************************************** //
+
master_test_suite_t&
master_test_suite()
{
- if( !s_frk_impl().m_master_test_suite )
- s_frk_impl().m_master_test_suite = new master_test_suite_t;
+ if( !impl::s_frk_state().m_master_test_suite )
+ impl::s_frk_state().m_master_test_suite = new master_test_suite_t;
- return *s_frk_impl().m_master_test_suite;
+ return *impl::s_frk_state().m_master_test_suite;
}
//____________________________________________________________________________//
+// ************************************************************************** //
+// ************** current_auto_test_suite ************** //
+// ************************************************************************** //
+
+test_suite&
+current_auto_test_suite( test_suite* ts, bool push_or_pop )
+{
+ if( impl::s_frk_state().m_auto_test_suites.empty() )
+ impl::s_frk_state().m_auto_test_suites.push_back( &framework::master_test_suite() );
+
+ if( !push_or_pop )
+ impl::s_frk_state().m_auto_test_suites.pop_back();
+ else if( ts )
+ impl::s_frk_state().m_auto_test_suites.push_back( ts );
+
+ return *impl::s_frk_state().m_auto_test_suites.back();
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** current_test_case ************** //
+// ************************************************************************** //
+
test_case const&
current_test_case()
{
- return get<test_case>( s_frk_impl().m_curr_test_case );
+ return get<test_case>( impl::s_frk_state().m_curr_test_case );
}
//____________________________________________________________________________//
+test_unit_id
+current_test_case_id()
+{
+ return impl::s_frk_state().m_curr_test_case;
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** framework::get ************** //
+// ************************************************************************** //
+
test_unit&
get( test_unit_id id, test_unit_type t )
{
- test_unit* res = s_frk_impl().m_test_units[id];
+ test_unit* res = impl::s_frk_state().m_test_units[id];
if( (res->p_type & t) == 0 )
- throw internal_error( "Invalid test unit type" );
+ BOOST_TEST_IMPL_THROW( internal_error( "Invalid test unit type" ) );
return *res;
}
//____________________________________________________________________________//
+// ************************************************************************** //
+// ************** framework::run ************** //
+// ************************************************************************** //
+
void
run( test_unit_id id, bool continue_test )
{
if( id == INV_TEST_UNIT_ID )
id = master_test_suite().p_id;
+ // Figure out run status for execution phase
+ impl::s_frk_state().deduce_run_status( id );
+
test_case_counter tcc;
traverse_test_tree( id, tcc );
- BOOST_TEST_SETUP_ASSERT( tcc.p_count != 0 , runtime_config::test_to_run().is_empty()
- ? BOOST_TEST_L( "test tree is empty" )
- : BOOST_TEST_L( "no test cases matching filter" ) );
+ BOOST_TEST_SETUP_ASSERT( tcc.p_count != 0 , runtime_config::test_to_run().empty()
+ ? BOOST_TEST_L( "test tree is empty" )
+ : BOOST_TEST_L( "no test cases matching filter or all test cases were disabled" ) );
- bool call_start_finish = !continue_test || !s_frk_impl().m_test_in_progress;
- bool was_in_progress = s_frk_impl().m_test_in_progress;
+ bool was_in_progress = framework::test_in_progress();
+ bool call_start_finish = !continue_test || !was_in_progress;
- s_frk_impl().m_test_in_progress = true;
+ impl::s_frk_state().m_test_in_progress = true;
if( call_start_finish ) {
- BOOST_TEST_FOREACH( test_observer*, to, s_frk_impl().m_observers ) {
- boost::execution_monitor em;
-
- try {
- em.execute( ut_detail::test_start_caller( to, tcc.p_count ) );
+ BOOST_TEST_FOREACH( test_observer*, to, impl::s_frk_state().m_observers ) {
+ BOOST_TEST_IMPL_TRY {
+ impl::s_frk_state().m_aux_em.vexecute( boost::bind( &test_observer::test_start, to, tcc.p_count ) );
}
- catch( execution_exception const& ex ) {
- throw setup_error( ex.what() );
+ BOOST_TEST_IMPL_CATCH( execution_exception, ex ) {
+ BOOST_TEST_SETUP_ASSERT( false, ex.what() );
}
}
}
@@ -428,7 +1205,7 @@ run( test_unit_id id, bool continue_test )
case 0:
break;
case 1: {
- unsigned int seed = static_cast<unsigned int>( std::time( 0 ) );
+ unsigned seed = static_cast<unsigned>( std::time( 0 ) );
BOOST_TEST_MESSAGE( "Test cases order is shuffled using seed: " << seed );
std::srand( seed );
break;
@@ -438,19 +1215,14 @@ run( test_unit_id id, bool continue_test )
std::srand( runtime_config::random_seed() );
}
- try {
- traverse_test_tree( id, s_frk_impl() );
- }
- catch( test_being_aborted const& ) {
- // abort already reported
- }
+ impl::s_frk_state().execute_test_tree( id );
if( call_start_finish ) {
- BOOST_TEST_FOREACH( test_observer*, to, s_frk_impl().m_observers )
+ BOOST_TEST_REVERSE_FOREACH( test_observer*, to, impl::s_frk_state().m_observers )
to->test_finish();
}
- s_frk_impl().m_test_in_progress = was_in_progress;
+ impl::s_frk_state().m_test_in_progress = was_in_progress;
}
//____________________________________________________________________________//
@@ -463,41 +1235,49 @@ run( test_unit const* tu, bool continue_test )
//____________________________________________________________________________//
+// ************************************************************************** //
+// ************** assertion_result ************** //
+// ************************************************************************** //
+
void
-assertion_result( bool passed )
+assertion_result( unit_test::assertion_result ar )
{
- BOOST_TEST_FOREACH( test_observer*, to, s_frk_impl().m_observers )
- to->assertion_result( passed );
+ BOOST_TEST_FOREACH( test_observer*, to, impl::s_frk_state().m_observers )
+ to->assertion_result( ar );
}
//____________________________________________________________________________//
+// ************************************************************************** //
+// ************** exception_caught ************** //
+// ************************************************************************** //
+
void
exception_caught( execution_exception const& ex )
{
- BOOST_TEST_FOREACH( test_observer*, to, s_frk_impl().m_observers )
+ BOOST_TEST_FOREACH( test_observer*, to, impl::s_frk_state().m_observers )
to->exception_caught( ex );
}
//____________________________________________________________________________//
+// ************************************************************************** //
+// ************** test_unit_aborted ************** //
+// ************************************************************************** //
+
void
test_unit_aborted( test_unit const& tu )
{
- BOOST_TEST_FOREACH( test_observer*, to, s_frk_impl().m_observers )
+ BOOST_TEST_FOREACH( test_observer*, to, impl::s_frk_state().m_observers )
to->test_unit_aborted( tu );
}
//____________________________________________________________________________//
} // namespace framework
-
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_FRAMEWORK_IPP_021005GER
diff --git a/boost/test/impl/interaction_based.ipp b/boost/test/impl/interaction_based.ipp
deleted file mode 100644
index ce2893364a..0000000000
--- a/boost/test/impl/interaction_based.ipp
+++ /dev/null
@@ -1,90 +0,0 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
-// http://www.boost.org/LICENSE_1_0.txt)
-
-// See http://www.boost.org/libs/test for the library home page.
-//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : Facilities to perform interaction-based testing
-// ***************************************************************************
-
-#ifndef BOOST_TEST_INTERACTION_BASED_IPP_112105GER
-#define BOOST_TEST_INTERACTION_BASED_IPP_112105GER
-
-// Boost.Test
-#include <boost/test/detail/config.hpp>
-
-#if BOOST_TEST_SUPPORT_INTERACTION_TESTING
-
-// Boost.Test
-#include <boost/test/detail/config.hpp>
-#include <boost/test/utils/callback.hpp>
-#include <boost/test/interaction_based.hpp>
-#include <boost/test/mock_object.hpp>
-#include <boost/test/framework.hpp> // for setup_error
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-// STL
-#include <stdexcept>
-#include <string>
-
-//____________________________________________________________________________//
-
-namespace boost {
-
-namespace itest { // interaction-based testing
-
-// ************************************************************************** //
-// ************** manager ************** //
-// ************************************************************************** //
-
-manager::manager()
-{
- instance_ptr( true, this );
-}
-
-//____________________________________________________________________________//
-
-manager::~manager()
-{
- instance_ptr( true );
-}
-
-//____________________________________________________________________________//
-
-manager*
-manager::instance_ptr( bool reset, manager* new_ptr )
-{
- static manager dummy( 0 );
-
- static manager* ptr = &dummy;
-
- if( reset ) {
- if( new_ptr ) {
- BOOST_TEST_SETUP_ASSERT( ptr == &dummy, BOOST_TEST_L( "Can't run two interation based test the same time" ) );
-
- ptr = new_ptr;
- }
- else
- ptr = &dummy;
- }
-
- return ptr;
-}
-
-} // namespace itest
-
-} // namespace boost
-
-//____________________________________________________________________________//
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // not ancient compiler
-
-#endif // BOOST_TEST_INTERACTION_BASED_IPP_112105GER
diff --git a/boost/test/impl/logged_expectations.ipp b/boost/test/impl/logged_expectations.ipp
deleted file mode 100644
index ff30628b8e..0000000000
--- a/boost/test/impl/logged_expectations.ipp
+++ /dev/null
@@ -1,246 +0,0 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, ELOG_VER 1.0. (See accompanying file
-// http://www.boost.org/LICENSE_1_0.txt)
-
-// See http://www.boost.org/libs/test for the library home page.
-//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : Facilities to perform interaction based testng of logged expectations
-// ***************************************************************************
-
-#ifndef BOOST_TEST_LOGGED_EXPECTATIONS_IPP_120905GER
-#define BOOST_TEST_LOGGED_EXPECTATIONS_IPP_120905GER
-
-// Boost.Test
-#include <boost/test/detail/config.hpp>
-
-#if BOOST_TEST_SUPPORT_INTERACTION_TESTING
-
-#include <boost/test/detail/global_typedef.hpp>
-
-#include <boost/test/utils/callback.hpp>
-#include <boost/test/utils/iterator/token_iterator.hpp>
-
-#include <boost/test/interaction_based.hpp>
-#include <boost/test/test_tools.hpp>
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-// Boost
-#include <boost/lexical_cast.hpp>
-
-// STL
-#include <fstream>
-
-//____________________________________________________________________________//
-
-namespace boost {
-
-using namespace ::boost::unit_test;
-
-namespace itest {
-
-// ************************************************************************** //
-// ************** logged expectation test implementation ************** //
-// ************************************************************************** //
-
-struct expectations_logger : itest::manager {
- // Constructor
- expectations_logger( const_string log_file_name, bool test_or_log );
-
- virtual bool decision_point( const_string, std::size_t );
- virtual unsigned enter_scope( const_string, std::size_t, const_string scope_name );
- virtual void allocated( const_string, std::size_t, void*, std::size_t s );
- virtual void data_flow( const_string d );
- virtual std::string return_value( const_string default_value );
-
-private:
- // Data members
- bool m_test_or_log;
- std::fstream m_log_file;
-};
-
-literal_string ELOG_VER = "1.0";
-literal_string CLMN_SEP = "|";
-static const char LINE_SEP = '\n';
-
-literal_string FILE_SIG = "ELOG";
-literal_string SCOPE_SIG = "SCOPE";
-literal_string ALLOC_SIG = "ALLOC";
-literal_string DP_SIG = "SWITCH";
-literal_string DATA_SIG = "DATA";
-literal_string RETURN_SIG = "RETURN";
-
-//____________________________________________________________________________//
-
-expectations_logger::expectations_logger( const_string log_file_name, bool test_or_log )
-: m_test_or_log( test_or_log )
-{
- BOOST_REQUIRE_MESSAGE( !log_file_name.is_empty(), "Empty expectations log file name" );
-
- m_log_file.open( log_file_name.begin(), test_or_log ? std::ios::in : std::ios::out );
-
- BOOST_REQUIRE_MESSAGE( m_log_file.is_open(),
- "Can't open expectations log file " << log_file_name
- << " for " << ( m_test_or_log ? "reading" : "writing") );
-
- if( m_test_or_log ) {
- std::string line;
-
- std::getline( m_log_file, line, LINE_SEP );
-
- const_string cline( line );
- string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
-
- BOOST_CHECK_EQUAL( *tit, FILE_SIG );
- ++tit;
- BOOST_CHECK_EQUAL( *tit, ELOG_VER );
- }
- else {
- m_log_file << FILE_SIG << CLMN_SEP << ELOG_VER << LINE_SEP;
- }
-}
-
-//____________________________________________________________________________//
-
-bool
-expectations_logger::decision_point( const_string, std::size_t )
-{
- if( m_test_or_log ) {
- std::string line;
-
- std::getline( m_log_file, line, LINE_SEP );
-
- const_string cline( line );
- string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
-
- BOOST_CHECK_EQUAL( *tit, DP_SIG ); ++tit;
- return lexical_cast<bool>( *tit );
- }
- else {
- m_log_file << DP_SIG << CLMN_SEP << std::boolalpha << true << LINE_SEP;
-
- return true;
- }
-}
-
-//____________________________________________________________________________//
-
-unsigned
-expectations_logger::enter_scope( const_string, std::size_t, const_string scope_name )
-{
- if( m_test_or_log ) {
- std::string line;
-
- std::getline( m_log_file, line, LINE_SEP );
-
- const_string cline( line );
- string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
-
- BOOST_CHECK_EQUAL( *tit, SCOPE_SIG ); ++tit;
- BOOST_CHECK_EQUAL( *tit, scope_name );
- }
- else {
- m_log_file << SCOPE_SIG << CLMN_SEP << scope_name << LINE_SEP;
- }
-
- return 0;
-}
-
-//____________________________________________________________________________//
-
-void
-expectations_logger::allocated( const_string, std::size_t, void*, std::size_t s )
-{
- if( m_test_or_log ) {
- std::string line;
-
- std::getline( m_log_file, line, LINE_SEP );
-
- const_string cline( line );
- string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
-
- BOOST_CHECK_EQUAL( *tit, ALLOC_SIG ); ++tit;
- BOOST_CHECK_EQUAL( lexical_cast<std::size_t>( *tit ), s );
- }
- else {
- m_log_file << ALLOC_SIG << CLMN_SEP << s << LINE_SEP;
- }
-}
-
-//____________________________________________________________________________//
-
-void
-expectations_logger::data_flow( const_string d )
-{
- if( m_test_or_log ) {
- std::string line;
-
- std::getline( m_log_file, line, LINE_SEP );
-
- const_string cline( line );
- string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
-
- BOOST_CHECK_EQUAL( *tit, DATA_SIG ); ++tit;
- BOOST_CHECK_EQUAL( *tit, d );
- }
- else {
- m_log_file << DATA_SIG << CLMN_SEP << d << LINE_SEP;
- }
-}
-
-//____________________________________________________________________________//
-
-std::string
-expectations_logger::return_value( const_string default_value )
-{
- if( m_test_or_log ) {
- std::string line;
-
- std::getline( m_log_file, line, LINE_SEP );
-
- const_string cline( line );
- string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
-
- BOOST_CHECK_EQUAL( *tit, RETURN_SIG ); ++tit;
-
- return std::string( tit->begin(), tit->size() );
- }
- else {
- m_log_file << RETURN_SIG << CLMN_SEP << default_value << LINE_SEP;
-
- return std::string();
- }
-}
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** logged expectations test ************** //
-// ************************************************************************** //
-
-void BOOST_TEST_DECL
-logged_expectations( callback0<> const& F, const_string log_file_name, bool test_or_log )
-{
- expectations_logger el( log_file_name, test_or_log );
-
- F();
-}
-
-//____________________________________________________________________________//
-
-} // namespace itest
-
-} // namespace boost
-
-//____________________________________________________________________________//
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // not ancient compiler
-
-#endif // BOOST_TEST_LOGGED_EXPECTATIONS_IPP_120905GER
diff --git a/boost/test/impl/plain_report_formatter.ipp b/boost/test/impl/plain_report_formatter.ipp
index 95b662135d..f9e7db772a 100644
--- a/boost/test/impl/plain_report_formatter.ipp
+++ b/boost/test/impl/plain_report_formatter.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 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)
@@ -19,9 +19,13 @@
#include <boost/test/output/plain_report_formatter.hpp>
#include <boost/test/utils/custom_manip.hpp>
#include <boost/test/results_collector.hpp>
-#include <boost/test/unit_test_suite_impl.hpp>
+
+#include <boost/test/tree/test_unit.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
+#include <boost/test/utils/setcolor.hpp>
+
+#include <boost/test/unit_test_parameters.hpp>
// STL
#include <iomanip>
@@ -37,9 +41,7 @@ namespace std { using ::log10; }
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
-
namespace output {
namespace {
@@ -58,17 +60,16 @@ operator<<( custom_printer<quote> const& p, T const& value )
//____________________________________________________________________________//
void
-print_stat_value( std::ostream& ostr, counter_t v, counter_t indent, counter_t total,
- const_string name, const_string res )
+print_stat_value( std::ostream& ostr, counter_t v, counter_t indent, counter_t total, const_string name, const_string res )
{
- if( v > 0 ) {
- ostr << std::setw( indent ) << ""
- << v << ' ' << name << ( v != 1 ? "s" : "" );
- if( total > 0 )
- ostr << " out of " << total;
+ if( v == 0 )
+ return;
- ostr << ' ' << res << '\n';
- }
+ if( total > 0 )
+ ostr << std::setw( static_cast<int>(indent) ) << "" << v << ' ' << name << ( v != 1 ? "s" : "" )
+ << " out of " << total << ' ' << res << '\n';
+ else
+ ostr << std::setw( static_cast<int>(indent) ) << "" << v << ' ' << res << ' ' << name << ( v != 1 ? "s" : "" ) << '\n';
}
//____________________________________________________________________________//
@@ -104,40 +105,42 @@ plain_report_formatter::test_unit_report_start( test_unit const& tu, std::ostrea
const_string descr;
if( tr.passed() )
- descr = "passed";
+ descr = "has passed";
else if( tr.p_skipped )
- descr = "skipped";
+ descr = "was skipped";
else if( tr.p_aborted )
- descr = "aborted";
+ descr = "was aborted";
else
- descr = "failed";
+ descr = "has failed";
- ostr << std::setw( m_indent ) << ""
- << "Test " << (tu.p_type == tut_case ? "case " : "suite " ) << quote() << tu.p_name << ' ' << descr;
+ ostr << std::setw( static_cast<int>(m_indent) ) << ""
+ << "Test " << tu.p_type_name << ' ' << quote() << tu.full_name() << ' ' << descr;
if( tr.p_skipped ) {
- ostr << " due to " << (tu.check_dependencies() ? "test aborting\n" : "failed dependancy\n" );
+ ostr << "\n";
m_indent += 2;
return;
}
-
+
counter_t total_assertions = tr.p_assertions_passed + tr.p_assertions_failed;
- counter_t total_tc = tr.p_test_cases_passed + tr.p_test_cases_failed + tr.p_test_cases_skipped;
+ counter_t total_tc = tr.p_test_cases_passed + tr.p_test_cases_warned + tr.p_test_cases_failed + tr.p_test_cases_skipped;
- if( total_assertions > 0 || total_tc > 0 )
+ if( total_assertions > 0 || total_tc > 0 || tr.p_warnings_failed > 0)
ostr << " with:";
ostr << '\n';
m_indent += 2;
- print_stat_value( ostr, tr.p_assertions_passed, m_indent, total_assertions, "assertion", "passed" );
- print_stat_value( ostr, tr.p_assertions_failed, m_indent, total_assertions, "assertion", "failed" );
- print_stat_value( ostr, tr.p_expected_failures, m_indent, 0 , "failure" , "expected" );
- print_stat_value( ostr, tr.p_test_cases_passed, m_indent, total_tc , "test case", "passed" );
- print_stat_value( ostr, tr.p_test_cases_failed, m_indent, total_tc , "test case", "failed" );
- print_stat_value( ostr, tr.p_test_cases_skipped, m_indent, total_tc , "test case", "skipped" );
- print_stat_value( ostr, tr.p_test_cases_aborted, m_indent, total_tc , "test case", "aborted" );
-
+ print_stat_value( ostr, tr.p_test_cases_passed , m_indent, total_tc , "test case", "passed" );
+ print_stat_value( ostr, tr.p_test_cases_warned , m_indent, total_tc , "test case", "passed with warnings" );
+ print_stat_value( ostr, tr.p_test_cases_failed , m_indent, total_tc , "test case", "failed" );
+ print_stat_value( ostr, tr.p_test_cases_skipped, m_indent, total_tc , "test case", "skipped" );
+ print_stat_value( ostr, tr.p_test_cases_aborted, m_indent, total_tc , "test case", "aborted" );
+ print_stat_value( ostr, tr.p_assertions_passed , m_indent, total_assertions, "assertion", "passed" );
+ print_stat_value( ostr, tr.p_assertions_failed , m_indent, total_assertions, "assertion", "failed" );
+ print_stat_value( ostr, tr.p_warnings_failed , m_indent, 0 , "warning" , "failed" );
+ print_stat_value( ostr, tr.p_expected_failures , m_indent, 0 , "failure" , "expected" );
+
ostr << '\n';
}
@@ -155,44 +158,50 @@ void
plain_report_formatter::do_confirmation_report( test_unit const& tu, std::ostream& ostr )
{
test_results const& tr = results_collector.results( tu.p_id );
-
+
if( tr.passed() ) {
+ BOOST_TEST_SCOPE_SETCOLOR( ostr, term_attr::BRIGHT, term_color::GREEN );
+
ostr << "*** No errors detected\n";
return;
}
-
+
+ BOOST_TEST_SCOPE_SETCOLOR( ostr, term_attr::BRIGHT, term_color::RED );
+
if( tr.p_skipped ) {
- ostr << "*** Test " << tu.p_type_name << " skipped due to "
- << (tu.check_dependencies() ? "test aborting\n" : "failed dependancy\n" );
+ ostr << "*** The test " << tu.p_type_name << ' ' << quote() << tu.full_name() << " was skipped"
+ << "; see standard output for details\n";
return;
}
- if( tr.p_assertions_failed == 0 ) {
- ostr << "*** errors detected in test " << tu.p_type_name << " " << quote() << tu.p_name
+ if( tr.p_aborted ) {
+ ostr << "*** The test " << tu.p_type_name << ' ' << quote() << tu.full_name() << " was aborted"
<< "; see standard output for details\n";
+ }
+
+ if( tr.p_assertions_failed == 0 ) {
+ if( !tr.p_aborted )
+ ostr << "*** Errors were detected in the test " << tu.p_type_name << ' ' << quote() << tu.full_name()
+ << "; see standard output for details\n";
return;
}
counter_t num_failures = tr.p_assertions_failed;
-
- ostr << "*** " << num_failures << " failure" << ( num_failures != 1 ? "s" : "" ) << " detected";
-
+
+ ostr << "*** " << num_failures << " failure" << ( num_failures != 1 ? "s are" : " is" ) << " detected";
+
if( tr.p_expected_failures > 0 )
- ostr << " (" << tr.p_expected_failures << " failure" << ( tr.p_expected_failures != 1 ? "s" : "" ) << " expected)";
-
- ostr << " in test " << tu.p_type_name << " " << quote() << tu.p_name << "\n";
+ ostr << " (" << tr.p_expected_failures << " failure" << ( tr.p_expected_failures != 1 ? "s are" : " is" ) << " expected)";
+
+ ostr << " in the test " << tu.p_type_name << " " << quote() << tu.full_name() << "\n";
}
//____________________________________________________________________________//
} // namespace output
-
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_PLAIN_REPORT_FORMATTER_IPP_020105GER
diff --git a/boost/test/impl/progress_monitor.ipp b/boost/test/impl/progress_monitor.ipp
index 5175755c3a..ebdd7e9320 100644
--- a/boost/test/impl/progress_monitor.ipp
+++ b/boost/test/impl/progress_monitor.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 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)
@@ -17,12 +17,15 @@
// Boost.Test
#include <boost/test/progress_monitor.hpp>
-#include <boost/test/unit_test_suite_impl.hpp>
-#include <boost/test/detail/unit_test_parameters.hpp>
+#include <boost/test/unit_test_parameters.hpp>
+#include <boost/test/utils/setcolor.hpp>
+
+#include <boost/test/tree/test_unit.hpp>
+#include <boost/test/tree/test_case_counter.hpp>
+#include <boost/test/tree/traverse.hpp>
// Boost
-#include <boost/progress.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
@@ -30,13 +33,70 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
// ************************************************************************** //
// ************** progress_monitor ************** //
// ************************************************************************** //
+struct progress_display {
+ progress_display( counter_t expected_count, std::ostream& os )
+ : m_os(os)
+ , m_count( 0 )
+ , m_expected_count( expected_count )
+ , m_next_tic_count( 0 )
+ , m_tic( 0 )
+ {
+
+ m_os << "\n0% 10 20 30 40 50 60 70 80 90 100%"
+ << "\n|----|----|----|----|----|----|----|----|----|----|"
+ << std::endl;
+
+ if( !m_expected_count )
+ m_expected_count = 1; // prevent divide by zero
+ }
+
+ unsigned long operator+=( unsigned long increment )
+ {
+ if( (m_count += increment) < m_next_tic_count )
+ return m_count;
+
+ // use of floating point ensures that both large and small counts
+ // work correctly. static_cast<>() is also used several places
+ // to suppress spurious compiler warnings.
+ unsigned int tics_needed = static_cast<unsigned int>(
+ (static_cast<double>(m_count)/m_expected_count)*50.0 );
+
+ do {
+ m_os << '*' << std::flush;
+ } while( ++m_tic < tics_needed );
+
+ m_next_tic_count = static_cast<unsigned long>((m_tic/50.0) * m_expected_count);
+
+ if( m_count == m_expected_count ) {
+ if( m_tic < 51 )
+ m_os << '*';
+
+ m_os << std::endl;
+ }
+
+ return m_count;
+ }
+ unsigned long operator++() { return operator+=( 1 ); }
+ unsigned long count() const { return m_count; }
+
+private:
+ BOOST_DELETED_FUNCTION(progress_display(progress_display const&))
+ BOOST_DELETED_FUNCTION(progress_display& operator=(progress_display const&))
+
+ std::ostream& m_os; // may not be present in all imps
+
+ unsigned long m_count;
+ unsigned long m_expected_count;
+ unsigned long m_next_tic_count;
+ unsigned int m_tic;
+};
+
namespace {
struct progress_monitor_impl {
@@ -58,6 +118,8 @@ progress_monitor_impl& s_pm_impl() { static progress_monitor_impl the_inst; retu
void
progress_monitor_t::test_start( counter_t test_cases_amount )
{
+ BOOST_TEST_SCOPE_SETCOLOR( *s_pm_impl().m_stream, term_attr::BRIGHT, term_color::MAGENTA );
+
s_pm_impl().m_progress_display.reset( new progress_display( test_cases_amount, *s_pm_impl().m_stream ) );
}
@@ -66,6 +128,8 @@ progress_monitor_t::test_start( counter_t test_cases_amount )
void
progress_monitor_t::test_aborted()
{
+ BOOST_TEST_SCOPE_SETCOLOR( *s_pm_impl().m_stream, term_attr::BRIGHT, term_color::MAGENTA );
+
(*s_pm_impl().m_progress_display) += s_pm_impl().m_progress_display->count();
}
@@ -74,18 +138,22 @@ progress_monitor_t::test_aborted()
void
progress_monitor_t::test_unit_finish( test_unit const& tu, unsigned long )
{
- if( tu.p_type == tut_case )
+ BOOST_TEST_SCOPE_SETCOLOR( *s_pm_impl().m_stream, term_attr::BRIGHT, term_color::MAGENTA );
+
+ if( tu.p_type == TUT_CASE )
++(*s_pm_impl().m_progress_display);
}
//____________________________________________________________________________//
void
-progress_monitor_t::test_unit_skipped( test_unit const& tu )
+progress_monitor_t::test_unit_skipped( test_unit const& tu, const_string /*reason*/ )
{
+ BOOST_TEST_SCOPE_SETCOLOR( *s_pm_impl().m_stream, term_attr::BRIGHT, term_color::MAGENTA );
+
test_case_counter tcc;
traverse_test_tree( tu, tcc );
-
+
(*s_pm_impl().m_progress_display) += tcc.p_count;
}
@@ -98,13 +166,10 @@ progress_monitor_t::set_stream( std::ostream& ostr )
}
//____________________________________________________________________________//
-
-} // namespace unit_test
+} // namespace unit_test
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_PROGRESS_MONITOR_IPP_020105GER
diff --git a/boost/test/impl/results_collector.ipp b/boost/test/impl/results_collector.ipp
index 0d5691aab6..d04d64fd6d 100644
--- a/boost/test/impl/results_collector.ipp
+++ b/boost/test/impl/results_collector.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 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)
@@ -16,11 +16,15 @@
#define BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
// Boost.Test
-#include <boost/test/unit_test_suite_impl.hpp>
#include <boost/test/unit_test_log.hpp>
#include <boost/test/results_collector.hpp>
#include <boost/test/framework.hpp>
+#include <boost/test/tree/test_unit.hpp>
+#include <boost/test/tree/visitor.hpp>
+#include <boost/test/tree/test_case_counter.hpp>
+#include <boost/test/tree/traverse.hpp>
+
// Boost
#include <boost/cstdlib.hpp>
@@ -32,7 +36,6 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
// ************************************************************************** //
@@ -52,6 +55,7 @@ test_results::passed() const
return !p_skipped &&
p_test_cases_failed == 0 &&
p_assertions_failed <= p_expected_failures &&
+ p_test_cases_skipped == 0 &&
!p_aborted;
}
@@ -73,7 +77,9 @@ test_results::operator+=( test_results const& tr )
{
p_assertions_passed.value += tr.p_assertions_passed;
p_assertions_failed.value += tr.p_assertions_failed;
+ p_warnings_failed.value += tr.p_warnings_failed;
p_test_cases_passed.value += tr.p_test_cases_passed;
+ p_test_cases_warned.value += tr.p_test_cases_warned;
p_test_cases_failed.value += tr.p_test_cases_failed;
p_test_cases_skipped.value += tr.p_test_cases_skipped;
p_test_cases_aborted.value += tr.p_test_cases_aborted;
@@ -84,25 +90,25 @@ test_results::operator+=( test_results const& tr )
void
test_results::clear()
{
- p_assertions_passed.value = 0;
- p_assertions_failed.value = 0;
- p_expected_failures.value = 0;
- p_test_cases_passed.value = 0;
- p_test_cases_failed.value = 0;
- p_test_cases_skipped.value = 0;
- p_test_cases_aborted.value = 0;
- p_aborted.value = false;
- p_skipped.value = true;
+ p_assertions_passed.value = 0;
+ p_assertions_failed.value = 0;
+ p_warnings_failed.value = 0;
+ p_expected_failures.value = 0;
+ p_test_cases_passed.value = 0;
+ p_test_cases_warned.value = 0;
+ p_test_cases_failed.value = 0;
+ p_test_cases_skipped.value = 0;
+ p_test_cases_aborted.value = 0;
+ p_aborted.value = false;
+ p_skipped.value = false;
}
//____________________________________________________________________________//
-
+
// ************************************************************************** //
// ************** results_collector ************** //
// ************************************************************************** //
-#if !BOOST_WORKAROUND(BOOST_MSVC, <1300)
-
namespace {
struct results_collector_impl {
@@ -113,16 +119,6 @@ results_collector_impl& s_rc_impl() { static results_collector_impl the_inst; re
} // local namespace
-#else
-
-struct results_collector_impl {
- std::map<test_unit_id,test_results> m_results_store;
-};
-
-static results_collector_impl& s_rc_impl() { static results_collector_impl the_inst; return the_inst; }
-
-#endif
-
//____________________________________________________________________________//
void
@@ -134,31 +130,14 @@ results_collector_t::test_start( counter_t )
//____________________________________________________________________________//
void
-results_collector_t::test_finish()
-{
- // do nothing
-}
-
-//____________________________________________________________________________//
-
-void
-results_collector_t::test_aborted()
-{
- // do nothing
-}
-
-//____________________________________________________________________________//
-
-void
results_collector_t::test_unit_start( test_unit const& tu )
{
// init test_results entry
test_results& tr = s_rc_impl().m_results_store[tu.p_id];
tr.clear();
-
- tr.p_expected_failures.value = tu.p_expected_failures;
- tr.p_skipped.value = false;
+
+ tr.p_expected_failures.value = tu.p_expected_failures;
}
//____________________________________________________________________________//
@@ -172,13 +151,18 @@ public:
test_results const& tr = results_collector.results( tc.p_id );
m_tr += tr;
- if( tr.passed() )
- m_tr.p_test_cases_passed.value++;
+ if( tr.passed() ) {
+ if( tr.p_warnings_failed )
+ m_tr.p_test_cases_warned.value++;
+ else
+ m_tr.p_test_cases_passed.value++;
+ }
else if( tr.p_skipped )
m_tr.p_test_cases_skipped.value++;
else {
if( tr.p_aborted )
m_tr.p_test_cases_aborted.value++;
+
m_tr.p_test_cases_failed.value++;
}
}
@@ -186,10 +170,9 @@ public:
{
if( m_ts.p_id == ts.p_id )
return true;
- else {
- m_tr += results_collector.results( ts.p_id );
- return false;
- }
+
+ m_tr += results_collector.results( ts.p_id );
+ return false;
}
private:
@@ -203,53 +186,55 @@ private:
void
results_collector_t::test_unit_finish( test_unit const& tu, unsigned long )
{
- if( tu.p_type == tut_suite ) {
+ if( tu.p_type == TUT_SUITE ) {
results_collect_helper ch( s_rc_impl().m_results_store[tu.p_id], tu );
traverse_test_tree( tu, ch );
}
else {
test_results const& tr = s_rc_impl().m_results_store[tu.p_id];
-
+
bool num_failures_match = tr.p_aborted || tr.p_assertions_failed >= tr.p_expected_failures;
if( !num_failures_match )
- BOOST_TEST_MESSAGE( "Test case " << tu.p_name << " has fewer failures than expected" );
+ BOOST_TEST_MESSAGE( "Test case " << tu.full_name() << " has fewer failures than expected" );
bool check_any_assertions = tr.p_aborted || (tr.p_assertions_failed != 0) || (tr.p_assertions_passed != 0);
if( !check_any_assertions )
- BOOST_TEST_MESSAGE( "Test case " << tu.p_name << " did not check any assertions" );
+ BOOST_TEST_MESSAGE( "Test case " << tu.full_name() << " did not check any assertions" );
}
}
//____________________________________________________________________________//
void
-results_collector_t::test_unit_skipped( test_unit const& tu )
+results_collector_t::test_unit_skipped( test_unit const& tu, const_string /*reason*/ )
{
- if( tu.p_type == tut_suite ) {
+ test_results& tr = s_rc_impl().m_results_store[tu.p_id];
+
+ tr.clear();
+
+ tr.p_skipped.value = true;
+
+ if( tu.p_type == TUT_SUITE ) {
test_case_counter tcc;
traverse_test_tree( tu, tcc );
- test_results& tr = s_rc_impl().m_results_store[tu.p_id];
-
- tr.clear();
-
- tr.p_skipped.value = true;
- tr.p_test_cases_skipped.value = tcc.p_count;
+ tr.p_test_cases_skipped.value = tcc.p_count;
}
}
//____________________________________________________________________________//
void
-results_collector_t::assertion_result( bool passed )
+results_collector_t::assertion_result( unit_test::assertion_result ar )
{
- test_results& tr = s_rc_impl().m_results_store[framework::current_test_case().p_id];
+ test_results& tr = s_rc_impl().m_results_store[framework::current_test_case_id()];
- if( passed )
- tr.p_assertions_passed.value++;
- else
- tr.p_assertions_failed.value++;
+ switch( ar ) {
+ case AR_PASSED: tr.p_assertions_passed.value++; break;
+ case AR_FAILED: tr.p_assertions_failed.value++; break;
+ case AR_TRIGGERED: tr.p_warnings_failed.value++; break;
+ }
if( tr.p_assertions_failed == 1 )
first_failed_assertion();
@@ -260,7 +245,7 @@ results_collector_t::assertion_result( bool passed )
void
results_collector_t::exception_caught( execution_exception const& )
{
- test_results& tr = s_rc_impl().m_results_store[framework::current_test_case().p_id];
+ test_results& tr = s_rc_impl().m_results_store[framework::current_test_case_id()];
tr.p_assertions_failed.value++;
}
@@ -284,11 +269,8 @@ results_collector_t::results( test_unit_id id ) const
//____________________________________________________________________________//
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
diff --git a/boost/test/impl/results_reporter.ipp b/boost/test/impl/results_reporter.ipp
index 54447c3932..885295c928 100644
--- a/boost/test/impl/results_reporter.ipp
+++ b/boost/test/impl/results_reporter.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 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)
@@ -17,13 +17,16 @@
// Boost.Test
#include <boost/test/results_reporter.hpp>
-#include <boost/test/unit_test_suite_impl.hpp>
#include <boost/test/results_collector.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/output/plain_report_formatter.hpp>
#include <boost/test/output/xml_report_formatter.hpp>
-#include <boost/test/detail/unit_test_parameters.hpp>
+#include <boost/test/tree/visitor.hpp>
+#include <boost/test/tree/test_unit.hpp>
+#include <boost/test/tree/traverse.hpp>
+
+#include <boost/test/unit_test_parameters.hpp>
// Boost
#include <boost/scoped_ptr.hpp>
@@ -38,9 +41,7 @@ typedef ::boost::io::ios_base_all_saver io_saver_type;
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
-
namespace results_reporter {
// ************************************************************************** //
@@ -126,14 +127,13 @@ void
set_format( output_format rf )
{
switch( rf ) {
- case CLF:
+ default:
+ case OF_CLF:
set_format( new output::plain_report_formatter );
break;
- case XML:
+ case OF_XML:
set_format( new output::xml_report_formatter );
break;
- default:
- break;
}
}
@@ -190,13 +190,9 @@ make_report( report_level l, test_unit_id id )
//____________________________________________________________________________//
} // namespace results_reporter
-
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_RESULTS_REPORTER_IPP_020105GER
diff --git a/boost/test/impl/test_main.ipp b/boost/test/impl/test_main.ipp
index b08f5e16c7..c95c91e88b 100644
--- a/boost/test/impl/test_main.ipp
+++ b/boost/test/impl/test_main.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// (C) Copyright Beman Dawes 1995-2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -6,11 +6,8 @@
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $$Revision$
-//
-// Description : implements main function for Test Execution Monitor.
+/// @file
+/// @brief Implements main function for Test Execution Monitor.
// ***************************************************************************
#ifndef BOOST_TEST_TEST_MAIN_IPP_012205GER
@@ -32,16 +29,16 @@ extern int test_main( int argc, char* argv[] ); // prototype for user's test_
struct test_main_caller {
test_main_caller( int argc, char** argv ) : m_argc( argc ), m_argv( argv ) {}
-
+
void operator()() {
int test_main_result = test_main( m_argc, m_argv );
// translate a test_main non-success return into a test error
BOOST_CHECK( test_main_result == 0 || test_main_result == boost::exit_success );
}
-
+
private:
- // Data members
+ // Data members
int m_argc;
char** m_argv;
};
@@ -53,11 +50,11 @@ private:
::boost::unit_test::test_suite*
init_unit_test_suite( int argc, char* argv[] ) {
using namespace ::boost::unit_test;
-
+
framework::master_test_suite().p_name.value = "Test Program";
-
+
framework::master_test_suite().add( BOOST_TEST_CASE( test_main_caller( argc, argv ) ) );
-
+
return 0;
}
diff --git a/boost/test/impl/test_tools.ipp b/boost/test/impl/test_tools.ipp
index 6f5d7e9edf..03fea91605 100644
--- a/boost/test/impl/test_tools.ipp
+++ b/boost/test/impl/test_tools.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 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)
@@ -16,12 +16,18 @@
#define BOOST_TEST_TEST_TOOLS_IPP_012205GER
// Boost.Test
-#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test_log.hpp>
-#include <boost/test/output_test_stream.hpp>
+#include <boost/test/tools/context.hpp>
+#include <boost/test/tools/output_test_stream.hpp>
+
+#include <boost/test/tools/detail/fwd.hpp>
+#include <boost/test/tools/detail/print_helper.hpp>
+
#include <boost/test/framework.hpp>
+#include <boost/test/tree/test_unit.hpp>
#include <boost/test/execution_monitor.hpp> // execution_aborted
-#include <boost/test/unit_test_suite_impl.hpp>
+
+#include <boost/test/detail/throw_exception.hpp>
// Boost
#include <boost/config.hpp>
@@ -33,6 +39,8 @@
#include <cctype>
#include <cwchar>
#include <stdexcept>
+#include <vector>
+#include <utility>
#include <ios>
// !! should we use #include <cstdarg>
@@ -50,8 +58,8 @@ namespace std { using ::wcscmp; }
# endif
namespace boost {
-
namespace test_tools {
+namespace tt_detail {
// ************************************************************************** //
// ************** print_log_value ************** //
@@ -105,119 +113,78 @@ print_log_value<wchar_t const*>::operator()( std::ostream& ostr, wchar_t const*
//____________________________________________________________________________//
-namespace tt_detail {
-
// ************************************************************************** //
// ************** TOOL BOX Implementation ************** //
// ************************************************************************** //
using ::boost::unit_test::lazy_ostream;
-bool
-check_impl( predicate_result const& pr, lazy_ostream const& check_descr,
- const_string file_name, std::size_t line_num,
- tool_level tl, check_type ct,
- std::size_t num_of_args, ... )
+static char const* check_str [] = { " == ", " != ", " < " , " <= ", " > " , " >= " };
+static char const* rever_str [] = { " != ", " == ", " >= ", " > " , " <= ", " < " };
+
+template<typename OutStream>
+void
+format_report( OutStream& os, assertion_result const& pr, unit_test::lazy_ostream const& assertion_descr,
+ tool_level tl, check_type ct,
+ std::size_t num_args, va_list args,
+ char const* prefix, char const* suffix )
{
using namespace unit_test;
- if( !framework::is_initialized() )
- throw std::runtime_error( "can't use testing tools before framework is initialized" );
-
- if( !!pr )
- tl = PASS;
-
- log_level ll;
- char const* prefix;
- char const* suffix;
-
- switch( tl ) {
- case PASS:
- ll = log_successful_tests;
- prefix = "check ";
- suffix = " passed";
- break;
- case WARN:
- ll = log_warnings;
- prefix = "condition ";
- suffix = " is not satisfied";
- break;
- case CHECK:
- ll = log_all_errors;
- prefix = "check ";
- suffix = " failed";
- break;
- case REQUIRE:
- ll = log_fatal_errors;
- prefix = "critical check ";
- suffix = " failed";
- break;
- default:
- return true;
- }
-
switch( ct ) {
case CHECK_PRED:
- unit_test_log << unit_test::log::begin( file_name, line_num )
- << ll << prefix << check_descr << suffix;
-
+ os << prefix << assertion_descr << suffix;
+
if( !pr.has_empty_message() )
- unit_test_log << ". " << pr.message();
-
- unit_test_log << unit_test::log::end();
+ os << ". " << pr.message();
break;
+ case CHECK_BUILT_ASSERTION: {
+ os << prefix << assertion_descr << suffix;
+
+ if( tl != PASS ) {
+ const_string details_message = pr.message();
+
+ if( !details_message.is_empty() ) {
+ os << details_message;
+ }
+ }
+ break;
+ }
+
case CHECK_MSG:
- unit_test_log << unit_test::log::begin( file_name, line_num ) << ll;
-
if( tl == PASS )
- unit_test_log << prefix << "'" << check_descr << "'" << suffix;
+ os << prefix << "'" << assertion_descr << "'" << suffix;
else
- unit_test_log << check_descr;
-
- if( !pr.has_empty_message() )
- unit_test_log << ". " << pr.message();
+ os << assertion_descr;
- unit_test_log << unit_test::log::end();
+ if( !pr.has_empty_message() )
+ os << ". " << pr.message();
break;
- case CHECK_EQUAL:
- case CHECK_NE:
- case CHECK_LT:
- case CHECK_LE:
- case CHECK_GT:
+ case CHECK_EQUAL:
+ case CHECK_NE:
+ case CHECK_LT:
+ case CHECK_LE:
+ case CHECK_GT:
case CHECK_GE: {
- static char const* check_str [] = { " == ", " != ", " < " , " <= ", " > " , " >= " };
- static char const* rever_str [] = { " != ", " == ", " >= ", " > " , " <= ", " < " };
-
- va_list args;
-
- va_start( args, num_of_args );
char const* arg1_descr = va_arg( args, char const* );
lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
char const* arg2_descr = va_arg( args, char const* );
lazy_ostream const* arg2_val = va_arg( args, lazy_ostream const* );
- unit_test_log << unit_test::log::begin( file_name, line_num )
- << ll << prefix << arg1_descr << check_str[ct-CHECK_EQUAL] << arg2_descr << suffix;
+ os << prefix << arg1_descr << check_str[ct-CHECK_EQUAL] << arg2_descr << suffix;
if( tl != PASS )
- unit_test_log << " [" << *arg1_val << rever_str[ct-CHECK_EQUAL] << *arg2_val << "]" ;
+ os << " [" << *arg1_val << rever_str[ct-CHECK_EQUAL] << *arg2_val << "]" ;
- va_end( args );
-
if( !pr.has_empty_message() )
- unit_test_log << ". " << pr.message();
-
- unit_test_log << unit_test::log::end();
+ os << ". " << pr.message();
break;
}
case CHECK_CLOSE:
case CHECK_CLOSE_FRACTION: {
- va_list args;
-
- va_start( args, num_of_args );
char const* arg1_descr = va_arg( args, char const* );
lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
char const* arg2_descr = va_arg( args, char const* );
@@ -225,151 +192,172 @@ check_impl( predicate_result const& pr, lazy_ostream const& check_descr,
/* toler_descr = */ va_arg( args, char const* );
lazy_ostream const* toler_val = va_arg( args, lazy_ostream const* );
- unit_test_log << unit_test::log::begin( file_name, line_num ) << ll;
-
- unit_test_log << "difference{" << pr.message() << (ct == CHECK_CLOSE ? "%" : "")
- << "} between " << arg1_descr << "{" << *arg1_val
- << "} and " << arg2_descr << "{" << *arg2_val
- << ( tl == PASS ? "} doesn't exceed " : "} exceeds " )
- << *toler_val;
+ os << "difference{" << pr.message()
+ << "} between " << arg1_descr << "{" << *arg1_val
+ << "} and " << arg2_descr << "{" << *arg2_val
+ << ( tl == PASS ? "} doesn't exceed " : "} exceeds " )
+ << *toler_val;
if( ct == CHECK_CLOSE )
- unit_test_log << "%";
-
- va_end( args );
-
- unit_test_log << unit_test::log::end();
+ os << "%";
break;
}
case CHECK_SMALL: {
- va_list args;
-
- va_start( args, num_of_args );
char const* arg1_descr = va_arg( args, char const* );
lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
/* toler_descr = */ va_arg( args, char const* );
lazy_ostream const* toler_val = va_arg( args, lazy_ostream const* );
- unit_test_log << unit_test::log::begin( file_name, line_num ) << ll;
-
- unit_test_log << "absolute value of " << arg1_descr << "{" << *arg1_val << "}"
- << ( tl == PASS ? " doesn't exceed " : " exceeds " )
- << *toler_val;
+ os << "absolute value of " << arg1_descr << "{" << *arg1_val << "}"
+ << ( tl == PASS ? " doesn't exceed " : " exceeds " )
+ << *toler_val;
- va_end( args );
-
if( !pr.has_empty_message() )
- unit_test_log << ". " << pr.message();
-
- unit_test_log << unit_test::log::end();
+ os << ". " << pr.message();
break;
}
case CHECK_PRED_WITH_ARGS: {
- unit_test_log << unit_test::log::begin( file_name, line_num )
- << ll << prefix << check_descr;
+ std::vector< std::pair<char const*, lazy_ostream const*> > args_copy;
+ args_copy.reserve( num_args );
+ for( std::size_t i = 0; i < num_args; ++i ) {
+ char const* desc = va_arg( args, char const* );
+ lazy_ostream const* value = va_arg( args, lazy_ostream const* );
+ args_copy.push_back( std::make_pair( desc, value ) );
+ }
+
+ os << prefix << assertion_descr;
// print predicate call description
- {
- va_list args;
- va_start( args, num_of_args );
-
- unit_test_log << "( ";
- for( std::size_t i = 0; i < num_of_args; ++i ) {
- unit_test_log << va_arg( args, char const* );
- va_arg( args, lazy_ostream const* ); // skip argument value;
-
- if( i != num_of_args-1 )
- unit_test_log << ", ";
- }
- unit_test_log << " )" << suffix;
- va_end( args );
+ os << "( ";
+ for( std::size_t i = 0; i < num_args; ++i ) {
+ os << args_copy[i].first;
+
+ if( i != num_args-1 )
+ os << ", ";
}
-
+ os << " )" << suffix;
+
if( tl != PASS ) {
- va_list args;
- va_start( args, num_of_args );
-
- unit_test_log << " for ( ";
- for( std::size_t i = 0; i < num_of_args; ++i ) {
- va_arg( args, char const* ); // skip argument description;
- unit_test_log << *va_arg( args, lazy_ostream const* );
-
- if( i != num_of_args-1 )
- unit_test_log << ", ";
+ os << " for ( ";
+ for( std::size_t i = 0; i < num_args; ++i ) {
+ os << *args_copy[i].second;
+
+ if( i != num_args-1 )
+ os << ", ";
}
- unit_test_log << " )";
- va_end( args );
+ os << " )";
}
-
- if( !pr.has_empty_message() )
- unit_test_log << ". " << pr.message();
- unit_test_log << unit_test::log::end();
+ if( !pr.has_empty_message() )
+ os << ". " << pr.message();
break;
}
case CHECK_EQUAL_COLL: {
- va_list args;
-
- va_start( args, num_of_args );
char const* left_begin_descr = va_arg( args, char const* );
char const* left_end_descr = va_arg( args, char const* );
char const* right_begin_descr = va_arg( args, char const* );
char const* right_end_descr = va_arg( args, char const* );
- unit_test_log << unit_test::log::begin( file_name, line_num )
- << ll << prefix
- << "{ " << left_begin_descr << ", " << left_end_descr << " } == { "
- << right_begin_descr << ", " << right_end_descr << " }"
- << suffix;
+ os << prefix << "{ " << left_begin_descr << ", " << left_end_descr << " } == { "
+ << right_begin_descr << ", " << right_end_descr << " }"
+ << suffix;
- va_end( args );
-
if( !pr.has_empty_message() )
- unit_test_log << ". " << pr.message();
-
- unit_test_log << unit_test::log::end();
+ os << ". " << pr.message();
break;
}
case CHECK_BITWISE_EQUAL: {
- va_list args;
-
- va_start( args, num_of_args );
char const* left_descr = va_arg( args, char const* );
char const* right_descr = va_arg( args, char const* );
- unit_test_log << unit_test::log::begin( file_name, line_num )
- << ll << prefix << left_descr << " =.= " << right_descr << suffix;
+ os << prefix << left_descr << " =.= " << right_descr << suffix;
- va_end( args );
-
if( !pr.has_empty_message() )
- unit_test_log << ". " << pr.message();
-
- unit_test_log << unit_test::log::end();
+ os << ". " << pr.message();
break;
}
}
+}
+
+//____________________________________________________________________________//
+
+bool
+report_assertion( assertion_result const& ar,
+ lazy_ostream const& assertion_descr,
+ const_string file_name,
+ std::size_t line_num,
+ tool_level tl,
+ check_type ct,
+ std::size_t num_args, ... )
+{
+ using namespace unit_test;
+
+ if( framework::current_test_case_id() == INV_TEST_UNIT_ID )
+ BOOST_TEST_IMPL_THROW(
+ std::runtime_error( "can't use testing tools outside of test case implementation" ) );
+
+ if( !!ar )
+ tl = PASS;
+
+ log_level ll;
+ char const* prefix;
+ char const* suffix;
switch( tl ) {
case PASS:
- framework::assertion_result( true );
+ ll = log_successful_tests;
+ prefix = "check ";
+ suffix = " has passed";
+ break;
+ case WARN:
+ ll = log_warnings;
+ prefix = "condition ";
+ suffix = " is not satisfied";
+ break;
+ case CHECK:
+ ll = log_all_errors;
+ prefix = "check ";
+ suffix = " has failed";
+ break;
+ case REQUIRE:
+ ll = log_fatal_errors;
+ prefix = "critical check ";
+ suffix = " has failed";
+ break;
+ default:
+ return true;
+ }
+
+ unit_test_log << unit_test::log::begin( file_name, line_num ) << ll;
+ va_list args;
+ va_start( args, num_args );
+
+ format_report( unit_test_log, ar, assertion_descr, tl, ct, num_args, args, prefix, suffix );
+
+ va_end( args );
+ unit_test_log << unit_test::log::end();
+
+ switch( tl ) {
+ case PASS:
+ framework::assertion_result( AR_PASSED );
return true;
case WARN:
+ framework::assertion_result( AR_TRIGGERED );
return false;
case CHECK:
- framework::assertion_result( false );
+ framework::assertion_result( AR_FAILED );
return false;
-
+
case REQUIRE:
- framework::assertion_result( false );
+ framework::assertion_result( AR_FAILED );
framework::test_unit_aborted( framework::current_test_case() );
- throw execution_aborted();
+ BOOST_TEST_IMPL_THROW( execution_aborted() );
}
return true;
@@ -377,7 +365,51 @@ check_impl( predicate_result const& pr, lazy_ostream const& check_descr,
//____________________________________________________________________________//
-predicate_result
+assertion_result
+format_assertion_result( const_string expr_val, const_string details )
+{
+ assertion_result res(false);
+
+ bool starts_new_line = first_char( expr_val ) == '\n';
+
+ if( !starts_new_line && !expr_val.is_empty() )
+ res.message().stream() << " [" << expr_val << "]";
+
+ if( !details.is_empty() ) {
+ if( first_char(details) != '[' )
+ res.message().stream() << ". ";
+ else
+ res.message().stream() << " ";
+
+ res.message().stream() << details;
+ }
+
+ if( starts_new_line )
+ res.message().stream() << "." << expr_val;
+
+ return res;
+}
+
+//____________________________________________________________________________//
+
+BOOST_TEST_DECL std::string
+prod_report_format( assertion_result const& ar, unit_test::lazy_ostream const& assertion_descr, check_type ct, std::size_t num_args, ... )
+{
+ std::ostringstream msg_buff;
+
+ va_list args;
+ va_start( args, num_args );
+
+ format_report( msg_buff, ar, assertion_descr, CHECK, ct, num_args, args, "assertion ", " failed" );
+
+ va_end( args );
+
+ return msg_buff.str();
+}
+
+//____________________________________________________________________________//
+
+assertion_result
equal_impl( char const* left, char const* right )
{
return (left && right) ? std::strcmp( left, right ) == 0 : (left == right);
@@ -387,7 +419,7 @@ equal_impl( char const* left, char const* right )
#if !defined( BOOST_NO_CWCHAR )
-predicate_result
+assertion_result
equal_impl( wchar_t const* left, wchar_t const* right )
{
return (left && right) ? std::wcscmp( left, right ) == 0 : (left == right);
@@ -406,6 +438,31 @@ is_defined_impl( const_string symbol_name, const_string symbol_value )
//____________________________________________________________________________//
+// ************************************************************************** //
+// ************** context_frame ************** //
+// ************************************************************************** //
+
+context_frame::context_frame( ::boost::unit_test::lazy_ostream const& context_descr )
+: m_frame_id( unit_test::framework::add_context( context_descr, true ) )
+{
+}
+
+//____________________________________________________________________________//
+
+context_frame::~context_frame()
+{
+ unit_test::framework::clear_context( m_frame_id );
+}
+
+//____________________________________________________________________________//
+
+context_frame::operator bool()
+{
+ return true;
+}
+
+//____________________________________________________________________________//
+
} // namespace tt_detail
// ************************************************************************** //
@@ -429,7 +486,7 @@ struct output_test_stream::Impl
return res;
}
- void check_and_fill( predicate_result& res )
+ void check_and_fill( assertion_result& res )
{
if( !res.p_predicate_value )
res.message() << "Output content: \"" << m_synced_string << '\"';
@@ -448,9 +505,8 @@ output_test_stream::output_test_stream( const_string pattern_file_name, bool mat
m_pimpl->m_pattern.open( pattern_file_name.begin(), m );
- BOOST_WARN_MESSAGE( m_pimpl->m_pattern.is_open(),
- "Can't open pattern file " << pattern_file_name
- << " for " << (match_or_save ? "reading" : "writing") );
+ if( !m_pimpl->m_pattern.is_open() )
+ BOOST_TEST_MESSAGE( "Can't open pattern file " << pattern_file_name << " for " << (match_or_save ? "reading" : "writing") );
}
m_pimpl->m_match_or_save = match_or_save;
@@ -466,12 +522,12 @@ output_test_stream::~output_test_stream()
//____________________________________________________________________________//
-predicate_result
+assertion_result
output_test_stream::is_empty( bool flush_stream )
{
sync();
- result_type res( m_pimpl->m_synced_string.empty() );
+ assertion_result res( m_pimpl->m_synced_string.empty() );
m_pimpl->check_and_fill( res );
@@ -483,12 +539,12 @@ output_test_stream::is_empty( bool flush_stream )
//____________________________________________________________________________//
-predicate_result
+assertion_result
output_test_stream::check_length( std::size_t length_, bool flush_stream )
{
sync();
- result_type res( m_pimpl->m_synced_string.length() == length_ );
+ assertion_result res( m_pimpl->m_synced_string.length() == length_ );
m_pimpl->check_and_fill( res );
@@ -500,12 +556,12 @@ output_test_stream::check_length( std::size_t length_, bool flush_stream )
//____________________________________________________________________________//
-predicate_result
+assertion_result
output_test_stream::is_equal( const_string arg, bool flush_stream )
{
sync();
- result_type res( const_string( m_pimpl->m_synced_string ) == arg );
+ assertion_result res( const_string( m_pimpl->m_synced_string ) == arg );
m_pimpl->check_and_fill( res );
@@ -517,12 +573,12 @@ output_test_stream::is_equal( const_string arg, bool flush_stream )
//____________________________________________________________________________//
-predicate_result
+assertion_result
output_test_stream::match_pattern( bool flush_stream )
{
sync();
- result_type result( true );
+ assertion_result result( true );
if( !m_pimpl->m_pattern.is_open() ) {
result = false;
@@ -548,18 +604,18 @@ output_test_stream::match_pattern( bool flush_stream )
std::string::size_type counter = suffix_size;
while( --counter ) {
- char c = m_pimpl->get_char();
+ char c2 = m_pimpl->get_char();
if( m_pimpl->m_pattern.fail() || m_pimpl->m_pattern.eof() )
break;
- result.message() << c;
+ result.message() << c2;
}
result.message() << "...";
// skip rest of the bytes. May help for further matching
- m_pimpl->m_pattern.ignore(
+ m_pimpl->m_pattern.ignore(
static_cast<std::streamsize>( m_pimpl->m_synced_string.length() - i - suffix_size) );
break;
}
@@ -618,11 +674,8 @@ output_test_stream::sync()
//____________________________________________________________________________//
} // namespace test_tools
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TEST_TOOLS_IPP_012205GER
diff --git a/boost/test/impl/test_tree.ipp b/boost/test/impl/test_tree.ipp
new file mode 100644
index 0000000000..712cb9ee42
--- /dev/null
+++ b/boost/test/impl/test_tree.ipp
@@ -0,0 +1,459 @@
+// (C) Copyright Gennadiy Rozental 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/test for the library home page.
+//
+/// @file
+/// Provides core implementation for Unit Test Framework.
+/// Extensions can be provided in separate files
+// ***************************************************************************
+
+#ifndef BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
+#define BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
+
+// Boost.Test
+#include <boost/detail/workaround.hpp>
+
+#include <boost/test/framework.hpp>
+#include <boost/test/results_collector.hpp>
+
+#include <boost/test/tree/test_unit.hpp>
+#include <boost/test/tree/visitor.hpp>
+#include <boost/test/tree/traverse.hpp>
+#include <boost/test/tree/auto_registration.hpp>
+#include <boost/test/tree/global_fixture.hpp>
+
+#include <boost/test/utils/foreach.hpp>
+#include <boost/test/utils/basic_cstring/io.hpp>
+
+#include <boost/test/unit_test_parameters.hpp>
+
+// Boost
+#include <boost/timer.hpp>
+
+// STL
+#include <algorithm>
+#include <vector>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, < 0x600) && BOOST_WORKAROUND(_STLPORT_VERSION, <= 0x450)
+ using std::rand; // rand is in std and random_shuffle is in _STL
+#endif
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+
+// ************************************************************************** //
+// ************** test_unit ************** //
+// ************************************************************************** //
+
+test_unit::test_unit( const_string name, const_string file_name, std::size_t line_num, test_unit_type t )
+: p_type( t )
+, p_type_name( t == TUT_CASE ? "case" : "suite" )
+, p_file_name( file_name )
+, p_line_num( line_num )
+, p_id( INV_TEST_UNIT_ID )
+, p_parent_id( INV_TEST_UNIT_ID )
+, p_name( std::string( name.begin(), name.size() ) )
+, p_timeout( 0 )
+, p_expected_failures( 0 )
+, p_default_status( RS_INHERIT )
+, p_run_status( RS_INVALID )
+, p_sibling_rank(0)
+{
+}
+
+//____________________________________________________________________________//
+
+test_unit::test_unit( const_string module_name )
+: p_type( TUT_SUITE )
+, p_type_name( "module" )
+, p_line_num( 0 )
+, p_id( INV_TEST_UNIT_ID )
+, p_parent_id( INV_TEST_UNIT_ID )
+, p_name( std::string( module_name.begin(), module_name.size() ) )
+, p_timeout( 0 )
+, p_expected_failures( 0 )
+, p_default_status( RS_INHERIT )
+, p_run_status( RS_INVALID )
+, p_sibling_rank(0)
+{
+}
+
+//____________________________________________________________________________//
+
+test_unit::~test_unit()
+{
+ framework::deregister_test_unit( this );
+}
+
+//____________________________________________________________________________//
+
+void
+test_unit::depends_on( test_unit* tu )
+{
+ BOOST_TEST_SETUP_ASSERT( p_id != framework::master_test_suite().p_id,
+ "Can't add dependency to the master test suite" );
+
+ p_dependencies.value.push_back( tu->p_id );
+}
+
+//____________________________________________________________________________//
+
+void
+test_unit::add_precondition( precondition_t const& pc )
+{
+ p_preconditions.value.push_back( pc );
+}
+
+//____________________________________________________________________________//
+
+test_tools::assertion_result
+test_unit::check_preconditions() const
+{
+ BOOST_TEST_FOREACH( test_unit_id, dep_id, p_dependencies.get() ) {
+ test_unit const& dep = framework::get( dep_id, TUT_ANY );
+
+ if( !dep.is_enabled() ) {
+ test_tools::assertion_result res(false);
+ res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" is disabled";
+ return res;
+ }
+
+ test_results const& test_rslt = unit_test::results_collector.results( dep_id );
+ if( !test_rslt.passed() ) {
+ test_tools::assertion_result res(false);
+ res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" has failed";
+ return res;
+ }
+
+ if( test_rslt.p_test_cases_skipped > 0 ) {
+ test_tools::assertion_result res(false);
+ res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" has skipped test cases";
+ return res;
+ }
+ }
+
+ BOOST_TEST_FOREACH( precondition_t, precondition, p_preconditions.get() ) {
+ test_tools::assertion_result res = precondition( p_id );
+ if( !res )
+ return res;
+ }
+
+ return true;
+}
+
+//____________________________________________________________________________//
+
+void
+test_unit::increase_exp_fail( counter_t num )
+{
+ p_expected_failures.value += num;
+
+ if( p_parent_id != INV_TEST_UNIT_ID )
+ framework::get<test_suite>( p_parent_id ).increase_exp_fail( num );
+}
+
+//____________________________________________________________________________//
+
+std::string
+test_unit::full_name() const
+{
+ if( p_parent_id == INV_TEST_UNIT_ID || p_parent_id == framework::master_test_suite().p_id )
+ return p_name;
+
+ std::string res = framework::get<test_suite>( p_parent_id ).full_name();
+ res.append("/");
+
+ res.append( p_name );
+
+ return res;
+}
+
+//____________________________________________________________________________//
+
+void
+test_unit::add_label( const_string l )
+{
+ p_labels.value.push_back( std::string() + l );
+}
+
+//____________________________________________________________________________//
+
+bool
+test_unit::has_label( const_string l ) const
+{
+ return std::find( p_labels->begin(), p_labels->end(), l ) != p_labels->end();
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** test_case ************** //
+// ************************************************************************** //
+
+test_case::test_case( const_string name, boost::function<void ()> const& test_func )
+: test_unit( name, "", 0, static_cast<test_unit_type>(type) )
+, p_test_func( test_func )
+{
+ framework::register_test_unit( this );
+}
+
+//____________________________________________________________________________//
+
+test_case::test_case( const_string name, const_string file_name, std::size_t line_num, boost::function<void ()> const& test_func )
+: test_unit( name, file_name, line_num, static_cast<test_unit_type>(type) )
+, p_test_func( test_func )
+{
+ framework::register_test_unit( this );
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** test_suite ************** //
+// ************************************************************************** //
+
+//____________________________________________________________________________//
+
+test_suite::test_suite( const_string name, const_string file_name, std::size_t line_num )
+: test_unit( name, file_name, line_num, static_cast<test_unit_type>(type) )
+{
+ framework::register_test_unit( this );
+}
+
+//____________________________________________________________________________//
+
+test_suite::test_suite( const_string module_name )
+: test_unit( module_name )
+{
+ framework::register_test_unit( this );
+}
+
+//____________________________________________________________________________//
+
+void
+test_suite::add( test_unit* tu, counter_t expected_failures, unsigned timeout )
+{
+ tu->p_timeout.value = timeout;
+
+ m_children.push_back( tu->p_id );
+ tu->p_parent_id.value = p_id;
+
+ if( tu->p_expected_failures != 0 )
+ increase_exp_fail( tu->p_expected_failures );
+
+ if( expected_failures )
+ tu->increase_exp_fail( expected_failures );
+}
+
+//____________________________________________________________________________//
+
+void
+test_suite::add( test_unit_generator const& gen, unsigned timeout )
+{
+ test_unit* tu;
+ while((tu = gen.next()) != 0)
+ add( tu, 0, timeout );
+}
+
+//____________________________________________________________________________//
+
+void
+test_suite::add( test_unit_generator const& gen, decorator::collector& decorators )
+{
+ test_unit* tu;
+ while((tu = gen.next()) != 0) {
+ decorators.store_in( *tu );
+ add( tu, 0 );
+ }
+
+ decorators.reset();
+}
+
+//____________________________________________________________________________//
+
+void
+test_suite::remove( test_unit_id id )
+{
+ test_unit_id_list::iterator it = std::find( m_children.begin(), m_children.end(), id );
+
+ if( it != m_children.end() )
+ m_children.erase( it );
+}
+
+//____________________________________________________________________________//
+
+test_unit_id
+test_suite::get( const_string tu_name ) const
+{
+ BOOST_TEST_FOREACH( test_unit_id, id, m_children ) {
+ if( tu_name == framework::get( id, ut_detail::test_id_2_unit_type( id ) ).p_name.get() )
+ return id;
+ }
+
+ return INV_TEST_UNIT_ID;
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** master_test_suite ************** //
+// ************************************************************************** //
+
+master_test_suite_t::master_test_suite_t()
+: test_suite( "Master Test Suite" )
+, argc( 0 )
+, argv( 0 )
+{
+ p_default_status.value = RS_ENABLED;
+}
+
+// ************************************************************************** //
+// ************** traverse_test_tree ************** //
+// ************************************************************************** //
+
+void
+traverse_test_tree( test_case const& tc, test_tree_visitor& V, bool ignore_status )
+{
+ if( tc.is_enabled() || ignore_status )
+ V.visit( tc );
+}
+
+//____________________________________________________________________________//
+
+void
+traverse_test_tree( test_suite const& suite, test_tree_visitor& V, bool ignore_status )
+{
+ // skip disabled test suite unless we asked to ignore this condition
+ if( !ignore_status && !suite.is_enabled() )
+ return;
+
+ // Invoke test_suite_start callback
+ if( !V.test_suite_start( suite ) )
+ return;
+
+ // Recurse into children
+ std::size_t total_children = suite.m_children.size();
+ for( std::size_t i=0; i < total_children; ) {
+ // this statement can remove the test unit from this list
+ traverse_test_tree( suite.m_children[i], V, ignore_status );
+ if( total_children > suite.m_children.size() )
+ total_children = suite.m_children.size();
+ else
+ ++i;
+ }
+
+ // Invoke test_suite_finish callback
+ V.test_suite_finish( suite );
+}
+
+//____________________________________________________________________________//
+
+void
+traverse_test_tree( test_unit_id id, test_tree_visitor& V, bool ignore_status )
+{
+ if( ut_detail::test_id_2_unit_type( id ) == TUT_CASE )
+ traverse_test_tree( framework::get<test_case>( id ), V, ignore_status );
+ else
+ traverse_test_tree( framework::get<test_suite>( id ), V, ignore_status );
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** object generators ************** //
+// ************************************************************************** //
+
+namespace ut_detail {
+
+std::string
+normalize_test_case_name( const_string name )
+{
+ std::string norm_name( name.begin(), name.size() );
+
+ if( name[0] == '&' )
+ norm_name = norm_name.substr( 1 );
+
+ std::replace(norm_name.begin(), norm_name.end(), ' ', '_');
+
+ return norm_name;
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** auto_test_unit_registrar ************** //
+// ************************************************************************** //
+
+auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, decorator::collector& decorators, counter_t exp_fail )
+{
+ framework::current_auto_test_suite().add( tc, exp_fail );
+
+ decorators.store_in( *tc );
+ decorators.reset();
+}
+
+//____________________________________________________________________________//
+
+auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name, const_string ts_file, std::size_t ts_line, decorator::collector& decorators )
+{
+ test_unit_id id = framework::current_auto_test_suite().get( ts_name );
+
+ test_suite* ts;
+
+ if( id != INV_TEST_UNIT_ID ) {
+ ts = &framework::get<test_suite>( id );
+ BOOST_ASSERT( ts->p_parent_id == framework::current_auto_test_suite().p_id );
+ }
+ else {
+ ts = new test_suite( ts_name, ts_file, ts_line );
+ framework::current_auto_test_suite().add( ts );
+ }
+
+ decorators.store_in( *ts );
+ decorators.reset();
+
+ framework::current_auto_test_suite( ts );
+}
+
+//____________________________________________________________________________//
+
+auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector& decorators )
+{
+ framework::current_auto_test_suite().add( tc_gen, decorators );
+}
+
+//____________________________________________________________________________//
+
+auto_test_unit_registrar::auto_test_unit_registrar( int )
+{
+ framework::current_auto_test_suite( 0, false );
+}
+
+//____________________________________________________________________________//
+
+} // namespace ut_detail
+
+// ************************************************************************** //
+// ************** global_fixture ************** //
+// ************************************************************************** //
+
+global_fixture::global_fixture()
+{
+ framework::register_observer( *this );
+}
+
+//____________________________________________________________________________//
+
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
diff --git a/boost/test/impl/unit_test_log.ipp b/boost/test/impl/unit_test_log.ipp
index 7cb4f4b4a8..f202f5027d 100644
--- a/boost/test/impl/unit_test_log.ipp
+++ b/boost/test/impl/unit_test_log.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 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)
@@ -18,10 +18,10 @@
// Boost.Test
#include <boost/test/unit_test_log.hpp>
#include <boost/test/unit_test_log_formatter.hpp>
-#include <boost/test/unit_test_suite_impl.hpp>
#include <boost/test/execution_monitor.hpp>
+#include <boost/test/framework.hpp>
-#include <boost/test/detail/unit_test_parameters.hpp>
+#include <boost/test/unit_test_parameters.hpp>
#include <boost/test/utils/basic_cstring/compare.hpp>
@@ -38,7 +38,6 @@ typedef ::boost::io::ios_base_all_saver io_saver_type;
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
// ************************************************************************** //
@@ -57,7 +56,7 @@ entry_value_collector::operator<<( lazy_ostream const& v ) const
//____________________________________________________________________________//
-entry_value_collector const&
+entry_value_collector const&
entry_value_collector::operator<<( const_string v ) const
{
unit_test_log << v;
@@ -194,7 +193,7 @@ unit_test_log_t::test_unit_finish( test_unit const& tu, unsigned long elapsed )
//____________________________________________________________________________//
void
-unit_test_log_t::test_unit_skipped( test_unit const& tu )
+unit_test_log_t::test_unit_skipped( test_unit const& tu, const_string reason )
{
if( s_log_impl().m_threshold_level > log_test_units )
return;
@@ -202,23 +201,7 @@ unit_test_log_t::test_unit_skipped( test_unit const& tu )
if( s_log_impl().m_entry_in_progress )
*this << log::end();
- s_log_impl().m_log_formatter->test_unit_skipped( s_log_impl().stream(), tu );
-}
-
-//____________________________________________________________________________//
-
-void
-unit_test_log_t::test_unit_aborted( test_unit const& )
-{
- // do nothing
-}
-
-//____________________________________________________________________________//
-
-void
-unit_test_log_t::assertion_result( bool )
-{
- // do nothing
+ s_log_impl().m_log_formatter->test_unit_skipped( s_log_impl().stream(), tu, reason );
}
//____________________________________________________________________________//
@@ -235,8 +218,14 @@ unit_test_log_t::exception_caught( execution_exception const& ex )
if( s_log_impl().m_entry_in_progress )
*this << log::end();
- s_log_impl().m_log_formatter->log_exception( s_log_impl().stream(), s_log_impl().m_checkpoint_data, ex );
+ s_log_impl().m_log_formatter->log_exception_start( s_log_impl().stream(), s_log_impl().m_checkpoint_data, ex );
+
+ log_entry_context( l );
+
+ s_log_impl().m_log_formatter->log_exception_finish( s_log_impl().stream() );
}
+
+ clear_entry_context();
}
//____________________________________________________________________________//
@@ -254,7 +243,7 @@ set_unix_slash( char in )
{
return in == '\\' ? '/' : in;
}
-
+
unit_test_log_t&
unit_test_log_t::operator<<( log::begin const& b )
{
@@ -282,10 +271,15 @@ unit_test_log_t::operator<<( log::begin const& b )
unit_test_log_t&
unit_test_log_t::operator<<( log::end const& )
{
- if( s_log_impl().m_entry_in_progress )
+ if( s_log_impl().m_entry_in_progress ) {
+ log_entry_context( s_log_impl().m_entry_data.m_level );
+
s_log_impl().m_log_formatter->log_entry_finish( s_log_impl().stream() );
- s_log_impl().m_entry_in_progress = false;
+ s_log_impl().m_entry_in_progress = false;
+ }
+
+ clear_entry_context();
return *this;
}
@@ -315,7 +309,7 @@ unit_test_log_t::operator()( log_level l )
bool
unit_test_log_t::log_entry_start()
{
- if( s_log_impl().m_entry_in_progress )
+ if( s_log_impl().m_entry_in_progress )
return true;
switch( s_log_impl().m_entry_data.m_level ) {
@@ -377,6 +371,33 @@ unit_test_log_t::operator<<( lazy_ostream const& value )
//____________________________________________________________________________//
void
+unit_test_log_t::log_entry_context( log_level l )
+{
+ framework::context_generator const& context = framework::get_context();
+ if( context.is_empty() )
+ return;
+
+ const_string frame;
+
+ s_log_impl().m_log_formatter->entry_context_start( s_log_impl().stream(), l );
+
+ while( !(frame=context.next()).is_empty() )
+ s_log_impl().m_log_formatter->log_entry_context( s_log_impl().stream(), frame );
+
+ s_log_impl().m_log_formatter->entry_context_finish( s_log_impl().stream() );
+}
+
+//____________________________________________________________________________//
+
+void
+unit_test_log_t::clear_entry_context()
+{
+ framework::clear_context();
+}
+
+//____________________________________________________________________________//
+
+void
unit_test_log_t::set_stream( std::ostream& str )
{
if( s_log_impl().m_entry_in_progress )
@@ -405,10 +426,15 @@ unit_test_log_t::set_format( output_format log_format )
if( s_log_impl().m_entry_in_progress )
return;
- if( log_format == CLF )
+ switch( log_format ) {
+ default:
+ case OF_CLF:
set_formatter( new output::compiler_log_formatter );
- else
+ break;
+ case OF_XML:
set_formatter( new output::xml_log_formatter );
+ break;
+ }
}
//____________________________________________________________________________//
@@ -434,11 +460,8 @@ unit_test_log_formatter::log_entry_value( std::ostream& ostr, lazy_ostream const
//____________________________________________________________________________//
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_LOG_IPP_012205GER
diff --git a/boost/test/impl/unit_test_main.ipp b/boost/test/impl/unit_test_main.ipp
index adedf35180..327e14de30 100644
--- a/boost/test/impl/unit_test_main.ipp
+++ b/boost/test/impl/unit_test_main.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-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)
@@ -18,154 +18,164 @@
// Boost.Test
#include <boost/test/framework.hpp>
#include <boost/test/results_collector.hpp>
-#include <boost/test/unit_test_suite_impl.hpp>
#include <boost/test/results_reporter.hpp>
-#include <boost/test/detail/unit_test_parameters.hpp>
+#include <boost/test/tree/visitor.hpp>
+#include <boost/test/tree/test_unit.hpp>
+#include <boost/test/tree/traverse.hpp>
-#if !defined(__BORLANDC__) && !BOOST_WORKAROUND( BOOST_MSVC, < 1300 ) && !BOOST_WORKAROUND( __SUNPRO_CC, < 0x5100 )
-#define BOOST_TEST_SUPPORT_RUN_BY_NAME
-#include <boost/test/utils/iterator/token_iterator.hpp>
-#endif
+#include <boost/test/unit_test_parameters.hpp>
+
+#include <boost/test/utils/foreach.hpp>
+#include <boost/test/utils/basic_cstring/io.hpp>
// Boost
#include <boost/cstdlib.hpp>
-#include <boost/bind.hpp>
// STL
+#include <cstdio>
#include <stdexcept>
#include <iostream>
+#include <iomanip>
+#include <set>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
+namespace ut_detail {
+
// ************************************************************************** //
-// ************** test_case_filter ************** //
+// ************** hrf_content_reporter ************** //
// ************************************************************************** //
-class test_case_filter : public test_tree_visitor {
-public:
- struct single_filter {
- single_filter( const_string in )
- {
- if( in == "*" )
- m_kind = SFK_ALL;
- else if( first_char( in ) == '*' && last_char( in ) == '*' ) {
- m_kind = SFK_SUBSTR;
- m_value = in.substr( 1, in.size()-1 );
- }
- else if( first_char( in ) == '*' ) {
- m_kind = SFK_TRAILING;
- m_value = in.substr( 1 );
- }
- else if( last_char( in ) == '*' ) {
- m_kind = SFK_LEADING;
- m_value = in.substr( 0, in.size()-1 );
- }
- else {
- m_kind = SFK_MATCH;
- m_value = in;
- }
- };
+struct hrf_content_reporter : test_tree_visitor {
+ explicit hrf_content_reporter( std::ostream& os ) : m_os( os ), m_indent( -4 ) {} // skip master test suite
- bool pass( test_unit const& tu ) const
- {
- const_string name( tu.p_name );
-
- switch( m_kind ) {
- default:
- case SFK_ALL:
- return true;
+private:
+ void report_test_unit( test_unit const& tu )
+ {
+ m_os << std::setw( m_indent ) << "" << tu.p_name;
+ m_os << (tu.p_default_status == test_unit::RS_ENABLED ? "*" : " ");
+ //m_os << '[' << tu.p_sibling_rank << ']';
+ if( !tu.p_description->empty() )
+ m_os << ": " << tu.p_description;
- case SFK_LEADING:
- return name.substr( 0, m_value.size() ) == m_value;
+ m_os << "\n";
+ }
+ virtual void visit( test_case const& tc ) { report_test_unit( tc ); }
+ virtual bool test_suite_start( test_suite const& ts )
+ {
+ if( m_indent >= 0 )
+ report_test_unit( ts );
+ m_indent += 4;
+ return true;
+ }
+ virtual void test_suite_finish( test_suite const& )
+ {
+ m_indent -= 4;
+ }
- case SFK_TRAILING:
- return name.size() >= m_value.size() && name.substr( name.size() - m_value.size() ) == m_value;
+ // Data members
+ std::ostream& m_os;
+ int m_indent;
+};
- case SFK_SUBSTR:
- return name.find( m_value ) != const_string::npos;
+// ************************************************************************** //
+// ************** dot_content_reporter ************** //
+// ************************************************************************** //
- case SFK_MATCH:
- return m_value == tu.p_name.get();
- }
- }
- enum kind { SFK_ALL, SFK_LEADING, SFK_TRAILING, SFK_SUBSTR, SFK_MATCH };
-
- kind m_kind;
- const_string m_value;
- };
- // Constructor
-#ifndef BOOST_TEST_SUPPORT_RUN_BY_NAME
- explicit test_case_filter( const_string ) : m_depth( 0 ) {}
-#else
- explicit test_case_filter( const_string tc_to_run )
- : m_depth( 0 )
+struct dot_content_reporter : test_tree_visitor {
+ explicit dot_content_reporter( std::ostream& os ) : m_os( os ) {}
+
+private:
+ void report_test_unit( test_unit const& tu )
{
- string_token_iterator tit( tc_to_run, (dropped_delimeters = "/", kept_delimeters = dt_none) );
+ bool master_ts = tu.p_parent_id == INV_TEST_UNIT_ID;
- while( tit != string_token_iterator() ) {
- m_filters.push_back(
- std::vector<single_filter>( string_token_iterator( *tit, (dropped_delimeters = ",", kept_delimeters = dt_none) ),
- string_token_iterator() ) );
+ m_os << "tu" << tu.p_id;
- ++tit;
- }
- }
-#endif
-
- void filter_unit( test_unit const& tu )
- {
- if( (++m_depth - 1) > m_filters.size() ) {
- tu.p_enabled.value = true;
- return;
- }
+ m_os << (master_ts ? "[shape=ellipse,peripheries=2" : "[shape=Mrecord" );
- if( m_depth == 1 )
- return;
+ m_os << ",fontname=Helvetica";
- std::vector<single_filter> const& filters = m_filters[m_depth-2];
+ m_os << (tu.is_enabled() ? ",color=green" : ",color=yellow");
- tu.p_enabled.value =
- std::find_if( filters.begin(), filters.end(), bind( &single_filter::pass, _1, boost::ref(tu) ) ) != filters.end();
- }
+ if( master_ts )
+ m_os << ",label=\"" << tu.p_name << "\"];\n";
+ else {
+ m_os << ",label=\"" << tu.p_name << "|" << tu.p_file_name << "(" << tu.p_line_num << ")";
+ if( tu.p_timeout > 0 )
+ m_os << "|timeout=" << tu.p_timeout;
+ if( tu.p_expected_failures != 0 )
+ m_os << "|expected failures=" << tu.p_expected_failures;
+ if( !tu.p_labels->empty() ) {
+ m_os << "|labels:";
- // test tree visitor interface
- virtual void visit( test_case const& tc )
- {
- if( m_depth < m_filters.size() ) {
- tc.p_enabled.value = false;
- return;
+ BOOST_TEST_FOREACH( std::string const&, l, tu.p_labels.get() )
+ m_os << " @" << l;
+ }
+ m_os << "\"];\n";
}
- filter_unit( tc );
+ if( !master_ts )
+ m_os << "tu" << tu.p_parent_id << " -> " << "tu" << tu.p_id << ";\n";
- --m_depth;
- }
+ BOOST_TEST_FOREACH( test_unit_id, dep_id, tu.p_dependencies.get() ) {
+ test_unit const& dep = framework::get( dep_id, TUT_ANY );
- virtual bool test_suite_start( test_suite const& ts )
+ m_os << "tu" << tu.p_id << " -> " << "tu" << dep.p_id << "[color=red,style=dotted,constraint=false];\n";
+ }
+
+ }
+ virtual void visit( test_case const& tc )
{
- filter_unit( ts );
+ report_test_unit( tc );
+ }
+ virtual bool test_suite_start( test_suite const& ts )
+ {
+ if( ts.p_parent_id == INV_TEST_UNIT_ID )
+ m_os << "digraph G {rankdir=LR;\n";
- if( !ts.p_enabled )
- --m_depth;
+ report_test_unit( ts );
- return ts.p_enabled;
+ m_os << "{\n";
+
+ return true;
+ }
+ virtual void test_suite_finish( test_suite const& ts )
+ {
+ m_os << "}\n";
+ if( ts.p_parent_id == INV_TEST_UNIT_ID )
+ m_os << "}\n";
}
- virtual void test_suite_finish( test_suite const& ) { --m_depth; }
+ std::ostream& m_os;
+};
+
+// ************************************************************************** //
+// ************** labels_collector ************** //
+// ************************************************************************** //
+
+struct labels_collector : test_tree_visitor {
+ std::set<std::string> const& labels() const { return m_labels; }
private:
+ virtual bool visit( test_unit const& tu )
+ {
+ m_labels.insert( tu.p_labels->begin(), tu.p_labels->end() );
+ return true;
+ }
+
// Data members
- std::vector<std::vector<single_filter> > m_filters;
- unsigned m_depth;
+ std::set<std::string> m_labels;
};
+} // namespace ut_detail
+
// ************************************************************************** //
// ************** unit_test_main ************** //
// ************************************************************************** //
@@ -173,45 +183,81 @@ private:
int BOOST_TEST_DECL
unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
{
- try {
+ int result_code = 0;
+
+ BOOST_TEST_IMPL_TRY {
framework::init( init_func, argc, argv );
- if( !runtime_config::test_to_run().is_empty() ) {
- test_case_filter filter( runtime_config::test_to_run() );
+ if( runtime_config::wait_for_debugger() ) {
+ results_reporter::get_stream() << "Press any key to continue..." << std::endl;
+
+ std::getchar();
+ results_reporter::get_stream() << "Continuing..." << std::endl;
+ }
+
+ framework::finalize_setup_phase();
+
+ if( runtime_config::list_content() != unit_test::OF_INVALID ) {
+ if( runtime_config::list_content() == unit_test::OF_DOT ) {
+ ut_detail::dot_content_reporter reporter( results_reporter::get_stream() );
+
+ traverse_test_tree( framework::master_test_suite().p_id, reporter, true );
+ }
+ else {
+ ut_detail::hrf_content_reporter reporter( results_reporter::get_stream() );
+
+ traverse_test_tree( framework::master_test_suite().p_id, reporter, true );
+ }
- traverse_test_tree( framework::master_test_suite().p_id, filter );
+ return boost::exit_success;
+ }
+
+ if( runtime_config::list_labels() ) {
+ ut_detail::labels_collector collector;
+
+ traverse_test_tree( framework::master_test_suite().p_id, collector, true );
+
+ results_reporter::get_stream() << "Available labels:\n ";
+ std::copy( collector.labels().begin(), collector.labels().end(),
+ std::ostream_iterator<std::string>( results_reporter::get_stream(), "\n " ) );
+ results_reporter::get_stream() << "\n";
+
+ return boost::exit_success;
}
framework::run();
results_reporter::make_report();
- return runtime_config::no_result_code()
- ? boost::exit_success
- : results_collector.results( framework::master_test_suite().p_id ).result_code();
+ result_code = runtime_config::no_result_code()
+ ? boost::exit_success
+ : results_collector.results( framework::master_test_suite().p_id ).result_code();
}
- catch( framework::nothing_to_test const& ) {
- return boost::exit_success;
+ BOOST_TEST_IMPL_CATCH0( framework::nothing_to_test ) {
+ result_code = boost::exit_success;
}
- catch( framework::internal_error const& ex ) {
+ BOOST_TEST_IMPL_CATCH( framework::internal_error, ex ) {
results_reporter::get_stream() << "Boost.Test framework internal error: " << ex.what() << std::endl;
-
- return boost::exit_exception_failure;
+
+ result_code = boost::exit_exception_failure;
}
- catch( framework::setup_error const& ex ) {
+ BOOST_TEST_IMPL_CATCH( framework::setup_error, ex ) {
results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl;
-
- return boost::exit_exception_failure;
+
+ result_code = boost::exit_exception_failure;
}
- catch( ... ) {
+ BOOST_TEST_IMPL_CATCHALL() {
results_reporter::get_stream() << "Boost.Test framework internal error: unknown reason" << std::endl;
-
- return boost::exit_exception_failure;
+
+ result_code = boost::exit_exception_failure;
}
+
+ framework::shutdown();
+
+ return result_code;
}
} // namespace unit_test
-
} // namespace boost
#if !defined(BOOST_TEST_DYN_LINK) && !defined(BOOST_TEST_NO_MAIN)
diff --git a/boost/test/impl/unit_test_monitor.ipp b/boost/test/impl/unit_test_monitor.ipp
index dc912f544e..8c931f203f 100644
--- a/boost/test/impl/unit_test_monitor.ipp
+++ b/boost/test/impl/unit_test_monitor.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 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)
@@ -18,57 +18,34 @@
// Boost.Test
#include <boost/test/unit_test_monitor.hpp>
-#include <boost/test/unit_test_suite_impl.hpp>
-#include <boost/test/test_tools.hpp>
#include <boost/test/framework.hpp>
-
-#include <boost/test/detail/unit_test_parameters.hpp>
+#include <boost/test/tree/test_unit.hpp>
+#include <boost/test/unit_test_parameters.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
-namespace {
-
-template<typename F>
-struct zero_return_wrapper_t {
- explicit zero_return_wrapper_t( F const& f ) : m_f( f ) {}
-
- int operator()() { m_f(); return 0; }
-
- F const& m_f;
-};
-
-template<typename F>
-zero_return_wrapper_t<F>
-zero_return_wrapper( F const& f )
-{
- return zero_return_wrapper_t<F>( f );
-}
-
-}
-
// ************************************************************************** //
// ************** unit_test_monitor ************** //
// ************************************************************************** //
unit_test_monitor_t::error_level
-unit_test_monitor_t::execute_and_translate( test_case const& tc )
+unit_test_monitor_t::execute_and_translate( boost::function<void ()> const& func, unsigned timeout )
{
- try {
+ BOOST_TEST_IMPL_TRY {
p_catch_system_errors.value = runtime_config::catch_sys_errors();
- p_timeout.value = tc.p_timeout.get();
+ p_timeout.value = timeout;
p_auto_start_dbg.value = runtime_config::auto_start_dbg();
p_use_alt_stack.value = runtime_config::use_alt_stack();
p_detect_fp_exceptions.value = runtime_config::detect_fp_exceptions();
- execute( callback0<int>( zero_return_wrapper( tc.test_func() ) ) );
+ vexecute( func );
}
- catch( execution_exception const& ex ) {
+ BOOST_TEST_IMPL_CATCH( execution_exception, ex ) {
framework::exception_caught( ex );
framework::test_unit_aborted( framework::current_test_case() );
@@ -91,11 +68,8 @@ unit_test_monitor_t::execute_and_translate( test_case const& tc )
//____________________________________________________________________________//
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_MONITOR_IPP_012205GER
diff --git a/boost/test/impl/unit_test_parameters.ipp b/boost/test/impl/unit_test_parameters.ipp
index f220792b34..2ffa495e67 100644
--- a/boost/test/impl/unit_test_parameters.ipp
+++ b/boost/test/impl/unit_test_parameters.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-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)
@@ -19,7 +19,7 @@
#define BOOST_TEST_UNIT_TEST_PARAMETERS_IPP_012205GER
// Boost.Test
-#include <boost/test/detail/unit_test_parameters.hpp>
+#include <boost/test/unit_test_parameters.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/basic_cstring/compare.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
@@ -27,6 +27,8 @@
#include <boost/test/debug.hpp>
#include <boost/test/framework.hpp>
+#include <boost/test/detail/throw_exception.hpp>
+
// Boost.Runtime.Param
#include <boost/test/utils/runtime/cla/dual_name_parameter.hpp>
#include <boost/test/utils/runtime/cla/parser.hpp>
@@ -34,14 +36,12 @@
namespace rt = boost::runtime;
namespace cla = rt::cla;
-
#ifndef UNDER_CE
#include <boost/test/utils/runtime/env/variable.hpp>
namespace env = rt::env;
#endif
-
// Boost
#include <boost/config.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
@@ -63,7 +63,6 @@ namespace std { using ::getenv; using ::strncmp; using ::strcmp; }
# endif
namespace boost {
-
namespace unit_test {
// ************************************************************************** //
@@ -127,18 +126,19 @@ std::istream&
operator>>( std::istream& in, unit_test::output_format& of )
{
fixed_mapping<const_string,unit_test::output_format,case_ins_less<char const> > output_format_name (
- "HRF", unit_test::CLF,
- "CLF", unit_test::CLF,
- "XML", unit_test::XML,
+ "HRF", unit_test::OF_CLF,
+ "CLF", unit_test::OF_CLF,
+ "XML", unit_test::OF_XML,
+ "DOT", unit_test::OF_DOT,
- unit_test::INV_OF
+ unit_test::OF_INVALID
);
std::string val;
in >> val;
of = output_format_name[val];
- BOOST_TEST_SETUP_ASSERT( of != unit_test::INV_OF, "invalid output format " + val );
+ BOOST_TEST_SETUP_ASSERT( of != unit_test::OF_INVALID, "invalid output format " + val );
return in;
}
@@ -158,8 +158,11 @@ std::string AUTO_START_DBG = "auto_start_dbg";
std::string BREAK_EXEC_PATH = "break_exec_path";
std::string BUILD_INFO = "build_info";
std::string CATCH_SYS_ERRORS = "catch_system_errors";
+std::string COLOR_OUTPUT = "color_output";
std::string DETECT_FP_EXCEPT = "detect_fp_exceptions";
std::string DETECT_MEM_LEAKS = "detect_memory_leaks";
+std::string LIST_CONTENT = "list_content";
+std::string LIST_LABELS = "list_labels";
std::string LOG_FORMAT = "log_format";
std::string LOG_LEVEL = "log_level";
std::string LOG_SINK = "log_sink";
@@ -173,39 +176,55 @@ std::string TESTS_TO_RUN = "run_test";
std::string SAVE_TEST_PATTERN = "save_pattern";
std::string SHOW_PROGRESS = "show_progress";
std::string USE_ALT_STACK = "use_alt_stack";
+std::string WAIT_FOR_DEBUGGER = "wait_for_debugger";
+
+static const_string
+parameter_2_env_var( const_string param_name )
+{
+ typedef std::map<const_string,const_string> mtype;
+ static mtype s_mapping;
+
+ if( s_mapping.empty() ) {
+ s_mapping[AUTO_START_DBG] = "BOOST_TEST_AUTO_START_DBG";
+ s_mapping[BREAK_EXEC_PATH] = "BOOST_TEST_BREAK_EXEC_PATH";
+ s_mapping[BUILD_INFO] = "BOOST_TEST_BUILD_INFO";
+ s_mapping[CATCH_SYS_ERRORS] = "BOOST_TEST_CATCH_SYSTEM_ERRORS";
+ s_mapping[COLOR_OUTPUT] = "BOOST_TEST_COLOR_OUTPUT";
+ s_mapping[DETECT_FP_EXCEPT] = "BOOST_TEST_DETECT_FP_EXCEPTIONS";
+ s_mapping[DETECT_MEM_LEAKS] = "BOOST_TEST_DETECT_MEMORY_LEAK";
+ s_mapping[LIST_CONTENT] = "BOOST_TEST_LIST_CONTENT";
+ s_mapping[LIST_CONTENT] = "BOOST_TEST_LIST_LABELS";
+ s_mapping[LOG_FORMAT] = "BOOST_TEST_LOG_FORMAT";
+ s_mapping[LOG_LEVEL] = "BOOST_TEST_LOG_LEVEL";
+ s_mapping[LOG_SINK] = "BOOST_TEST_LOG_SINK";
+ s_mapping[OUTPUT_FORMAT] = "BOOST_TEST_OUTPUT_FORMAT";
+ s_mapping[RANDOM_SEED] = "BOOST_TEST_RANDOM";
+ s_mapping[REPORT_FORMAT] = "BOOST_TEST_REPORT_FORMAT";
+ s_mapping[REPORT_LEVEL] = "BOOST_TEST_REPORT_LEVEL";
+ s_mapping[REPORT_SINK] = "BOOST_TEST_REPORT_SINK";
+ s_mapping[RESULT_CODE] = "BOOST_TEST_RESULT_CODE";
+ s_mapping[TESTS_TO_RUN] = "BOOST_TESTS_TO_RUN";
+ s_mapping[SAVE_TEST_PATTERN] = "BOOST_TEST_SAVE_PATTERN";
+ s_mapping[SHOW_PROGRESS] = "BOOST_TEST_SHOW_PROGRESS";
+ s_mapping[USE_ALT_STACK] = "BOOST_TEST_USE_ALT_STACK";
+ s_mapping[WAIT_FOR_DEBUGGER] = "BOOST_TEST_WAIT_FOR_DEBUGGER";
+ }
-fixed_mapping<const_string,const_string> parameter_2_env_var(
- AUTO_START_DBG , "BOOST_TEST_AUTO_START_DBG",
- BREAK_EXEC_PATH , "BOOST_TEST_BREAK_EXEC_PATH",
- BUILD_INFO , "BOOST_TEST_BUILD_INFO",
- CATCH_SYS_ERRORS , "BOOST_TEST_CATCH_SYSTEM_ERRORS",
- DETECT_FP_EXCEPT , "BOOST_TEST_DETECT_FP_EXCEPTIONS",
- DETECT_MEM_LEAKS , "BOOST_TEST_DETECT_MEMORY_LEAK",
- LOG_FORMAT , "BOOST_TEST_LOG_FORMAT",
- LOG_LEVEL , "BOOST_TEST_LOG_LEVEL",
- LOG_SINK , "BOOST_TEST_LOG_SINK",
- OUTPUT_FORMAT , "BOOST_TEST_OUTPUT_FORMAT",
- RANDOM_SEED , "BOOST_TEST_RANDOM",
- REPORT_FORMAT , "BOOST_TEST_REPORT_FORMAT",
- REPORT_LEVEL , "BOOST_TEST_REPORT_LEVEL",
- REPORT_SINK , "BOOST_TEST_REPORT_SINK",
- RESULT_CODE , "BOOST_TEST_RESULT_CODE",
- TESTS_TO_RUN , "BOOST_TESTS_TO_RUN",
- SAVE_TEST_PATTERN , "BOOST_TEST_SAVE_PATTERN",
- SHOW_PROGRESS , "BOOST_TEST_SHOW_PROGRESS",
- USE_ALT_STACK , "BOOST_TEST_USE_ALT_STACK",
-
- ""
-);
+ mtype::const_iterator it = s_mapping.find( param_name );
+
+ return it == s_mapping.end() ? const_string() : it->second;
+}
//____________________________________________________________________________//
// storage for the CLAs
-cla::parser s_cla_parser;
-std::string s_empty;
+cla::parser s_cla_parser;
+std::string s_empty;
+
+output_format s_report_format;
+output_format s_log_format;
-output_format s_report_format;
-output_format s_log_format;
+std::list<std::string> s_test_to_run;
//____________________________________________________________________________//
@@ -229,7 +248,7 @@ retrieve_parameter( const_string parameter_name, cla::parser const& s_cla_parser
boost::optional<T> v;
#ifndef UNDER_CE
- env::get( parameter_2_env_var[parameter_name], v );
+ env::get( parameter_2_env_var(parameter_name), v );
#endif
if( v )
@@ -240,101 +259,127 @@ retrieve_parameter( const_string parameter_name, cla::parser const& s_cla_parser
//____________________________________________________________________________//
-} // local namespace
+void
+disable_use( cla::parameter const&, std::string const& )
+{
+ BOOST_TEST_SETUP_ASSERT( false, "parameter break_exec_path is disabled in this release" );
+}
+
+//____________________________________________________________________________//
+
+} // local namespace
void
init( int& argc, char** argv )
{
using namespace cla;
- try {
- s_cla_parser - cla::ignore_mismatch
- << cla::dual_name_parameter<bool>( AUTO_START_DBG + "|d" )
- - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
- cla::description = "Automatically starts debugger if system level error (signal) occurs")
- << cla::named_parameter<std::string>( BREAK_EXEC_PATH )
- - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,
- cla::description = "For the exception safety testing allows to break at specific execution path")
- << cla::dual_name_parameter<bool>( BUILD_INFO + "|i" )
- - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
- cla::description = "Shows library build information" )
- << cla::dual_name_parameter<bool>( CATCH_SYS_ERRORS + "|s" )
- - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
- cla::description = "Allows to switch between catching and ignoring system errors (signals)")
- << cla::named_parameter<bool>( DETECT_FP_EXCEPT )
- - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,
- cla::description = "Allows to switch between catching and ignoring floating point exceptions")
- << cla::named_parameter<long>( DETECT_MEM_LEAKS )
- - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,
- cla::description = "Allows to switch between catching and ignoring memory leaks")
- << cla::dual_name_parameter<unit_test::output_format>( LOG_FORMAT + "|f" )
- - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
- cla::description = "Specifies log format")
- << cla::dual_name_parameter<unit_test::log_level>( LOG_LEVEL + "|l" )
- - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
- cla::description = "Specifies log level")
- << cla::dual_name_parameter<std::string>( LOG_SINK + "|k" )
- - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
- cla::description = "Specifies log sink:stdout(default),stderr or file name")
- << cla::dual_name_parameter<unit_test::output_format>( OUTPUT_FORMAT + "|o" )
- - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
- cla::description = "Specifies output format (both log and report)")
- << cla::dual_name_parameter<int>( RANDOM_SEED + "|a" )
- - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,cla::optional_value,
- cla::description = "Allows to switch between sequential and random order of test units execution.\n"
- "Optionally allows to specify concrete seed for random number generator")
- << cla::dual_name_parameter<unit_test::output_format>( REPORT_FORMAT + "|m" )
- - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
- cla::description = "Specifies report format")
- << cla::dual_name_parameter<unit_test::report_level>(REPORT_LEVEL + "|r")
- - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
- cla::description = "Specifies report level")
- << cla::dual_name_parameter<std::string>( REPORT_SINK + "|e" )
- - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
- cla::description = "Specifies report sink:stderr(default),stdout or file name")
- << cla::dual_name_parameter<bool>( RESULT_CODE + "|c" )
- - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
- cla::description = "Allows to disable test modules's result code generation")
- << cla::dual_name_parameter<std::string>( TESTS_TO_RUN + "|t" )
- - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
- cla::description = "Allows to filter which test units to run")
- << cla::named_parameter<bool>( SAVE_TEST_PATTERN )
- - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,
- cla::description = "Allows to switch between saving and matching against test pattern file")
- << cla::dual_name_parameter<bool>( SHOW_PROGRESS + "|p" )
- - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
- cla::description = "Turns on progress display")
- << cla::named_parameter<bool>( USE_ALT_STACK )
- - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,
- cla::description = "Turns on/off usage of an alternative stack for signal handling")
-
- << cla::dual_name_parameter<bool>( "help|?" )
- - (cla::prefix = "--|-",cla::separator = "=",cla::guess_name,cla::optional,
- cla::description = "this help message")
- ;
+ BOOST_TEST_IMPL_TRY {
+ if( s_cla_parser.num_params() != 0 )
+ s_cla_parser.reset();
+ else
+ s_cla_parser - cla::ignore_mismatch
+ << cla::dual_name_parameter<bool>( AUTO_START_DBG + "|d" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
+ cla::description = "Automatically starts debugger if system level error (signal) occurs")
+ << cla::named_parameter<std::string>( BREAK_EXEC_PATH )
+ - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,
+ cla::description = "For the exception safety testing allows to break at specific execution path",
+ cla::handler = &disable_use)
+ << cla::dual_name_parameter<bool>( BUILD_INFO + "|i" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
+ cla::description = "Shows library build information" )
+ << cla::dual_name_parameter<bool>( CATCH_SYS_ERRORS + "|s" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
+ cla::description = "Allows to switch between catching and ignoring system errors (signals)")
+ << cla::dual_name_parameter<bool>( COLOR_OUTPUT + "|x" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
+ cla::description = "Allows to switch between catching and ignoring system errors (signals)")
+ << cla::named_parameter<bool>( DETECT_FP_EXCEPT )
+ - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,
+ cla::description = "Allows to switch between catching and ignoring floating point exceptions")
+ << cla::named_parameter<std::string>( DETECT_MEM_LEAKS )
+ - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,cla::optional_value,
+ cla::description = "Allows to switch between catching and ignoring memory leaks")
+ << cla::dual_name_parameter<unit_test::output_format>( LOG_FORMAT + "|f" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
+ cla::description = "Specifies log format")
+ << cla::dual_name_parameter<unit_test::log_level>( LOG_LEVEL + "|l" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
+ cla::description = "Specifies log level")
+ << cla::dual_name_parameter<std::string>( LOG_SINK + "|k" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
+ cla::description = "Specifies log sink:stdout(default),stderr or file name")
+ << cla::dual_name_parameter<unit_test::output_format>( OUTPUT_FORMAT + "|o" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
+ cla::description = "Specifies output format (both log and report)")
+ << cla::dual_name_parameter<unsigned>( RANDOM_SEED + "|a" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,cla::optional_value,
+ cla::description = "Allows to switch between sequential and random order of test units execution.\n"
+ "Optionally allows to specify concrete seed for random number generator")
+ << cla::dual_name_parameter<unit_test::output_format>( REPORT_FORMAT + "|m" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
+ cla::description = "Specifies report format")
+ << cla::dual_name_parameter<unit_test::report_level>(REPORT_LEVEL + "|r")
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
+ cla::description = "Specifies report level")
+ << cla::dual_name_parameter<std::string>( REPORT_SINK + "|e" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
+ cla::description = "Specifies report sink:stderr(default),stdout or file name")
+ << cla::dual_name_parameter<bool>( RESULT_CODE + "|c" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
+ cla::description = "Allows to disable test modules's result code generation")
+ << cla::dual_name_parameter<std::string>( TESTS_TO_RUN + "|t" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,cla::multiplicable,
+ cla::description = "Allows to filter which test units to run")
+ << cla::named_parameter<bool>( SAVE_TEST_PATTERN )
+ - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,
+ cla::description = "Allows to switch between saving and matching against test pattern file")
+ << cla::dual_name_parameter<bool>( SHOW_PROGRESS + "|p" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
+ cla::description = "Turns on progress display")
+ << cla::dual_name_parameter<unit_test::output_format>( LIST_CONTENT + "|j" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,cla::optional_value,
+ cla::description = "Lists the content of test tree - names of all test suites and test cases")
+ << cla::named_parameter<bool>( LIST_LABELS )
+ - (cla::prefix = "--",cla::separator = "= ",cla::guess_name,cla::optional,
+ cla::description = "Lists all available labels")
+ << cla::named_parameter<bool>( USE_ALT_STACK )
+ - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,
+ cla::description = "Turns on/off usage of an alternative stack for signal handling")
+ << cla::dual_name_parameter<bool>( WAIT_FOR_DEBUGGER + "|w" )
+ - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,cla::optional_value,
+ cla::description = "Forces test module to wait for button to be pressed before starting test run")
+
+ << cla::dual_name_parameter<bool>( "help|?" )
+ - (cla::prefix = "--|-",cla::separator = "=",cla::guess_name,cla::optional,
+ cla::description = "this help message")
+ ;
s_cla_parser.parse( argc, argv );
if( s_cla_parser["help"] ) {
s_cla_parser.help( std::cout );
- throw framework::nothing_to_test();
+ BOOST_TEST_IMPL_THROW( framework::nothing_to_test() );
}
- s_report_format = retrieve_parameter( REPORT_FORMAT, s_cla_parser, unit_test::CLF );
- s_log_format = retrieve_parameter( LOG_FORMAT, s_cla_parser, unit_test::CLF );
+ s_report_format = retrieve_parameter( REPORT_FORMAT, s_cla_parser, unit_test::OF_CLF );
+ s_log_format = retrieve_parameter( LOG_FORMAT, s_cla_parser, unit_test::OF_CLF );
- unit_test::output_format of = retrieve_parameter( OUTPUT_FORMAT, s_cla_parser, unit_test::INV_OF );
+ unit_test::output_format of = retrieve_parameter( OUTPUT_FORMAT, s_cla_parser, unit_test::OF_INVALID );
- if( of != unit_test::INV_OF )
+ if( of != unit_test::OF_INVALID )
s_report_format = s_log_format = of;
+
+ s_test_to_run = retrieve_parameter<std::list<std::string> >( TESTS_TO_RUN, s_cla_parser );
}
- catch( rt::logic_error const& ex ) {
+ BOOST_TEST_IMPL_CATCH( rt::logic_error, ex ) {
std::ostringstream err;
-
+
err << "Fail to process runtime parameters: " << ex.msg() << std::endl;
s_cla_parser.usage( err );
- throw framework::setup_error( err.str() );
+ BOOST_TEST_SETUP_ASSERT( false, err.str() );
}
}
@@ -364,11 +409,9 @@ report_level()
//____________________________________________________________________________//
-const_string
+std::list<std::string> const&
test_to_run()
{
- static std::string s_test_to_run = retrieve_parameter( TESTS_TO_RUN, s_cla_parser, s_empty );
-
return s_test_to_run;
}
@@ -408,14 +451,30 @@ show_build_info()
//____________________________________________________________________________//
+output_format
+list_content()
+{
+ return retrieve_parameter( LIST_CONTENT, s_cla_parser, unit_test::OF_INVALID, unit_test::OF_CLF );
+}
+
+//____________________________________________________________________________//
+
+bool
+list_labels()
+{
+ return retrieve_parameter( LIST_LABELS, s_cla_parser, false );
+}
+
+//____________________________________________________________________________//
+
bool
catch_sys_errors()
{
- return retrieve_parameter( CATCH_SYS_ERRORS, s_cla_parser,
+ return retrieve_parameter( CATCH_SYS_ERRORS, s_cla_parser,
#ifdef BOOST_TEST_DEFAULTS_TO_CORE_DUMP
false
#else
- true
+ true
#endif
);
}
@@ -423,9 +482,17 @@ catch_sys_errors()
//____________________________________________________________________________//
bool
+color_output()
+{
+ return retrieve_parameter( COLOR_OUTPUT, s_cla_parser, false );
+}
+
+//____________________________________________________________________________//
+
+bool
auto_start_dbg()
{
- // !! set debugger as an option
+ // !! ?? set debugger as an option
return retrieve_parameter( AUTO_START_DBG, s_cla_parser, false );
;
}
@@ -433,6 +500,14 @@ auto_start_dbg()
//____________________________________________________________________________//
bool
+wait_for_debugger()
+{
+ return retrieve_parameter( WAIT_FOR_DEBUGGER, s_cla_parser, false );
+}
+
+//____________________________________________________________________________//
+
+bool
use_alt_stack()
{
return retrieve_parameter( USE_ALT_STACK, s_cla_parser, true );
@@ -470,13 +545,13 @@ report_sink()
std::string sink_name = retrieve_parameter( REPORT_SINK, s_cla_parser, s_empty );
if( sink_name.empty() || sink_name == "stderr" )
- return &std::cerr;
-
+ return &std::cerr;
+
if( sink_name == "stdout" )
return &std::cout;
- static std::ofstream log_file( sink_name.c_str() );
- return &log_file;
+ static std::ofstream report_file( sink_name.c_str() );
+ return &report_file;
}
//____________________________________________________________________________//
@@ -487,13 +562,13 @@ log_sink()
std::string sink_name = retrieve_parameter( LOG_SINK, s_cla_parser, s_empty );
if( sink_name.empty() || sink_name == "stdout" )
- return &std::cout;
+ return &std::cout;
if( sink_name == "stderr" )
- return &std::cerr;
+ return &std::cerr;
- static std::ofstream report_file( sink_name.c_str() );
- return &report_file;
+ static std::ofstream log_file( sink_name.c_str() );
+ return &log_file;
}
//____________________________________________________________________________//
@@ -501,27 +576,65 @@ log_sink()
long
detect_memory_leaks()
{
- return retrieve_parameter( DETECT_MEM_LEAKS, s_cla_parser, static_cast<long>(1) );
+ static long s_value = -1;
+
+ if( s_value >= 0 )
+ return s_value;
+
+ std::string value = retrieve_parameter( DETECT_MEM_LEAKS, s_cla_parser, s_empty );
+
+ optional<bool> bool_val;
+ if( runtime::interpret_argument_value_impl<bool>::_( value, bool_val ) )
+ s_value = *bool_val ? 1L : 0L;
+ else {
+ BOOST_TEST_IMPL_TRY {
+ // if representable as long - this is leak number
+ s_value = boost::lexical_cast<long>( value );
+ }
+ BOOST_TEST_IMPL_CATCH0( boost::bad_lexical_cast ) {
+ // value is leak report file and detection is enabled
+ s_value = 1L;
+ }
+ }
+
+ return s_value;
+}
+
+//____________________________________________________________________________//
+
+const_string
+memory_leaks_report_file()
+{
+ if( detect_memory_leaks() != 1 )
+ return const_string();
+
+ static std::string s_value;
+
+ if( s_value.empty() ) {
+ s_value = retrieve_parameter<std::string>( DETECT_MEM_LEAKS, s_cla_parser );
+
+ optional<bool> bool_val;
+ if( runtime::interpret_argument_value_impl<bool>::_( s_value, bool_val ) )
+ s_value.clear();
+ }
+
+ return s_value;
}
//____________________________________________________________________________//
-int
+unsigned
random_seed()
{
- return retrieve_parameter( RANDOM_SEED, s_cla_parser, 0, 1 );
+ return retrieve_parameter( RANDOM_SEED, s_cla_parser, 0U, 1U );
}
//____________________________________________________________________________//
} // namespace runtime_config
-
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_PARAMETERS_IPP_012205GER
diff --git a/boost/test/impl/unit_test_suite.ipp b/boost/test/impl/unit_test_suite.ipp
deleted file mode 100644
index 32efc6059e..0000000000
--- a/boost/test/impl/unit_test_suite.ipp
+++ /dev/null
@@ -1,346 +0,0 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Distributed under the Boost 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/test for the library home page.
-//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : privides core implementation for Unit Test Framework.
-// Extensions can be provided in separate files
-// ***************************************************************************
-
-#ifndef BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
-#define BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
-
-// Boost.Test
-#include <boost/detail/workaround.hpp>
-#include <boost/test/unit_test_suite_impl.hpp>
-#include <boost/test/framework.hpp>
-#include <boost/test/utils/foreach.hpp>
-#include <boost/test/results_collector.hpp>
-#include <boost/test/detail/unit_test_parameters.hpp>
-
-// Boost
-#include <boost/timer.hpp>
-
-// STL
-#include <algorithm>
-#include <vector>
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-#if BOOST_WORKAROUND(__BORLANDC__, < 0x600) && \
- BOOST_WORKAROUND(_STLPORT_VERSION, <= 0x450) \
- /**/
- using std::rand; // rand is in std and random_shuffle is in _STL
-#endif
-
-//____________________________________________________________________________//
-
-namespace boost {
-
-namespace unit_test {
-
-// ************************************************************************** //
-// ************** test_unit ************** //
-// ************************************************************************** //
-
-test_unit::test_unit( const_string name, test_unit_type t )
-: p_type( t )
-, p_type_name( t == tut_case ? "case" : "suite" )
-, p_id( INV_TEST_UNIT_ID )
-, p_name( std::string( name.begin(), name.size() ) )
-, p_enabled( true )
-{
-}
-
-//____________________________________________________________________________//
-
-test_unit::~test_unit()
-{
- framework::deregister_test_unit( this );
-}
-
-//____________________________________________________________________________//
-
-void
-test_unit::depends_on( test_unit* tu )
-{
- m_dependencies.push_back( tu->p_id );
-}
-
-//____________________________________________________________________________//
-
-bool
-test_unit::check_dependencies() const
-{
- BOOST_TEST_FOREACH( test_unit_id, tu_id, m_dependencies ) {
- if( !unit_test::results_collector.results( tu_id ).passed() )
- return false;
- }
-
- return true;
-}
-
-//____________________________________________________________________________//
-
-void
-test_unit::increase_exp_fail( unsigned num )
-{
- p_expected_failures.value += num;
-
- if( p_parent_id != 0 )
- framework::get<test_suite>( p_parent_id ).increase_exp_fail( num );
-}
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** test_case ************** //
-// ************************************************************************** //
-
-test_case::test_case( const_string name, callback0<> const& test_func )
-: test_unit( name, static_cast<test_unit_type>(type) )
-, m_test_func( test_func )
-{
- // !! weirdest MSVC BUG; try to remove this statement; looks like it eats first token of next statement
-#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
- 0;
-#endif
- framework::register_test_unit( this );
-}
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** test_suite ************** //
-// ************************************************************************** //
-
-//____________________________________________________________________________//
-
-test_suite::test_suite( const_string name )
-: test_unit( name, static_cast<test_unit_type>(type) )
-{
- framework::register_test_unit( this );
-}
-
-//____________________________________________________________________________//
-
-void
-test_suite::add( test_unit* tu, counter_t expected_failures, unsigned timeout )
-{
- if( timeout != 0 )
- tu->p_timeout.value = timeout;
-
- m_members.push_back( tu->p_id );
- tu->p_parent_id.value = p_id;
-
- if( tu->p_expected_failures )
- increase_exp_fail( tu->p_expected_failures );
-
- if( expected_failures )
- tu->increase_exp_fail( expected_failures );
-}
-
-//____________________________________________________________________________//
-
-void
-test_suite::add( test_unit_generator const& gen, unsigned timeout )
-{
- test_unit* tu;
- while((tu = gen.next(), tu))
- add( tu, 0, timeout );
-}
-
-//____________________________________________________________________________//
-
-void
-test_suite::remove( test_unit_id id )
-{
- std::vector<test_unit_id>::iterator it = std::find( m_members.begin(), m_members.end(), id );
-
- if( it != m_members.end() )
- m_members.erase( it );
-}
-
-//____________________________________________________________________________//
-
-test_unit_id
-test_suite::get( const_string tu_name ) const
-{
- BOOST_TEST_FOREACH( test_unit_id, id, m_members ) {
- if( tu_name == framework::get( id, ut_detail::test_id_2_unit_type( id ) ).p_name.get() )
- return id;
- }
-
- return INV_TEST_UNIT_ID;
-}
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** traverse_test_tree ************** //
-// ************************************************************************** //
-
-void
-traverse_test_tree( test_case const& tc, test_tree_visitor& V )
-{
- if( tc.p_enabled )
- V.visit( tc );
-}
-
-//____________________________________________________________________________//
-
-void
-traverse_test_tree( test_suite const& suite, test_tree_visitor& V )
-{
- if( !suite.p_enabled || !V.test_suite_start( suite ) )
- return;
-
- try {
- if( runtime_config::random_seed() == 0 ) {
- BOOST_TEST_FOREACH( test_unit_id, id, suite.m_members )
- traverse_test_tree( id, V );
- }
- else {
- std::vector<test_unit_id> members( suite.m_members );
- std::random_shuffle( members.begin(), members.end() );
- BOOST_TEST_FOREACH( test_unit_id, id, members )
- traverse_test_tree( id, V );
- }
-
- } catch( test_being_aborted const& ) {
- V.test_suite_finish( suite );
- framework::test_unit_aborted( suite );
-
- throw;
- }
-
- V.test_suite_finish( suite );
-}
-
-//____________________________________________________________________________//
-
-void
-traverse_test_tree( test_unit_id id, test_tree_visitor& V )
-{
- if( ut_detail::test_id_2_unit_type( id ) == tut_case )
- traverse_test_tree( framework::get<test_case>( id ), V );
- else
- traverse_test_tree( framework::get<test_suite>( id ), V );
-}
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** test_case_counter ************** //
-// ************************************************************************** //
-
-void
-test_case_counter::visit( test_case const& tc )
-{
- if( tc.p_enabled )
- ++p_count.value;
-}
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** object generators ************** //
-// ************************************************************************** //
-
-namespace ut_detail {
-
-std::string
-normalize_test_case_name( const_string name )
-{
- return ( name[0] == '&'
- ? std::string( name.begin()+1, name.size()-1 )
- : std::string( name.begin(), name.size() ) );
-}
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** auto_test_unit_registrar ************** //
-// ************************************************************************** //
-
-auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, counter_t exp_fail )
-{
- curr_ts_store().back()->add( tc, exp_fail );
-}
-
-//____________________________________________________________________________//
-
-auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name )
-{
- test_unit_id id = curr_ts_store().back()->get( ts_name );
-
- test_suite* ts;
-
- if( id != INV_TEST_UNIT_ID ) {
- ts = &framework::get<test_suite>( id ); // !! test for invalid tu type
- BOOST_ASSERT( ts->p_parent_id == curr_ts_store().back()->p_id );
- }
- else {
- ts = new test_suite( ts_name );
- curr_ts_store().back()->add( ts );
- }
-
- curr_ts_store().push_back( ts );
-}
-
-//____________________________________________________________________________//
-
-auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_gen )
-{
- curr_ts_store().back()->add( tc_gen );
-}
-
-//____________________________________________________________________________//
-
-auto_test_unit_registrar::auto_test_unit_registrar( int )
-{
- if( curr_ts_store().size() == 0 )
- return; // report error?
-
- curr_ts_store().pop_back();
-}
-
-//____________________________________________________________________________//
-
-std::list<test_suite*>&
-auto_test_unit_registrar::curr_ts_store()
-{
- static std::list<test_suite*> inst( 1, &framework::master_test_suite() );
- return inst;
-}
-
-//____________________________________________________________________________//
-
-} // namespace ut_detail
-
-// ************************************************************************** //
-// ************** global_fixture ************** //
-// ************************************************************************** //
-
-global_fixture::global_fixture()
-{
- framework::register_observer( *this );
-}
-
-//____________________________________________________________________________//
-
-} // namespace unit_test
-
-} // namespace boost
-
-//____________________________________________________________________________//
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
diff --git a/boost/test/impl/xml_log_formatter.ipp b/boost/test/impl/xml_log_formatter.ipp
index 6c0127bb57..286cd60005 100644
--- a/boost/test/impl/xml_log_formatter.ipp
+++ b/boost/test/impl/xml_log_formatter.ipp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -9,7 +9,7 @@
//
// Version : $Revision$
//
-// Description : implements XML Log formatter
+// Description : implements OF_XML Log formatter
// ***************************************************************************
#ifndef BOOST_TEST_XML_LOG_FORMATTER_IPP_020105GER
@@ -17,10 +17,10 @@
// Boost.Test
#include <boost/test/output/xml_log_formatter.hpp>
-#include <boost/test/unit_test_suite_impl.hpp>
+#include <boost/test/execution_monitor.hpp>
#include <boost/test/framework.hpp>
+#include <boost/test/tree/test_unit.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
-
#include <boost/test/utils/xml_printer.hpp>
// Boost
@@ -34,14 +34,12 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
-
namespace output {
static const_string tu_type_name( test_unit const& tu )
{
- return tu.p_type == tut_case ? "TestCase" : "TestSuite";
+ return tu.p_type == TUT_CASE ? "TestCase" : "TestSuite";
}
// ************************************************************************** //
@@ -82,7 +80,13 @@ xml_log_formatter::log_build_info( std::ostream& ostr )
void
xml_log_formatter::test_unit_start( std::ostream& ostr, test_unit const& tu )
{
- ostr << "<" << tu_type_name( tu ) << " name" << attr_value() << tu.p_name.get() << ">";
+ ostr << "<" << tu_type_name( tu ) << " name" << attr_value() << tu.p_name.get();
+
+ if( !tu.p_file_name.get().empty() )
+ ostr << BOOST_TEST_L( " file" ) << attr_value() << tu.p_file_name
+ << BOOST_TEST_L( " line" ) << attr_value() << tu.p_line_num;
+
+ ostr << ">";
}
//____________________________________________________________________________//
@@ -90,27 +94,28 @@ xml_log_formatter::test_unit_start( std::ostream& ostr, test_unit const& tu )
void
xml_log_formatter::test_unit_finish( std::ostream& ostr, test_unit const& tu, unsigned long elapsed )
{
- if( tu.p_type == tut_case )
+ if( tu.p_type == TUT_CASE )
ostr << "<TestingTime>" << elapsed << "</TestingTime>";
-
+
ostr << "</" << tu_type_name( tu ) << ">";
}
//____________________________________________________________________________//
void
-xml_log_formatter::test_unit_skipped( std::ostream& ostr, test_unit const& tu )
+xml_log_formatter::test_unit_skipped( std::ostream& ostr, test_unit const& tu, const_string reason )
{
ostr << "<" << tu_type_name( tu )
<< " name" << attr_value() << tu.p_name.get()
<< " skipped" << attr_value() << "yes"
+ << " reason" << attr_value() << reason
<< "/>";
}
-
+
//____________________________________________________________________________//
void
-xml_log_formatter::log_exception( std::ostream& ostr, log_checkpoint_data const& checkpoint_data, execution_exception const& ex )
+xml_log_formatter::log_exception_start( std::ostream& ostr, log_checkpoint_data const& checkpoint_data, execution_exception const& ex )
{
execution_exception::location const& loc = ex.where();
@@ -129,7 +134,13 @@ xml_log_formatter::log_exception( std::ostream& ostr, log_checkpoint_data const&
<< cdata() << checkpoint_data.m_message
<< "</LastCheckpoint>";
}
+}
+
+//____________________________________________________________________________//
+void
+xml_log_formatter::log_exception_finish( std::ostream& ostr )
+{
ostr << "</Exception>";
}
@@ -145,6 +156,8 @@ xml_log_formatter::log_entry_start( std::ostream& ostr, log_entry_data const& en
<< BOOST_TEST_L( " file" ) << attr_value() << entry_data.m_file_name
<< BOOST_TEST_L( " line" ) << attr_value() << entry_data.m_line_num
<< BOOST_TEST_L( "><![CDATA[" );
+
+ m_value_closed = false;
}
//____________________________________________________________________________//
@@ -152,7 +165,7 @@ xml_log_formatter::log_entry_start( std::ostream& ostr, log_entry_data const& en
void
xml_log_formatter::log_entry_value( std::ostream& ostr, const_string value )
{
- ostr << value;
+ print_escaped_cdata( ostr, value );
}
//____________________________________________________________________________//
@@ -160,21 +173,52 @@ xml_log_formatter::log_entry_value( std::ostream& ostr, const_string value )
void
xml_log_formatter::log_entry_finish( std::ostream& ostr )
{
- ostr << BOOST_TEST_L( "]]></" ) << m_curr_tag << BOOST_TEST_L( ">" );
+ if( !m_value_closed ) {
+ ostr << BOOST_TEST_L( "]]>" );
+ m_value_closed = true;
+ }
+
+ ostr << BOOST_TEST_L( "</" ) << m_curr_tag << BOOST_TEST_L( ">" );
m_curr_tag.clear();
}
//____________________________________________________________________________//
-} // namespace output
+void
+xml_log_formatter::entry_context_start( std::ostream& ostr, log_level )
+{
+ if( !m_value_closed ) {
+ ostr << BOOST_TEST_L( "]]>" );
+ m_value_closed = true;
+ }
-} // namespace unit_test
+ ostr << BOOST_TEST_L( "<Context>" );
-} // namespace boost
+}
+
+//____________________________________________________________________________//
+
+void
+xml_log_formatter::entry_context_finish( std::ostream& ostr )
+{
+ ostr << BOOST_TEST_L( "</Context>" );
+}
//____________________________________________________________________________//
+void
+xml_log_formatter::log_entry_context( std::ostream& ostr, const_string context_descr )
+{
+ ostr << BOOST_TEST_L( "<Frame>" ) << cdata() << context_descr << BOOST_TEST_L( "</Frame>" );
+}
+
+//____________________________________________________________________________//
+
+} // namespace output
+} // namespace unit_test
+} // namespace boost
+
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_XML_LOG_FORMATTER_IPP_020105GER
diff --git a/boost/test/impl/xml_report_formatter.ipp b/boost/test/impl/xml_report_formatter.ipp
index 261db788b3..5606fdc0b1 100644
--- a/boost/test/impl/xml_report_formatter.ipp
+++ b/boost/test/impl/xml_report_formatter.ipp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -9,7 +9,7 @@
//
// Version : $Revision$
//
-// Description : XML report formatter
+// Description : OF_XML report formatter
// ***************************************************************************
#ifndef BOOST_TEST_XML_REPORT_FORMATTER_IPP_020105GER
@@ -17,9 +17,9 @@
// Boost.Test
#include <boost/test/results_collector.hpp>
-#include <boost/test/unit_test_suite_impl.hpp>
#include <boost/test/output/xml_report_formatter.hpp>
+#include <boost/test/tree/test_unit.hpp>
#include <boost/test/utils/xml_printer.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
@@ -28,9 +28,7 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
-
namespace output {
void
@@ -66,20 +64,23 @@ xml_report_formatter::test_unit_report_start( test_unit const& tu, std::ostream&
else
descr = "failed";
- ostr << '<' << ( tu.p_type == tut_case ? "TestCase" : "TestSuite" )
+ ostr << '<' << ( tu.p_type == TUT_CASE ? "TestCase" : "TestSuite" )
<< " name" << attr_value() << tu.p_name.get()
<< " result" << attr_value() << descr
<< " assertions_passed" << attr_value() << tr.p_assertions_passed
<< " assertions_failed" << attr_value() << tr.p_assertions_failed
+ << " warnings_failed" << attr_value() << tr.p_warnings_failed
<< " expected_failures" << attr_value() << tr.p_expected_failures;
- if( tu.p_type == tut_suite )
+ if( tu.p_type == TUT_SUITE ) {
ostr << " test_cases_passed" << attr_value() << tr.p_test_cases_passed
+ << " test_cases_passed_with_warnings" << attr_value() << tr.p_test_cases_warned
<< " test_cases_failed" << attr_value() << tr.p_test_cases_failed
<< " test_cases_skipped" << attr_value() << tr.p_test_cases_skipped
<< " test_cases_aborted" << attr_value() << tr.p_test_cases_aborted;
-
-
+ }
+
+
ostr << '>';
}
@@ -88,7 +89,7 @@ xml_report_formatter::test_unit_report_start( test_unit const& tu, std::ostream&
void
xml_report_formatter::test_unit_report_finish( test_unit const& tu, std::ostream& ostr )
{
- ostr << "</" << ( tu.p_type == tut_case ? "TestCase" : "TestSuite" ) << '>';
+ ostr << "</" << ( tu.p_type == TUT_CASE ? "TestCase" : "TestSuite" ) << '>';
}
//____________________________________________________________________________//
@@ -97,19 +98,15 @@ void
xml_report_formatter::do_confirmation_report( test_unit const& tu, std::ostream& ostr )
{
test_unit_report_start( tu, ostr );
- test_unit_report_finish( tu, ostr );
+ test_unit_report_finish( tu, ostr );
}
//____________________________________________________________________________//
} // namespace output
-
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_XML_REPORT_FORMATTER_IPP_020105GER
diff --git a/boost/test/included/execution_monitor.hpp b/boost/test/included/execution_monitor.hpp
new file mode 100644
index 0000000000..d372084604
--- /dev/null
+++ b/boost/test/included/execution_monitor.hpp
@@ -0,0 +1,21 @@
+// (C) Copyright Gennadiy Rozental 2010-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision$
+//
+// Description : included variant of Execution Monitor to be used independently
+// ***************************************************************************
+
+#ifndef BOOST_INCLUDED_EXECUTION_MONITOR_HPP_051410GER
+#define BOOST_INCLUDED_EXECUTION_MONITOR_HPP_051410GER
+
+#include <boost/test/impl/execution_monitor.ipp>
+#include <boost/test/impl/debug.ipp>
+
+#endif // BOOST_INCLUDED_EXECUTION_MONITOR_HPP_051410GER
diff --git a/boost/test/included/prg_exec_monitor.hpp b/boost/test/included/prg_exec_monitor.hpp
index 530cc3feba..e8d655be7d 100644
--- a/boost/test/included/prg_exec_monitor.hpp
+++ b/boost/test/included/prg_exec_monitor.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
diff --git a/boost/test/included/test_exec_monitor.hpp b/boost/test/included/test_exec_monitor.hpp
index 8d351b158b..0d5e4b1bf4 100644
--- a/boost/test/included/test_exec_monitor.hpp
+++ b/boost/test/included/test_exec_monitor.hpp
@@ -1,15 +1,13 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
//
-// Version : $Revision$
-//
-// Description : included (vs. linked) version of Test Execution Monitor
+/// @file
+/// @brief Included (vs. linked) version of Test Execution Monitor
// ***************************************************************************
#ifndef BOOST_INCLUDED_TEST_EXEC_MONITOR_HPP_071894GER
@@ -17,6 +15,7 @@
#include <boost/test/impl/compiler_log_formatter.ipp>
#include <boost/test/impl/debug.ipp>
+#include <boost/test/impl/decorator.ipp>
#include <boost/test/impl/execution_monitor.ipp>
#include <boost/test/impl/framework.ipp>
#include <boost/test/impl/plain_report_formatter.ipp>
@@ -25,11 +24,11 @@
#include <boost/test/impl/results_reporter.ipp>
#include <boost/test/impl/test_main.ipp>
#include <boost/test/impl/test_tools.ipp>
+#include <boost/test/impl/test_tree.ipp>
#include <boost/test/impl/unit_test_log.ipp>
#include <boost/test/impl/unit_test_main.ipp>
#include <boost/test/impl/unit_test_monitor.ipp>
#include <boost/test/impl/unit_test_parameters.ipp>
-#include <boost/test/impl/unit_test_suite.ipp>
#include <boost/test/impl/xml_log_formatter.ipp>
#include <boost/test/impl/xml_report_formatter.ipp>
diff --git a/boost/test/included/unit_test.hpp b/boost/test/included/unit_test.hpp
index 5b2d50ab71..5bc17a38cb 100644
--- a/boost/test/included/unit_test.hpp
+++ b/boost/test/included/unit_test.hpp
@@ -1,15 +1,12 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : included (vs. linked) version of Unit Test Framework
+//!@file
+//!@brief Included (vs. linked) version of Unit Test Framework
// ***************************************************************************
#ifndef BOOST_INCLUDED_UNIT_TEST_FRAMEWORK_HPP_071894GER
@@ -17,21 +14,19 @@
#include <boost/test/impl/compiler_log_formatter.ipp>
#include <boost/test/impl/debug.ipp>
+#include <boost/test/impl/decorator.ipp>
#include <boost/test/impl/framework.ipp>
-#include <boost/test/impl/exception_safety.ipp>
#include <boost/test/impl/execution_monitor.ipp>
-#include <boost/test/impl/interaction_based.ipp>
-#include <boost/test/impl/logged_expectations.ipp>
#include <boost/test/impl/plain_report_formatter.ipp>
#include <boost/test/impl/progress_monitor.ipp>
#include <boost/test/impl/results_collector.ipp>
#include <boost/test/impl/results_reporter.ipp>
#include <boost/test/impl/test_tools.ipp>
+#include <boost/test/impl/test_tree.ipp>
#include <boost/test/impl/unit_test_log.ipp>
#include <boost/test/impl/unit_test_main.ipp>
#include <boost/test/impl/unit_test_monitor.ipp>
#include <boost/test/impl/unit_test_parameters.ipp>
-#include <boost/test/impl/unit_test_suite.ipp>
#include <boost/test/impl/xml_log_formatter.ipp>
#include <boost/test/impl/xml_report_formatter.ipp>
diff --git a/boost/test/included/unit_test_framework.hpp b/boost/test/included/unit_test_framework.hpp
index 2eab54ea91..219cc6c283 100644
--- a/boost/test/included/unit_test_framework.hpp
+++ b/boost/test/included/unit_test_framework.hpp
@@ -1,2 +1,12 @@
-// deprecated
+// (C) Copyright Gennadiy Rozental 2001-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/test for the library home page.
+//
+/// @file
+/// @deprecated
+// ***************************************************************************
+
#include <boost/test/included/unit_test.hpp>
diff --git a/boost/test/interaction_based.hpp b/boost/test/interaction_based.hpp
deleted file mode 100644
index e77128abd2..0000000000
--- a/boost/test/interaction_based.hpp
+++ /dev/null
@@ -1,262 +0,0 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Distributed under the Boost 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/test for the library home page.
-//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : Facilities to perform interaction-based testing
-// ***************************************************************************
-
-#ifndef BOOST_TEST_INTERACTION_BASED_HPP_112105GER
-#define BOOST_TEST_INTERACTION_BASED_HPP_112105GER
-
-// Boost.Test
-#include <boost/test/detail/config.hpp>
-#include <boost/test/detail/global_typedef.hpp>
-
-#include <boost/test/utils/wrap_stringstream.hpp>
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-// Boost
-#include <boost/lexical_cast.hpp>
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** BOOST_ITEST_EPOINT ************** //
-// ************************************************************************** //
-
-#define BOOST_ITEST_EPOINT( description ) \
- ::boost::itest::manager::instance().exception_point( BOOST_TEST_L(__FILE__), __LINE__, description )
-/**/
-
-// ************************************************************************** //
-// ************** BOOST_ITEST_DPOINT ************** //
-// ************************************************************************** //
-
-#define BOOST_ITEST_DPOINT() \
- ::boost::itest::manager::instance().decision_point( BOOST_TEST_L(__FILE__), __LINE__ )
-/**/
-
-// ************************************************************************** //
-// ************** BOOST_ITEST_SCOPE ************** //
-// ************************************************************************** //
-
-#define BOOST_ITEST_SCOPE( scope_name ) \
- ::boost::itest::scope_guard itest_scope_guard ## __LINE__( BOOST_TEST_L(__FILE__), __LINE__, BOOST_STRINGIZE(scope_name) )
-/**/
-
-// ************************************************************************** //
-// ************** BOOST_ITEST_NEW ************** //
-// ************************************************************************** //
-
-#define BOOST_ITEST_NEW( type_name ) \
- new ( ::boost::itest::location( BOOST_TEST_L(__FILE__), __LINE__ ) ) type_name
-/**/
-
-// ************************************************************************** //
-// ************** BOOST_ITEST_DATA_FLOW ************** //
-// ************************************************************************** //
-
-#define BOOST_ITEST_DATA_FLOW( v ) \
- ::boost::itest::manager::instance().generic_data_flow( v )
-/**/
-
-// ************************************************************************** //
-// ************** BOOST_ITEST_RETURN ************** //
-// ************************************************************************** //
-
-#define BOOST_ITEST_RETURN( type, default_value ) \
- ::boost::itest::manager::instance().generic_return<type>( default_value )
-/**/
-
-// ************************************************************************** //
-// ************** BOOST_ITEST_MOCK_FUNC ************** //
-// ************************************************************************** //
-
-#define BOOST_ITEST_MOCK_FUNC( function_name ) \
- BOOST_ITEST_SCOPE( function_name ); \
- BOOST_ITEST_EPOINT( 0 ); \
- return ::boost::itest::mock_object<>::prototype(); \
-/**/
-
-namespace boost {
-
-namespace itest { // interaction-based testing
-
-using unit_test::const_string;
-
-// ************************************************************************** //
-// ************** manager ************** //
-// ************************************************************************** //
-
-class BOOST_TEST_DECL manager {
-public:
- // instance access
- static manager& instance() { return *instance_ptr(); }
-
- // Mock objects interface hooks
- virtual void exception_point( const_string /*file*/,
- std::size_t /*line_num*/,
- const_string /*descr*/ ){}
- virtual bool decision_point( const_string /*file*/,
- std::size_t /*line_num*/ ) { return true; }
- virtual unsigned enter_scope( const_string /*file*/,
- std::size_t /*line_num*/,
- const_string /*scope_name*/){ return 0; }
- virtual void leave_scope( unsigned ) {}
- virtual void allocated( const_string /*file*/,
- std::size_t /*line_num*/,
- void* /*p*/, std::size_t /*s*/ ) {}
- virtual void freed( void* /*p*/ ) {}
- virtual void data_flow( const_string /*d*/ ) {}
- virtual std::string return_value( const_string /*default_value */ ) { return ""; }
-
- template<typename T>
- void generic_data_flow( T const& t )
- {
- wrap_stringstream ws;
-
- data_flow( (ws << t).str() );
- }
- template<typename T, typename DefaultValueType>
- T generic_return( DefaultValueType const& dv )
- {
- wrap_stringstream ws;
-
- std::string const& res = return_value( (ws << dv).str() );
-
- if( res.empty() )
- return dv;
-
- return lexical_cast<T>( res );
- }
-
-protected:
- manager();
-#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
-public:
-#endif
- BOOST_TEST_PROTECTED_VIRTUAL ~manager();
-
-private:
- struct dummy_constr{};
- explicit manager( dummy_constr* ) {}
-
- static manager* instance_ptr( bool reset = false, manager* ptr = 0 );
-}; // manager
-
-// ************************************************************************** //
-// ************** scope_guard ************** //
-// ************************************************************************** //
-
-class scope_guard {
-public:
- // Constructor
- scope_guard( const_string file, std::size_t line_num, const_string scope_name )
- {
- m_scope_index = manager::instance().enter_scope( file, line_num, scope_name );
- }
- ~scope_guard()
- {
- manager::instance().leave_scope( m_scope_index );
- }
-
- unsigned m_scope_index;
-};
-
-// ************************************************************************** //
-// ************** location ************** //
-// ************************************************************************** //
-
-struct location {
- location( const_string file, std::size_t line )
- : m_file_name( file )
- , m_line_num( line )
- {}
-
- const_string m_file_name;
- std::size_t m_line_num;
-};
-
-} // namespace itest
-
-} // namespace boost
-
-// ************************************************************************** //
-// ************** operator new overload ************** //
-// ************************************************************************** //
-
-#if !defined(BOOST_ITEST_NO_NEW_OVERLOADS)
-
-// STL
-#include <cstdlib>
-
-# ifdef BOOST_NO_STDC_NAMESPACE
-namespace std { using ::malloc; using ::free; }
-# endif
-# ifdef _CRTDBG_MAP_ALLOC
-namespace std { using ::_malloc_dbg; using ::_free_dbg; }
-# endif
-
-inline void*
-operator new( std::size_t s, ::boost::itest::location const& l )
-{
- void* res = std::malloc(s ? s : 1);
-
- if( res )
- ::boost::itest::manager::instance().allocated( l.m_file_name, l.m_line_num, res, s );
- else
- throw std::bad_alloc();
-
- return res;
-}
-
-//____________________________________________________________________________//
-
-inline void*
-operator new[]( std::size_t s, ::boost::itest::location const& l )
-{
- void* res = std::malloc(s ? s : 1);
-
- if( res )
- ::boost::itest::manager::instance().allocated( l.m_file_name, l.m_line_num, res, s );
- else
- throw std::bad_alloc();
-
- return res;
-}
-
-//____________________________________________________________________________//
-
-inline void
-operator delete( void* p, ::boost::itest::location const& )
-{
- ::boost::itest::manager::instance().freed( p );
-
- std::free( p );
-}
-
-//____________________________________________________________________________//
-
-inline void
-operator delete[]( void* p, ::boost::itest::location const& )
-{
- ::boost::itest::manager::instance().freed( p );
-
- std::free( p );
-}
-
-//____________________________________________________________________________//
-
-#endif
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // BOOST_TEST_INTERACTION_BASED_HPP_112105GER
diff --git a/boost/test/logged_expectations.hpp b/boost/test/logged_expectations.hpp
deleted file mode 100644
index 868281216a..0000000000
--- a/boost/test/logged_expectations.hpp
+++ /dev/null
@@ -1,74 +0,0 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Distributed under the Boost 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/test for the library home page.
-//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : Facilities to perform interaction based testng of logged expectations
-// ***************************************************************************
-
-#ifndef BOOST_TEST_LOGGED_EXPECTATIONS_HPP_120905GER
-#define BOOST_TEST_LOGGED_EXPECTATIONS_HPP_120905GER
-
-// Boost.Test
-#include <boost/test/detail/config.hpp>
-#include <boost/test/detail/unit_test_parameters.hpp>
-#include <boost/test/utils/callback.hpp>
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** BOOST_TEST_LOGGED_EXPECTATIONS ************** //
-// ************************************************************************** //
-
-#define BOOST_TEST_LOGGED_EXPECTATIONS( test_name ) \
-struct test_name : public BOOST_AUTO_TEST_CASE_FIXTURE \
-{ void test_method(); }; \
- \
-static void BOOST_AUTO_TC_INVOKER( test_name )() \
-{ \
- test_name t; \
- ::boost::itest::logged_expectations( \
- boost::bind( &test_name::test_method, t ), \
- BOOST_STRINGIZE(test_name) ".elog", \
- !::boost::unit_test::runtime_config::save_pattern() ); \
-} \
- \
-struct BOOST_AUTO_TC_UNIQUE_ID( test_name ) {}; \
- \
-BOOST_AUTO_TU_REGISTRAR( test_name )( \
- boost::unit_test::make_test_case( \
- &BOOST_AUTO_TC_INVOKER( test_name ), #test_name ), \
- boost::unit_test::ut_detail::auto_tc_exp_fail< \
- BOOST_AUTO_TC_UNIQUE_ID( test_name )>::instance()->value() ); \
- \
-void test_name::test_method() \
-/**/
-
-namespace boost {
-
-namespace itest {
-
-// ************************************************************************** //
-// ************** logged expectations test ************** //
-// ************************************************************************** //
-
-void BOOST_TEST_DECL
-logged_expectations( unit_test::callback0<> const& F,
- unit_test::const_string log_file_name,
- bool test_or_log = true );
-
-} // namespace itest
-
-} // namespace boost
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // BOOST_TEST_LOGGED_EXPECTATIONS_HPP_120905GER
diff --git a/boost/test/minimal.hpp b/boost/test/minimal.hpp
index 7d32150560..dfaa68c6e2 100644
--- a/boost/test/minimal.hpp
+++ b/boost/test/minimal.hpp
@@ -1,15 +1,31 @@
-// (C) Copyright Gennadiy Rozental 2002-2008.
+// (C) Copyright Gennadiy Rozental 2002-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : simple minimal testing definitions and implementation
+/// @file
+/// @brief Deprecated implementation of simple minimal testing
+/// @deprecated
+/// To convert to Unit Test Framework simply rewrite:
+/// @code
+/// #include <boost/test/minimal.hpp>
+///
+/// int test_main( int, char *[] )
+/// {
+/// ...
+/// }
+/// @endcode
+/// as
+/// @code
+/// #include <boost/test/included/unit_test.hpp>
+///
+/// BOOST_AUTO_TEST_CASE(test_main)
+/// {
+/// ...
+/// }
+/// @endcode
// ***************************************************************************
#ifndef BOOST_TEST_MINIMAL_HPP_071894GER
@@ -40,7 +56,7 @@
#include <boost/test/utils/basic_cstring/io.hpp>
// Boost
-#include <boost/cstdlib.hpp> // for exit codes#include <boost/cstdlib.hpp> // for exit codes
+#include <boost/cstdlib.hpp> // for exit codes
#include <boost/current_function.hpp> // for BOOST_CURRENT_FUNCTION
// STL
@@ -101,7 +117,6 @@ private:
}; // monitor
} // namespace minimal_test
-
} // namespace boost
//____________________________________________________________________________//
@@ -118,9 +133,7 @@ int BOOST_TEST_CALL_DECL main( int argc, char* argv[] )
}
catch( boost::execution_exception const& exex ) {
if( exex.code() != boost::execution_exception::no_error )
- BOOST_ERROR( (std::string( "exception \"" ).
- append( exex.what().begin(), exex.what().end() ).
- append( "\" caught" ) ).c_str() );
+ BOOST_ERROR( (std::string( "exception \"" ) + exex.what() + "\" caught").c_str() );
std::cerr << "\n**** Testing aborted.";
}
@@ -132,7 +145,7 @@ int BOOST_TEST_CALL_DECL main( int argc, char* argv[] )
}
std::cout << "\n**** no errors detected\n";
-
+
return boost::exit_success;
}
diff --git a/boost/test/mock_object.hpp b/boost/test/mock_object.hpp
deleted file mode 100644
index dbc4cb410a..0000000000
--- a/boost/test/mock_object.hpp
+++ /dev/null
@@ -1,328 +0,0 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Distributed under the Boost 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/test for the library home page.
-//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : Facilities to perform exception safety_tests
-// ***************************************************************************
-
-#ifndef BOOST_TEST_MOCK_OBJECT_HPP_112205GER
-#define BOOST_TEST_MOCK_OBJECT_HPP_112205GER
-
-// Boost.Test
-#include <boost/test/detail/config.hpp>
-#include <boost/test/interaction_based.hpp>
-
-// Boost
-#include <boost/preprocessor/punctuation/comma.hpp>
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-//____________________________________________________________________________//
-
-namespace boost {
-
-namespace itest {
-
-// ************************************************************************** //
-// ************** mock_object_base ************** //
-// ************************************************************************** //
-
-class mock_object_base {
-public:
- mock_object_base() {}
-
- template<typename T1>
- mock_object_base( T1 const& ) {}
-
- template<typename T1, typename T2>
- mock_object_base( T1 const&, T2 const& ) {}
-
- template<typename T1, typename T2, typename T3>
- mock_object_base( T1 const&, T2 const&, T3 const& ) {}
-
- template<typename T1, typename T2, typename T3, typename T4>
- mock_object_base( T1 const&, T2 const&, T3 const&, T4 const& ) {}
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5>
- mock_object_base( T1 const&, T2 const&, T3 const&, T4 const&, T5 const& ) {}
-};
-
-// ************************************************************************** //
-// ************** mock_object implementation helpers ************** //
-// ************************************************************************** //
-
-#define MO_OP_IMPL( op, descr, ret ) \
- BOOST_ITEST_SCOPE( mock_object::operator op ); \
- BOOST_ITEST_EPOINT( descr ); \
- return ret \
-/**/
-
-#define MO_UNARY_OP( op, descr ) \
-self_type const& operator op() const \
-{ \
- MO_OP_IMPL( op, descr, prototype() ); \
-} \
-/**/
-
-#define MO_UNARY_BOOL_OP( op, descr ) \
-bool operator op() const \
-{ \
- MO_OP_IMPL( op, descr, (!!BOOST_ITEST_DPOINT()) ); \
-} \
-/**/
-
-#define MO_BINARY_OP( op, descr ) \
-template<int i1, typename Base1,int i2, typename Base2> \
-inline mock_object<i1,Base1> const& \
-operator op( mock_object<i1,Base1> const& mo, \
- mock_object<i2,Base2> const& ) \
-{ \
- MO_OP_IMPL( op, descr, mo ); \
-} \
- \
-template<int i, typename Base, typename T> \
-inline mock_object<i,Base> const& \
-operator op( mock_object<i,Base> const& mo, T const& ) \
-{ \
- MO_OP_IMPL( op, descr, mo ); \
-} \
- \
-template<int i, typename Base, typename T> \
-inline mock_object<i,Base> const& \
-operator op( T const&, mock_object<i,Base> const& mo ) \
-{ \
- MO_OP_IMPL( op, descr, mo ); \
-} \
-/**/
-
-#define MO_BINARY_BOOL_OP( op, descr ) \
-template<int i1, typename Base1,int i2, typename Base2> \
-inline bool \
-operator op( mock_object<i1,Base1> const&, \
- mock_object<i2,Base2> const& ) \
-{ \
- MO_OP_IMPL( op, descr, BOOST_ITEST_DPOINT() ); \
-} \
- \
-template<int i, typename Base, typename T> \
-inline bool \
-operator op( mock_object<i,Base> const&, T const& ) \
-{ \
- MO_OP_IMPL( op, descr, BOOST_ITEST_DPOINT() ); \
-} \
- \
-template<int i, typename Base, typename T> \
-inline bool \
-operator op( T const&, mock_object<i,Base> const& ) \
-{ \
- MO_OP_IMPL( op, descr, BOOST_ITEST_DPOINT() ); \
-} \
-/**/
-
-// ************************************************************************** //
-// ************** mock_object ************** //
-// ************************************************************************** //
-
-template<int i = 0, typename Base=mock_object_base>
-class mock_object;
-
-template<int i, typename Base>
-class mock_object : public Base {
- // Private typeefs
- typedef mock_object<i,Base> self_type;
- struct dummy { void nonnull() {}; };
- typedef void (dummy::*safe_bool)();
-
- // prototype constructor
- mock_object( dummy* ) {}
-
-public:
- static mock_object& prototype()
- {
- static mock_object p( reinterpret_cast<dummy*>(0) );
- return p;
- }
-
- // Constructors
- mock_object()
- {
- BOOST_ITEST_SCOPE( mock_object::mock_object );
- BOOST_ITEST_EPOINT( "Mock object default constructor" );
- }
-
- template<typename T1>
- mock_object( T1 const& arg1 )
- : mock_object_base( arg1 )
- {
- BOOST_ITEST_SCOPE( mock_object::mock_object );
- BOOST_ITEST_EPOINT( "Mock object constructor" );
- }
-
- template<typename T1, typename T2>
- mock_object( T1 const& arg1, T2 const& arg2 )
- : mock_object_base( arg1, arg2 )
- {
- BOOST_ITEST_SCOPE( mock_object::mock_object );
- BOOST_ITEST_EPOINT( "Mock object constructor" );
- }
-
- template<typename T1, typename T2, typename T3>
- mock_object( T1 const& arg1, T2 const& arg2, T3 const& arg3 )
- : mock_object_base( arg1, arg2, arg3 )
- {
- BOOST_ITEST_SCOPE( mock_object::mock_object );
- BOOST_ITEST_EPOINT( "Mock object constructor" );
- }
-
- template<typename T1, typename T2, typename T3, typename T4>
- mock_object( T1 const& arg1, T2 const& arg2, T3 const& arg3, T4 const& arg4 )
- : mock_object_base( arg1, arg2, arg3, arg4 )
- {
- BOOST_ITEST_SCOPE( mock_object::mock_object );
- BOOST_ITEST_EPOINT( "Mock object constructor" );
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5>
- mock_object( T1 const& arg1, T2 const& arg2, T3 const& arg3, T4 const& arg4, T5 const& arg5 )
- : mock_object_base( arg1, arg2, arg3, arg4, arg5 )
- {
- BOOST_ITEST_SCOPE( mock_object::mock_object );
- BOOST_ITEST_EPOINT( "Mock object constructor" );
- }
-
- mock_object( mock_object const& )
- {
- BOOST_ITEST_SCOPE( mock_object::mock_object );
- BOOST_ITEST_EPOINT( "Mock object copy constructor" );
- }
-
- // assignment
- self_type const& operator =( mock_object const& ) const
- {
- MO_OP_IMPL( =, "Copy assignment", prototype() );
- }
-
- template <typename T>
- self_type const& operator =( T const& ) const
- {
- MO_OP_IMPL( =, "Copy assignment", prototype() );
- }
-
- // Unary operators
- MO_UNARY_BOOL_OP( !, "Logical NOT operator" )
- MO_UNARY_OP( &, "Address-of operator" )
- MO_UNARY_OP( ~, "One's complement operator" )
- MO_UNARY_OP( *, "Pointer dereference" )
- MO_UNARY_OP( +, "Unary plus" )
-
- // Increment and Decrement
- MO_UNARY_OP( ++, "Prefix increment" )
- MO_UNARY_OP( --, "Prefix decrement" )
- self_type const& operator ++(int) const
- {
- MO_OP_IMPL( ++, "Postfix increment", prototype() );
- }
- self_type const& operator --(int) const
- {
- MO_OP_IMPL( --, "Postfix decrement", prototype() );
- }
-
- // Bool context convertion
- operator safe_bool() const
- {
- MO_OP_IMPL( safe_bool, "Bool context conversion",
- (BOOST_ITEST_DPOINT() ? 0 : &dummy::nonnull) );
- }
-
- // Function-call operators
- self_type const& operator ()() const
- {
- MO_OP_IMPL( (), "0-arity function-call", prototype() );
- }
- template<typename T1>
- self_type const& operator ()( T1 const& arg1 ) const
- {
- MO_OP_IMPL( (), "1-arity function-call", prototype() );
- }
- template<typename T1, typename T2>
- self_type const& operator ()( T1 const&, T2 const& ) const
- {
- MO_OP_IMPL( (), "2-arity function-call", prototype() );
- }
- template<typename T1, typename T2, typename T3>
- self_type const& operator ()( T1 const&, T2 const&, T3 const& ) const
- {
- MO_OP_IMPL( (), "3-arity function-call", prototype() );
- }
- template<typename T1, typename T2, typename T3, typename T4>
- self_type const& operator ()( T1 const&, T2 const&, T3 const&, T4 const& ) const
- {
- MO_OP_IMPL( (), "4-arity function-call", prototype() );
- }
- template<typename T1, typename T2, typename T3, typename T4, typename T5>
- self_type const& operator ()( T1 const&, T2 const&, T3 const&, T4 const&, T5 const& ) const
- {
- MO_OP_IMPL( (), "5-arity function-call", prototype() );
- }
-
- // Substripting
- template<typename T>
- self_type const& operator []( T const& ) const
- {
- MO_OP_IMPL( [], "Substripting", prototype() );
- }
-
- // Class member access
- self_type const* operator->() const
- {
- MO_OP_IMPL( ->, "Class member access", this );
- }
-};
-
-// !! MO_BINARY_OP( BOOST_PP_COMMA(), "Comma operator" )
-
-MO_BINARY_BOOL_OP( !=, "Inequality" )
-MO_BINARY_OP( %, "Modulus" )
-MO_BINARY_OP( %=, "Modulus/assignment" )
-MO_BINARY_OP( &, "Bitwise AND" )
-MO_BINARY_BOOL_OP( &&, "Logical AND" )
-MO_BINARY_OP( &=, "Bitwise AND/assignment" )
-MO_BINARY_OP( *, "Multiplication" )
-MO_BINARY_OP( *=, "Multiplication/assignment" )
-MO_BINARY_OP( +, "Addition" )
-MO_BINARY_OP( +=, "Addition/assignment" )
-//MO_BINARY_OP( -, "Subtraction" )
-MO_BINARY_OP( -=, "Subtraction/assignment" )
-MO_BINARY_OP( ->*, "Pointer-to-member selection" )
-MO_BINARY_OP( /, "Division" )
-MO_BINARY_OP( /=, "Division/assignment" )
-MO_BINARY_BOOL_OP( <, "Less than" )
-MO_BINARY_OP( <<=, "Left shift/assignment" )
-MO_BINARY_BOOL_OP( <=, "Less than or equal to" )
-MO_BINARY_BOOL_OP( ==, "Equality" )
-MO_BINARY_BOOL_OP( >, "Greater than" )
-MO_BINARY_BOOL_OP( >=, "Greater than or equal to" )
-MO_BINARY_OP( >>=, "Right shift/assignment" )
-MO_BINARY_OP( ^, "Exclusive OR" )
-MO_BINARY_OP( ^=, "Exclusive OR/assignment" )
-MO_BINARY_OP( |, "Bitwise inclusive OR" )
-MO_BINARY_OP( |=, "Bitwise inclusive OR/assignment" )
-MO_BINARY_BOOL_OP( ||, "Logical OR" )
-
-MO_BINARY_OP( <<, "Left shift" )
-MO_BINARY_OP( >>, "Right shift" )
-
-} // namespace itest
-
-} // namespace boost
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // BOOST_TEST_MOCK_OBJECT_HPP_112205GER
diff --git a/boost/test/output/compiler_log_formatter.hpp b/boost/test/output/compiler_log_formatter.hpp
index 23795b99eb..0b3e881179 100644
--- a/boost/test/output/compiler_log_formatter.hpp
+++ b/boost/test/output/compiler_log_formatter.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -24,9 +24,7 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
-
namespace output {
// ************************************************************************** //
@@ -42,27 +40,28 @@ public:
void test_unit_start( std::ostream&, test_unit const& tu );
void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed );
- void test_unit_skipped( std::ostream&, test_unit const& tu );
+ void test_unit_skipped( std::ostream&, test_unit const& tu, const_string reason );
- void log_exception( std::ostream&, log_checkpoint_data const&, execution_exception const& ex );
+ void log_exception_start( std::ostream&, log_checkpoint_data const&, execution_exception const& ex );
+ void log_exception_finish( std::ostream& );
void log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let );
void log_entry_value( std::ostream&, const_string value );
void log_entry_value( std::ostream&, lazy_ostream const& value );
void log_entry_finish( std::ostream& );
+ void entry_context_start( std::ostream&, log_level );
+ void log_entry_context( std::ostream&, const_string );
+ void entry_context_finish( std::ostream& );
+
protected:
virtual void print_prefix( std::ostream&, const_string file, std::size_t line );
};
} // namespace output
-
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_COMPILER_LOG_FORMATTER_HPP_020105GER
diff --git a/boost/test/output/plain_report_formatter.hpp b/boost/test/output/plain_report_formatter.hpp
index 2785e697d6..ff8924f623 100644
--- a/boost/test/output/plain_report_formatter.hpp
+++ b/boost/test/output/plain_report_formatter.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -24,9 +24,7 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
-
namespace output {
// ************************************************************************** //
@@ -50,13 +48,9 @@ private:
};
} // namespace output
-
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_PLAIN_REPORT_FORMATTER_HPP_020105GER
diff --git a/boost/test/output/xml_log_formatter.hpp b/boost/test/output/xml_log_formatter.hpp
index 43b4ce82de..7c05e482e7 100644
--- a/boost/test/output/xml_log_formatter.hpp
+++ b/boost/test/output/xml_log_formatter.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -9,7 +9,7 @@
//
// Version : $Revision$
//
-// Description : contains XML Log formatter definition
+// Description : contains OF_XML Log formatter definition
// ***************************************************************************
#ifndef BOOST_TEST_XML_LOG_FORMATTER_020105GER
@@ -27,9 +27,7 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
-
namespace output {
// ************************************************************************** //
@@ -45,28 +43,30 @@ public:
void test_unit_start( std::ostream&, test_unit const& tu );
void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed );
- void test_unit_skipped( std::ostream&, test_unit const& tu );
+ void test_unit_skipped( std::ostream&, test_unit const& tu, const_string reason );
- void log_exception( std::ostream&, log_checkpoint_data const&, execution_exception const& ex );
+ void log_exception_start( std::ostream&, log_checkpoint_data const&, execution_exception const& ex );
+ void log_exception_finish( std::ostream& );
void log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let );
using unit_test_log_formatter::log_entry_value; // bring base class functions into overload set
void log_entry_value( std::ostream&, const_string value );
void log_entry_finish( std::ostream& );
+ void entry_context_start( std::ostream&, log_level );
+ void log_entry_context( std::ostream&, const_string );
+ void entry_context_finish( std::ostream& );
+
private:
// Data members
const_string m_curr_tag;
+ bool m_value_closed;
};
} // namespace output
-
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_XML_LOG_FORMATTER_020105GER
diff --git a/boost/test/output/xml_report_formatter.hpp b/boost/test/output/xml_report_formatter.hpp
index 0ee81d9457..ab183d02ae 100644
--- a/boost/test/output/xml_report_formatter.hpp
+++ b/boost/test/output/xml_report_formatter.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -9,7 +9,7 @@
//
// Version : $Revision$
//
-// Description : XML report formatter implementation
+// Description : OF_XML report formatter implementation
// ***************************************************************************
#ifndef BOOST_TEST_XML_REPORT_FORMATTER_HPP_020105GER
@@ -24,9 +24,7 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
-
namespace output {
// ************************************************************************** //
@@ -46,13 +44,9 @@ public:
};
} // namespace output
-
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_XML_REPORT_FORMATTER_HPP_020105GER
diff --git a/boost/test/output_test_stream.hpp b/boost/test/output_test_stream.hpp
index 2f2184a933..83f9264635 100644
--- a/boost/test/output_test_stream.hpp
+++ b/boost/test/output_test_stream.hpp
@@ -1,78 +1,14 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2011-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : output_test_stream class definition
+//!@file
+//!@brief Deprecated header.
+//!@deprecated Use boost/test/tools/output_test_stream.hpp instead
// ***************************************************************************
-#ifndef BOOST_TEST_OUTPUT_TEST_STREAM_HPP_012705GER
-#define BOOST_TEST_OUTPUT_TEST_STREAM_HPP_012705GER
-
// Boost.Test
-#include <boost/test/detail/global_typedef.hpp>
-#include <boost/test/utils/wrap_stringstream.hpp>
-#include <boost/test/predicate_result.hpp>
-
-// STL
-#include <cstddef> // for std::size_t
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** output_test_stream ************** //
-// ************************************************************************** //
-
-// class to be used to simplify testing of ostream-based output operations
-
-namespace boost {
-
-namespace test_tools {
-
-class BOOST_TEST_DECL output_test_stream : public wrap_stringstream::wrapped_stream {
- typedef unit_test::const_string const_string;
- typedef predicate_result result_type;
-public:
- // Constructor
- explicit output_test_stream( const_string pattern_file_name = const_string(),
- bool match_or_save = true,
- bool text_or_binary = true );
-
- // Destructor
- ~output_test_stream();
-
- // checking function
- result_type is_empty( bool flush_stream = true );
- result_type check_length( std::size_t length, bool flush_stream = true );
- result_type is_equal( const_string arg_, bool flush_stream = true );
- result_type match_pattern( bool flush_stream = true );
-
- // explicit flush
- void flush();
-
-private:
- // helper functions
- std::size_t length();
- void sync();
-
- struct Impl;
- Impl* m_pimpl;
-};
-
-} // namespace test_tools
-
-} // namespace boost
-
-//____________________________________________________________________________//
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // BOOST_TEST_OUTPUT_TEST_STREAM_HPP_012705GER
+#include <boost/test/tools/output_test_stream.hpp>
diff --git a/boost/test/parameterized_test.hpp b/boost/test/parameterized_test.hpp
index 7654409a8e..4e08567d31 100644
--- a/boost/test/parameterized_test.hpp
+++ b/boost/test/parameterized_test.hpp
@@ -1,15 +1,12 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : generators and helper macros for parameterized tests
+//!@file
+//!@brief generators and helper macros for parameterized tests
// ***************************************************************************
#ifndef BOOST_TEST_PARAMETERIZED_TEST_HPP_021102GER
@@ -17,12 +14,14 @@
// Boost.Test
#include <boost/test/unit_test_suite.hpp>
-#include <boost/test/utils/callback.hpp>
// Boost
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
+#include <boost/bind.hpp>
+#include <boost/function/function1.hpp>
+
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
@@ -30,41 +29,23 @@
#define BOOST_PARAM_TEST_CASE( function, begin, end ) \
boost::unit_test::make_test_case( function, \
BOOST_TEST_STRINGIZE( function ), \
+ __FILE__, __LINE__, \
(begin), (end) ) \
/**/
#define BOOST_PARAM_CLASS_TEST_CASE( function, tc_instance, begin, end ) \
boost::unit_test::make_test_case( function, \
BOOST_TEST_STRINGIZE( function ), \
+ __FILE__, __LINE__, \
(tc_instance), \
(begin), (end) ) \
/**/
namespace boost {
-
namespace unit_test {
-// ************************************************************************** //
-// ************** test_func_with_bound_param ************** //
-// ************************************************************************** //
-
namespace ut_detail {
-template<typename ParamType>
-struct test_func_with_bound_param {
- template<typename T>
- test_func_with_bound_param( callback1<ParamType> test_func, T const& param )
- : m_test_func( test_func )
- , m_param( param )
- {}
-
- void operator()() { m_test_func( m_param ); }
-
-private:
- callback1<ParamType> m_test_func;
- ParamType m_param;
-};
-
// ************************************************************************** //
// ************** param_test_case_generator ************** //
// ************************************************************************** //
@@ -72,12 +53,16 @@ private:
template<typename ParamType, typename ParamIter>
class param_test_case_generator : public test_unit_generator {
public:
- param_test_case_generator( callback1<ParamType> const& test_func,
- const_string tc_name,
- ParamIter par_begin,
- ParamIter par_end )
+ param_test_case_generator( boost::function<void (ParamType)> const& test_func,
+ const_string tc_name,
+ const_string tc_file,
+ std::size_t tc_line,
+ ParamIter par_begin,
+ ParamIter par_end )
: m_test_func( test_func )
, m_tc_name( ut_detail::normalize_test_case_name( tc_name ) )
+ , m_tc_file( tc_file )
+ , m_tc_line( tc_line )
, m_par_begin( par_begin )
, m_par_end( par_end )
{}
@@ -87,8 +72,7 @@ public:
if( m_par_begin == m_par_end )
return (test_unit*)0;
- test_func_with_bound_param<ParamType> bound_test_func( m_test_func, *m_par_begin );
- test_unit* res = new test_case( m_tc_name, bound_test_func );
+ test_unit* res = new test_case( m_tc_name, m_tc_file, m_tc_line, boost::bind( m_test_func, *m_par_begin ) );
++m_par_begin;
@@ -97,8 +81,10 @@ public:
private:
// Data members
- callback1<ParamType> m_test_func;
+ boost::function<void (ParamType)> m_test_func;
std::string m_tc_name;
+ const_string m_tc_file;
+ std::size_t m_tc_line;
mutable ParamIter m_par_begin;
ParamIter m_par_end;
};
@@ -126,12 +112,14 @@ struct user_param_tc_method_invoker {
template<typename ParamType, typename ParamIter>
inline ut_detail::param_test_case_generator<ParamType,ParamIter>
-make_test_case( callback1<ParamType> const& test_func,
- const_string tc_name,
- ParamIter par_begin,
- ParamIter par_end )
+make_test_case( boost::function<void (ParamType)> const& test_func,
+ const_string tc_name,
+ const_string tc_file,
+ std::size_t tc_line,
+ ParamIter par_begin,
+ ParamIter par_end )
{
- return ut_detail::param_test_case_generator<ParamType,ParamIter>( test_func, tc_name, par_begin, par_end );
+ return ut_detail::param_test_case_generator<ParamType,ParamIter>( test_func, tc_name, tc_file, tc_line, par_begin, par_end );
}
//____________________________________________________________________________//
@@ -140,12 +128,14 @@ template<typename ParamType, typename ParamIter>
inline ut_detail::param_test_case_generator<
BOOST_DEDUCED_TYPENAME remove_const<BOOST_DEDUCED_TYPENAME remove_reference<ParamType>::type>::type,ParamIter>
make_test_case( void (*test_func)( ParamType ),
- const_string tc_name,
+ const_string tc_name,
+ const_string tc_file,
+ std::size_t tc_line,
ParamIter par_begin,
ParamIter par_end )
{
typedef BOOST_DEDUCED_TYPENAME remove_const<BOOST_DEDUCED_TYPENAME remove_reference<ParamType>::type>::type param_value_type;
- return ut_detail::param_test_case_generator<param_value_type,ParamIter>( test_func, tc_name, par_begin, par_end );
+ return ut_detail::param_test_case_generator<param_value_type,ParamIter>( test_func, tc_name, tc_file, tc_line, par_begin, par_end );
}
//____________________________________________________________________________//
@@ -155,14 +145,18 @@ inline ut_detail::param_test_case_generator<
BOOST_DEDUCED_TYPENAME remove_const<BOOST_DEDUCED_TYPENAME remove_reference<ParamType>::type>::type,ParamIter>
make_test_case( void (UserTestCase::*test_method )( ParamType ),
const_string tc_name,
+ const_string tc_file,
+ std::size_t tc_line,
boost::shared_ptr<UserTestCase> const& user_test_case,
ParamIter par_begin,
ParamIter par_end )
{
typedef BOOST_DEDUCED_TYPENAME remove_const<BOOST_DEDUCED_TYPENAME remove_reference<ParamType>::type>::type param_value_type;
- return ut_detail::param_test_case_generator<param_value_type,ParamIter>(
- ut_detail::user_param_tc_method_invoker<UserTestCase,ParamType>( user_test_case, test_method ),
+ return ut_detail::param_test_case_generator<param_value_type,ParamIter>(
+ ut_detail::user_param_tc_method_invoker<UserTestCase,ParamType>( user_test_case, test_method ),
tc_name,
+ tc_file,
+ tc_line,
par_begin,
par_end );
}
@@ -170,11 +164,8 @@ make_test_case( void (UserTestCase::*test_method )( ParamType ),
//____________________________________________________________________________//
} // unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_PARAMETERIZED_TEST_HPP_021102GER
diff --git a/boost/test/predicate_result.hpp b/boost/test/predicate_result.hpp
index 8ac18b754b..fb924c7733 100644
--- a/boost/test/predicate_result.hpp
+++ b/boost/test/predicate_result.hpp
@@ -1,88 +1,14 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2011-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : enhanced result for test predicate that include message explaining failure
+/// @file
+/// @brief Deprecated header
+/// @deprecated Use boost/test/tools/assertion_result.hpp instead
// ***************************************************************************
-#ifndef BOOST_TEST_PREDICATE_RESULT_HPP_012705GER
-#define BOOST_TEST_PREDICATE_RESULT_HPP_012705GER
-
// Boost.Test
-#include <boost/test/utils/class_properties.hpp>
-#include <boost/test/utils/wrap_stringstream.hpp>
-#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
-
-// Boost
-#include <boost/shared_ptr.hpp>
-#include <boost/detail/workaround.hpp>
-
-// STL
-#include <cstddef> // for std::size_t
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-//____________________________________________________________________________//
-
-namespace boost {
-
-namespace test_tools {
-
-// ************************************************************************** //
-// ************** predicate_result ************** //
-// ************************************************************************** //
-
-class BOOST_TEST_DECL predicate_result {
- typedef unit_test::const_string const_string;
- struct dummy { void nonnull() {}; };
- typedef void (dummy::*safe_bool)();
-
-public:
- // Constructor
- predicate_result( bool pv_ )
- : p_predicate_value( pv_ )
- {}
-
- template<typename BoolConvertable>
- predicate_result( BoolConvertable const& pv_ ) : p_predicate_value( !!pv_ ) {}
-
- // Access methods
- bool operator!() const { return !p_predicate_value; }
- void operator=( bool pv_ ) { p_predicate_value.value = pv_; }
- operator safe_bool() const { return !!p_predicate_value ? &dummy::nonnull : 0; }
-
- // Public properties
- BOOST_READONLY_PROPERTY( bool, (predicate_result) ) p_predicate_value;
-
- // Access methods
- bool has_empty_message() const { return !m_message; }
- wrap_stringstream& message()
- {
- if( !m_message )
- m_message.reset( new wrap_stringstream );
-
- return *m_message;
- }
- const_string message() const { return !m_message ? const_string() : const_string( m_message->str() ); }
-
-private:
- // Data members
- shared_ptr<wrap_stringstream> m_message;
-};
-
-} // namespace test_tools
-
-} // namespace boost
-
-//____________________________________________________________________________//
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // BOOST_TEST_PREDICATE_RESULT_HPP_012705GER
+#include <boost/test/tools/assertion_result.hpp>
diff --git a/boost/test/prg_exec_monitor.hpp b/boost/test/prg_exec_monitor.hpp
index 6d65f20776..7234833f72 100644
--- a/boost/test/prg_exec_monitor.hpp
+++ b/boost/test/prg_exec_monitor.hpp
@@ -1,15 +1,20 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : Entry point for the end user into the Program Execution Monitor.
+/// @file
+/// @brief Entry point for the end user into the Program Execution Monitor.
+///
+/// Use this header to forward declare function prg_exec_monitor_main and to automatically define a main
+/// function for you. If you prefer to use your own main you are free to do so, but you need to define
+/// BOOST_TEST_NO_MAIN before incuding this header. To initiate your main program body execution you
+/// would use statement like this:
+/// @code ::boost::prg_exec_monitor_main( &my_main, argc, argv ); @endcode
+/// Also this header facilitate auto linking with the Program Execution Monitor library if this feature
+/// is supported
// ***************************************************************************
#ifndef BOOST_PRG_EXEC_MONITOR_HPP_071894GER
@@ -23,7 +28,7 @@
// ************** Auto Linking ************** //
// ************************************************************************** //
-// Automatically link to the correct build variant where possible.
+// Automatically link to the correct build variant where possible.
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_TEST_NO_LIB) && \
!defined(BOOST_TEST_SOURCE) && !defined(BOOST_TEST_INCLUDED)
# define BOOST_LIB_NAME boost_prg_exec_monitor
@@ -41,11 +46,18 @@
// ************** prg_exec_monitor_main ************** //
// ************************************************************************** //
-namespace boost {
+namespace boost {
+/// @brief Wrapper around the main function
+///
+/// Call this routine instead of your own main body implementation directly. This routine impements all the monitoring
+/// functionality. THe monitor behavior is configurable by using the environment variable BOOST_TEST_CATCH_SYSTEM_ERRORS.
+/// If set to string value "no", the monitor will not attempt to catch system errors (signals)
+/// @param[in] cpp_main main function body. Should have the same signature as regular main function
+/// @param[in] argc, argv command line arguments
int BOOST_TEST_DECL prg_exec_monitor_main( int (*cpp_main)( int argc, char* argv[] ), int argc, char* argv[] );
-}
+} // boost
#if defined(BOOST_TEST_DYN_LINK) && !defined(BOOST_TEST_NO_MAIN)
@@ -53,7 +65,8 @@ int BOOST_TEST_DECL prg_exec_monitor_main( int (*cpp_main)( int argc, char* argv
// ************** main function for tests using dll ************** //
// ************************************************************************** //
-int cpp_main( int argc, char* argv[] ); // prototype for user's cpp_main()
+// prototype for user's cpp_main()
+int cpp_main( int argc, char* argv[] );
int BOOST_TEST_CALL_DECL
main( int argc, char* argv[] )
diff --git a/boost/test/progress_monitor.hpp b/boost/test/progress_monitor.hpp
index 5bf69257a8..3d66152297 100644
--- a/boost/test/progress_monitor.hpp
+++ b/boost/test/progress_monitor.hpp
@@ -1,22 +1,19 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : defines simple text based progress monitor
+/// @file
+/// @brief defines simple text based progress monitor
// ***************************************************************************
#ifndef BOOST_TEST_PROGRESS_MONITOR_HPP_020105GER
#define BOOST_TEST_PROGRESS_MONITOR_HPP_020105GER
// Boost.Test
-#include <boost/test/test_observer.hpp>
+#include <boost/test/tree/observer.hpp>
#include <boost/test/utils/trivial_singleton.hpp>
// STL
@@ -27,39 +24,38 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
// ************************************************************************** //
// ************** progress_monitor ************** //
// ************************************************************************** //
+/// This class implements test observer interface and updates test progress as test units finish or get aborted
class BOOST_TEST_DECL progress_monitor_t : public test_observer, public singleton<progress_monitor_t> {
public:
- // test observer interface
- void test_start( counter_t test_cases_amount );
- void test_finish() {}
- void test_aborted();
+ /// @name Test observer interface
+ /// @{
+ virtual void test_start( counter_t test_cases_amount );
+ virtual void test_aborted();
- void test_unit_start( test_unit const& ) {}
- void test_unit_finish( test_unit const&, unsigned long );
- void test_unit_skipped( test_unit const& );
- void test_unit_aborted( test_unit const& ) {}
+ virtual void test_unit_finish( test_unit const&, unsigned long );
+ virtual void test_unit_skipped( test_unit const&, const_string );
- void assertion_result( bool ) {}
- void exception_caught( execution_exception const& ) {}
+ virtual int priority() { return 3; }
+ /// @}
- // configuration
- void set_stream( std::ostream& );
+ /// @name Configuration
+ /// @{
+ void set_stream( std::ostream& );
+ /// @}
private:
- BOOST_TEST_SINGLETON_CONS( progress_monitor_t );
+ BOOST_TEST_SINGLETON_CONS( progress_monitor_t )
}; // progress_monitor_t
BOOST_TEST_SINGLETON_INST( progress_monitor )
} // namespace unit_test
-
} // namespace boost
//____________________________________________________________________________//
diff --git a/boost/test/results_collector.hpp b/boost/test/results_collector.hpp
index e4200b025d..f34bf38345 100644
--- a/boost/test/results_collector.hpp
+++ b/boost/test/results_collector.hpp
@@ -1,23 +1,21 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : defines class unit_test_result that is responsible for
-// gathering test results and presenting this information to end-user
+/// @file results_collector.hpp @brief defines testing result collector components
+///
+/// Defines class results_collector_t that is responsible for
+/// gathering test results and class test_results for presenting this information to end-user
// ***************************************************************************
#ifndef BOOST_TEST_RESULTS_COLLECTOR_HPP_071894GER
#define BOOST_TEST_RESULTS_COLLECTOR_HPP_071894GER
// Boost.Test
-#include <boost/test/test_observer.hpp>
+#include <boost/test/tree/observer.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/fwd_decl.hpp>
@@ -30,41 +28,60 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
+namespace {
+
// ************************************************************************** //
-// ************** first failed assertion debugger hook ************** //
+/// First failed assertion debugger hook
+///
+/// This function is a placeholder where user can set a breakpoint in debugger to catch the
+/// very first assertion failure in each test case
// ************************************************************************** //
-
-namespace {
inline void first_failed_assertion() {}
}
// ************************************************************************** //
-// ************** test_results ************** //
+/// @brief Collection of attributes constituting test unit results
+///
+/// This class is a collection of attributes describing testing results. The atributes presented as public properties on
+/// an instance of the class. In addition summary conclusion methods are presented to generate simple answer to pass/fail question
// ************************************************************************** //
class BOOST_TEST_DECL test_results {
public:
test_results();
+ /// Type representing counter like public property
typedef BOOST_READONLY_PROPERTY( counter_t, (results_collector_t)(test_results)(results_collect_helper) ) counter_prop;
+ /// Type representing boolean like public property
typedef BOOST_READONLY_PROPERTY( bool, (results_collector_t)(test_results)(results_collect_helper) ) bool_prop;
+ /// @name Public properties
counter_prop p_assertions_passed;
counter_prop p_assertions_failed;
+ counter_prop p_warnings_failed;
counter_prop p_expected_failures;
counter_prop p_test_cases_passed;
+ counter_prop p_test_cases_warned;
counter_prop p_test_cases_failed;
counter_prop p_test_cases_skipped;
counter_prop p_test_cases_aborted;
bool_prop p_aborted;
bool_prop p_skipped;
+ /// @}
+
+ /// @name Summary conclusion
- // "conclusion" methods
+ /// Returns true if test unit passed
bool passed() const;
+ /// Produces result code for the test unit execution
+
+ /// This methhod return one of the result codes defined in boost/cstdlib.hpp
+ /// @returns boost::exit_success on success, boost::exit_exception_failure in case test unit was aborted for any reason
+ /// (incuding uncausght exception) and boost::exit_test_failure otherwise
int result_code() const;
+ /// @}
// collection helper
void operator+=( test_results const& );
@@ -73,39 +90,38 @@ public:
};
// ************************************************************************** //
-// ************** results_collector ************** //
+/// This class implements test observer interface to collect the result of test unit execution
// ************************************************************************** //
class BOOST_TEST_DECL results_collector_t : public test_observer, public singleton<results_collector_t> {
public:
- // test_observer interface implementation
- void test_start( counter_t test_cases_amount );
- void test_finish();
- void test_aborted();
- void test_unit_start( test_unit const& );
- void test_unit_finish( test_unit const&, unsigned long elapsed );
- void test_unit_skipped( test_unit const& );
- void test_unit_aborted( test_unit const& );
+ virtual void test_start( counter_t test_cases_amount );
+
+ virtual void test_unit_start( test_unit const& );
+ virtual void test_unit_finish( test_unit const&, unsigned long );
+ virtual void test_unit_skipped( test_unit const&, const_string );
+ virtual void test_unit_aborted( test_unit const& );
+
+ virtual void assertion_result( unit_test::assertion_result );
+ virtual void exception_caught( execution_exception const& );
+
+ virtual int priority() { return 2; }
- void assertion_result( bool passed );
- void exception_caught( execution_exception const& );
+ /// Results access per test unit
- // results access
- test_results const& results( test_unit_id ) const;
+ /// @param[in] tu_id id of a test unit
+ test_results const& results( test_unit_id tu_id ) const;
private:
- BOOST_TEST_SINGLETON_CONS( results_collector_t );
+ BOOST_TEST_SINGLETON_CONS( results_collector_t )
};
BOOST_TEST_SINGLETON_INST( results_collector )
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_RESULTS_COLLECTOR_HPP_071894GER
diff --git a/boost/test/results_reporter.hpp b/boost/test/results_reporter.hpp
index 862c622a68..4c8627e458 100644
--- a/boost/test/results_reporter.hpp
+++ b/boost/test/results_reporter.hpp
@@ -1,16 +1,15 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : defines class unit_test_result that is responsible for
-// gathering test results and presenting this information to end-user
+/// @file
+/// @brief defines testing result reporter interfaces
+///
+/// This file defines interfaces that are responsible for results reporting. Interface is presented in a form of
+/// free standing function implemented in namespace result_reporter
// ***************************************************************************
#ifndef BOOST_TEST_RESULTS_REPORTER_HPP_021205GER
@@ -28,13 +27,17 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
+/// Namespace for results reporter interfaces
namespace results_reporter {
// ************************************************************************** //
-// ************** formatter interface ************** //
+/// @brief Results report formatter interface
+///
+/// This is abstract interface for the report formatter used by results reporter routines.
+/// You can define a custom formatter by implementing this interface and setting the formatter using set_format function.
+/// This is usually done during test module initialization
// ************************************************************************** //
class BOOST_TEST_DECL format {
@@ -52,22 +55,57 @@ public:
};
// ************************************************************************** //
-// ************** report configuration ************** //
+/// @name report configuration
// ************************************************************************** //
-BOOST_TEST_DECL void set_level( report_level );
+/// Sets reporting level
+
+/// There are only four possible levels for results report:
+/// - confirmation report (boost::unit_test::CONFIRMATION_REPORT). This report level only produces short confirmation
+/// message about test module pass/fail status
+/// - short report (boost::unit_test::SHORT_REPORT). This report level produces short summary report for failed/passed
+/// assertions and test units.
+/// - detailed report (boost::unit_test::DETAILED_REPORT). This report level produces detailed report per test unit for
+/// passed/failed assertions and uncaught exceptions
+/// - no report (boost::unit_test::NO_REPORT). This report level produces no results report. This is used for test modules
+/// running as part of some kind of continues integration framework
+/// @param[in] l report level
+BOOST_TEST_DECL void set_level( report_level l );
+
+/// Sets output stream for results reporting
+
+/// By default std::cerr is used. Use this function to set a different stream. The framework
+/// refers to the stream by reference, so you need to make sure the stream object lifetime exceeds the testing main scope.
BOOST_TEST_DECL void set_stream( std::ostream& );
-BOOST_TEST_DECL void set_format( output_format );
-BOOST_TEST_DECL void set_format( results_reporter::format* );
+/// Sets one of the predefined formats
+
+/// The framework implements two results report formats:
+/// - plain human readable format (boost::unit_test::OF_CLF)
+/// - XML format (boost::unit_test::OF_XML)
+/// @param[in] of one of the presefined enumeration values for output formats
+BOOST_TEST_DECL void set_format( output_format of );
+
+/// Sets custom report formatter
+
+/// The framework takes ownership of the pointer passed as an argument. So this should be a pointer to
+/// a heap allocated object
+/// @param[in] f pointer to heap allocated instance of custom report formatter class
+BOOST_TEST_DECL void set_format( results_reporter::format* f );
+
+/// @brief Access to configured results reporter stream
+///
+/// Use this stream to report additional information abut test module execution
BOOST_TEST_DECL std::ostream& get_stream();
+/// @}
+
// ************************************************************************** //
// ************** report initiation ************** //
// ************************************************************************** //
BOOST_TEST_DECL void make_report( report_level l = INV_REPORT_LEVEL, test_unit_id = INV_TEST_UNIT_ID );
-inline void confirmation_report( test_unit_id id = INV_TEST_UNIT_ID )
+inline void confirmation_report( test_unit_id id = INV_TEST_UNIT_ID )
{ make_report( CONFIRMATION_REPORT, id ); }
inline void short_report( test_unit_id id = INV_TEST_UNIT_ID )
{ make_report( SHORT_REPORT, id ); }
@@ -75,13 +113,9 @@ inline void detailed_report( test_unit_id id = INV_TEST_UNIT_ID )
{ make_report( DETAILED_REPORT, id ); }
} // namespace results_reporter
-
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_RESULTS_REPORTER_HPP_021205GER
diff --git a/boost/test/test_case_template.hpp b/boost/test/test_case_template.hpp
index 8c64f1ce00..77adf6cc8c 100644
--- a/boost/test/test_case_template.hpp
+++ b/boost/test/test_case_template.hpp
@@ -1,15 +1,13 @@
-// (C) Copyright Gennadiy Rozental 2003-2008.
+// (C) Copyright Gennadiy Rozental 2003-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : deprecated
+/// @file
+/// @brief Deprecated header.
+/// @deprecated Use @c boost/test/unit_test.hpp instead
// ***************************************************************************
#include <boost/test/unit_test.hpp>
diff --git a/boost/test/test_exec_monitor.hpp b/boost/test/test_exec_monitor.hpp
index 13802ed1d5..af81aa0296 100644
--- a/boost/test/test_exec_monitor.hpp
+++ b/boost/test/test_exec_monitor.hpp
@@ -1,15 +1,32 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : Entry point for the end user into the Test Execution Monitor.
+/// @file
+/// @brief Deprecated implementation of Test Execution Monitor
+///
+/// To convert to Unit Test Framework simply rewrite:
+/// @code
+/// #include <boost/test/test_exec_monitor.hpp>
+///
+/// int test_main( int, char *[] )
+/// {
+/// ...
+/// }
+/// @endcode
+/// as
+/// @code
+/// #include <boost/test/unit_test.hpp>
+///
+/// BOOST_AUTO_TEST_CASE(test_main)
+/// {
+/// ...
+/// }
+/// @endcode
+/// and link with boost_unit_test_framework library *instead of* boost_test_exec_monitor
// ***************************************************************************
#ifndef BOOST_TEST_EXEC_MONITOR_HPP_071894GER
@@ -24,7 +41,7 @@
// ************** Auto Linking ************** //
// ************************************************************************** //
-// Automatically link to the correct build variant where possible.
+// Automatically link to the correct build variant where possible.
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_TEST_NO_LIB) && \
!defined(BOOST_TEST_SOURCE) && !defined(BOOST_TEST_INCLUDED)
diff --git a/boost/test/test_tools.hpp b/boost/test/test_tools.hpp
index 2800ac0616..dea2b20fa2 100644
--- a/boost/test/test_tools.hpp
+++ b/boost/test/test_tools.hpp
@@ -1,719 +1,61 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : contains definition for all test tools in test toolbox
+/// @file
+/// @brief test tools compatibility header
+///
+/// This file is used to select the test tools implementation and includes all the necessary headers
// ***************************************************************************
-#ifndef BOOST_TEST_TEST_TOOLS_HPP_012705GER
-#define BOOST_TEST_TEST_TOOLS_HPP_012705GER
-
-// Boost.Test
-#include <boost/test/predicate_result.hpp>
-#include <boost/test/unit_test_log.hpp>
-#include <boost/test/floating_point_comparison.hpp>
-
-#include <boost/test/detail/config.hpp>
-#include <boost/test/detail/global_typedef.hpp>
-#include <boost/test/detail/workaround.hpp>
-
-#include <boost/test/utils/wrap_stringstream.hpp>
-#include <boost/test/utils/basic_cstring/io.hpp>
-#include <boost/test/utils/lazy_ostream.hpp>
-
-// Boost
-#include <boost/preprocessor/seq/for_each.hpp>
-#include <boost/preprocessor/seq/size.hpp>
-#include <boost/preprocessor/seq/enum.hpp>
-#include <boost/preprocessor/repetition/repeat.hpp>
-#include <boost/preprocessor/punctuation/comma_if.hpp>
-#include <boost/preprocessor/arithmetic/add.hpp>
-
-#include <boost/limits.hpp>
-
-#include <boost/type_traits/is_array.hpp>
-#include <boost/type_traits/is_function.hpp>
-#include <boost/type_traits/is_abstract.hpp>
-
-#include <boost/mpl/or.hpp>
-
-// STL
-#include <cstddef> // for std::size_t
-#include <iosfwd>
-#include <ios> // for std::boolalpha
-#include <climits> // for CHAR_BIT
-
-#ifdef BOOST_MSVC
-# pragma warning(disable: 4127) // conditional expression is constant
-#endif
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** TOOL BOX ************** //
-// ************************************************************************** //
-
-// In macros below following argument abbreviations are used:
-// P - predicate
-// M - message
-// S - statement
-// E - exception
-// L - left argument
-// R - right argument
-// TL - tool level
-// CT - check type
-// ARGS - arguments list
-
-#define BOOST_TEST_TOOL_IMPL( func, P, check_descr, TL, CT ) \
- ::boost::test_tools::tt_detail::func( \
- P, \
- ::boost::unit_test::lazy_ostream::instance() << check_descr, \
- BOOST_TEST_L(__FILE__), \
- static_cast<std::size_t>(__LINE__), \
- ::boost::test_tools::tt_detail::TL, \
- ::boost::test_tools::tt_detail::CT \
-/**/
-
-//____________________________________________________________________________//
-
-#define BOOST_CHECK_IMPL( P, check_descr, TL, CT ) \
-do { \
- BOOST_TEST_PASSPOINT(); \
- BOOST_TEST_TOOL_IMPL( check_impl, P, check_descr, TL, CT ), 0 );\
-} while( ::boost::test_tools::dummy_cond ) \
-/**/
-
-//____________________________________________________________________________//
-
-#define BOOST_TEST_PASS_ARG_INFO( r, data, arg ) , arg, BOOST_STRINGIZE( arg )
-
-#define BOOST_CHECK_WITH_ARGS_IMPL( P, check_descr, TL, CT, ARGS ) \
-do { \
- BOOST_TEST_PASSPOINT(); \
- BOOST_TEST_TOOL_IMPL( check_frwd, P, check_descr, TL, CT ) \
- BOOST_PP_SEQ_FOR_EACH( BOOST_TEST_PASS_ARG_INFO, '_', ARGS ) ); \
-} while( ::boost::test_tools::dummy_cond ) \
-/**/
-
-//____________________________________________________________________________//
-
-#define BOOST_WARN( P ) BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), WARN, CHECK_PRED )
-#define BOOST_CHECK( P ) BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), CHECK, CHECK_PRED )
-#define BOOST_REQUIRE( P ) BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), REQUIRE, CHECK_PRED )
-
-//____________________________________________________________________________//
-
-#define BOOST_WARN_MESSAGE( P, M ) BOOST_CHECK_IMPL( (P), M, WARN, CHECK_MSG )
-#define BOOST_CHECK_MESSAGE( P, M ) BOOST_CHECK_IMPL( (P), M, CHECK, CHECK_MSG )
-#define BOOST_REQUIRE_MESSAGE( P, M ) BOOST_CHECK_IMPL( (P), M, REQUIRE, CHECK_MSG )
-
-//____________________________________________________________________________//
-
-#define BOOST_ERROR( M ) BOOST_CHECK_MESSAGE( false, M )
-#define BOOST_FAIL( M ) BOOST_REQUIRE_MESSAGE( false, M )
-
-//____________________________________________________________________________//
-
-#define BOOST_CHECK_THROW_IMPL( S, E, P, prefix, TL ) \
- try { \
- BOOST_TEST_PASSPOINT(); \
- S; \
- BOOST_CHECK_IMPL( false, "exception " BOOST_STRINGIZE( E ) " is expected", TL, CHECK_MSG ); } \
- catch( E const& ex ) { \
- ::boost::unit_test::ut_detail::ignore_unused_variable_warning( ex ); \
- BOOST_CHECK_IMPL( P, prefix BOOST_STRINGIZE( E ) " is caught", TL, CHECK_MSG ); \
- } \
-/**/
-
-//____________________________________________________________________________//
-
-#define BOOST_WARN_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", WARN )
-#define BOOST_CHECK_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", CHECK )
-#define BOOST_REQUIRE_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", REQUIRE )
-
-//____________________________________________________________________________//
-
-#define BOOST_WARN_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", WARN )
-#define BOOST_CHECK_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", CHECK )
-#define BOOST_REQUIRE_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", REQUIRE )
-
-//____________________________________________________________________________//
-
-#define BOOST_CHECK_NO_THROW_IMPL( S, TL ) \
- try { \
- S; \
- BOOST_CHECK_IMPL( true, "no exceptions thrown by " BOOST_STRINGIZE( S ), TL, CHECK_MSG ); } \
- catch( ... ) { \
- BOOST_CHECK_IMPL( false, "exception thrown by " BOOST_STRINGIZE( S ), TL, CHECK_MSG ); \
- } \
-/**/
-
-#define BOOST_WARN_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, WARN )
-#define BOOST_CHECK_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, CHECK )
-#define BOOST_REQUIRE_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, REQUIRE )
-
-//____________________________________________________________________________//
-
-#define BOOST_WARN_EQUAL( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", WARN, CHECK_EQUAL, (L)(R) )
-#define BOOST_CHECK_EQUAL( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", CHECK, CHECK_EQUAL, (L)(R) )
-#define BOOST_REQUIRE_EQUAL( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", REQUIRE, CHECK_EQUAL, (L)(R) )
-
-//____________________________________________________________________________//
-
-#define BOOST_WARN_NE( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ne_impl(), "", WARN, CHECK_NE, (L)(R) )
-#define BOOST_CHECK_NE( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ne_impl(), "", CHECK, CHECK_NE, (L)(R) )
-#define BOOST_REQUIRE_NE( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ne_impl(), "", REQUIRE, CHECK_NE, (L)(R) )
-
-//____________________________________________________________________________//
-
-#define BOOST_WARN_LT( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::lt_impl(), "", WARN, CHECK_LT, (L)(R) )
-#define BOOST_CHECK_LT( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::lt_impl(), "", CHECK, CHECK_LT, (L)(R) )
-#define BOOST_REQUIRE_LT( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::lt_impl(), "", REQUIRE, CHECK_LT, (L)(R) )
-
-//____________________________________________________________________________//
-
-#define BOOST_WARN_LE( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::le_impl(), "", WARN, CHECK_LE, (L)(R) )
-#define BOOST_CHECK_LE( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::le_impl(), "", CHECK, CHECK_LE, (L)(R) )
-#define BOOST_REQUIRE_LE( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::le_impl(), "", REQUIRE, CHECK_LE, (L)(R) )
-
-//____________________________________________________________________________//
-
-#define BOOST_WARN_GT( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::gt_impl(), "", WARN, CHECK_GT, (L)(R) )
-#define BOOST_CHECK_GT( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::gt_impl(), "", CHECK, CHECK_GT, (L)(R) )
-#define BOOST_REQUIRE_GT( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::gt_impl(), "", REQUIRE, CHECK_GT, (L)(R) )
-
-//____________________________________________________________________________//
-
-#define BOOST_WARN_GE( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ge_impl(), "", WARN, CHECK_GE, (L)(R) )
-#define BOOST_CHECK_GE( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ge_impl(), "", CHECK, CHECK_GE, (L)(R) )
-#define BOOST_REQUIRE_GE( L, R ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ge_impl(), "", REQUIRE, CHECK_GE, (L)(R) )
-
-//____________________________________________________________________________//
-
-#define BOOST_WARN_CLOSE( L, R, T ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", WARN, CHECK_CLOSE, \
- (L)(R)(::boost::test_tools::percent_tolerance(T)) )
-#define BOOST_CHECK_CLOSE( L, R, T ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", CHECK, CHECK_CLOSE, \
- (L)(R)(::boost::test_tools::percent_tolerance(T)) )
-#define BOOST_REQUIRE_CLOSE( L, R, T ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", REQUIRE, CHECK_CLOSE, \
- (L)(R)(::boost::test_tools::percent_tolerance(T)) )
-
-//____________________________________________________________________________//
-
-#define BOOST_WARN_CLOSE_FRACTION( L, R, T ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", WARN, CHECK_CLOSE_FRACTION, \
- (L)(R)(::boost::test_tools::fraction_tolerance(T)) )
-#define BOOST_CHECK_CLOSE_FRACTION( L, R, T ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", CHECK, CHECK_CLOSE_FRACTION, \
- (L)(R)(::boost::test_tools::fraction_tolerance(T)) )
-#define BOOST_REQUIRE_CLOSE_FRACTION( L, R, T ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", REQUIRE, CHECK_CLOSE_FRACTION, \
- (L)(R)(::boost::test_tools::fraction_tolerance(T)) )
-
-//____________________________________________________________________________//
-
-#define BOOST_WARN_SMALL( FPV, T ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", WARN, CHECK_SMALL, (FPV)(T) )
-#define BOOST_CHECK_SMALL( FPV, T ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", CHECK, CHECK_SMALL, (FPV)(T) )
-#define BOOST_REQUIRE_SMALL( FPV, T ) \
- BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", REQUIRE, CHECK_SMALL, (FPV)(T) )
-
-//____________________________________________________________________________//
-
-#define BOOST_WARN_PREDICATE( P, ARGS ) \
- BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), WARN, CHECK_PRED_WITH_ARGS, ARGS )
-#define BOOST_CHECK_PREDICATE( P, ARGS ) \
- BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), CHECK, CHECK_PRED_WITH_ARGS, ARGS )
-#define BOOST_REQUIRE_PREDICATE( P, ARGS ) \
- BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), REQUIRE, CHECK_PRED_WITH_ARGS, ARGS )
-
-//____________________________________________________________________________//
-
-#define BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, TL ) \
- BOOST_TEST_TOOL_IMPL( check_impl, ::boost::test_tools::tt_detail::equal_coll_impl( \
- (L_begin), (L_end), (R_begin), (R_end) ), "", TL, CHECK_EQUAL_COLL ), \
- 4, \
- BOOST_STRINGIZE( L_begin ), BOOST_STRINGIZE( L_end ), \
- BOOST_STRINGIZE( R_begin ), BOOST_STRINGIZE( R_end ) ) \
-/**/
-
-#define BOOST_WARN_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
- BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, WARN )
-#define BOOST_CHECK_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
- BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, CHECK )
-#define BOOST_REQUIRE_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
- BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, REQUIRE )
-
-//____________________________________________________________________________//
-
-#define BOOST_BITWISE_EQUAL_IMPL( L, R, TL ) \
- BOOST_TEST_TOOL_IMPL( check_impl, \
- ::boost::test_tools::tt_detail::bitwise_equal_impl( (L), (R) ), \
- "", TL, CHECK_BITWISE_EQUAL ), \
- 2, BOOST_STRINGIZE( L ), BOOST_STRINGIZE( R ) ) \
-/**/
-
-#define BOOST_WARN_BITWISE_EQUAL( L, R ) BOOST_BITWISE_EQUAL_IMPL( L, R, WARN )
-#define BOOST_CHECK_BITWISE_EQUAL( L, R ) BOOST_BITWISE_EQUAL_IMPL( L, R, CHECK )
-#define BOOST_REQUIRE_BITWISE_EQUAL( L, R ) BOOST_BITWISE_EQUAL_IMPL( L, R, REQUIRE )
-
-//____________________________________________________________________________//
-
-#define BOOST_IS_DEFINED( symb ) ::boost::test_tools::tt_detail::is_defined_impl( #symb, BOOST_STRINGIZE(= symb) )
-
-//____________________________________________________________________________//
-
-// ***************************** //
-// deprecated interface
-
-#define BOOST_BITWISE_EQUAL( L, R ) BOOST_CHECK_BITWISE_EQUAL( L, R )
-#define BOOST_MESSAGE( M ) BOOST_TEST_MESSAGE( M )
-#define BOOST_CHECKPOINT( M ) BOOST_TEST_CHECKPOINT( M )
-
-namespace boost {
-
-namespace test_tools {
-
-typedef unit_test::const_string const_string;
-
-namespace { bool dummy_cond = false; }
-
-// ************************************************************************** //
-// ************** print_log_value ************** //
-// ************************************************************************** //
-
-template<typename T>
-struct print_log_value {
- void operator()( std::ostream& ostr, T const& t )
- {
- // avoid warning: 'boost::test_tools::<unnamed>::dummy_cond' defined but not used
- if (::boost::test_tools::dummy_cond) {}
-
- typedef typename mpl::or_<is_array<T>,is_function<T>,is_abstract<T> >::type cant_use_nl;
-
- set_precision( ostr, cant_use_nl() );
-
- ostr << t; // by default print the value
- }
+#ifndef BOOST_TEST_TOOLS_HPP_111812GER
+#define BOOST_TEST_TOOLS_HPP_111812GER
- void set_precision( std::ostream& ostr, mpl::false_ )
- {
- if( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 2 )
- ostr.precision( 2 + std::numeric_limits<T>::digits * 301/1000 );
- }
+#include <boost/config.hpp>
+#include <boost/preprocessor/config/config.hpp>
- void set_precision( std::ostream&, mpl::true_ ) {}
-};
-
-//____________________________________________________________________________//
-
-#define BOOST_TEST_DONT_PRINT_LOG_VALUE( the_type ) \
-namespace boost { namespace test_tools { \
-template<> \
-struct print_log_value<the_type > { \
- void operator()( std::ostream&, the_type const& ) {} \
-}; \
-}} \
-/**/
-
-//____________________________________________________________________________//
-
-#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
-template<typename T, std::size_t N >
-struct print_log_value< T[N] > {
- void operator()( std::ostream& ostr, T const* t )
- {
- ostr << t;
- }
-};
+#if !BOOST_PP_VARIADICS || ((__cplusplus >= 201103L) && defined(BOOST_NO_CXX11_VARIADIC_MACROS))
+#define BOOST_TEST_NO_VARIADIC
#endif
-//____________________________________________________________________________//
-
-template<>
-struct BOOST_TEST_DECL print_log_value<bool> {
- void operator()( std::ostream& ostr, bool t )
- {
- ostr << std::boolalpha << t;
- }
-};
-
-//____________________________________________________________________________//
-
-template<>
-struct BOOST_TEST_DECL print_log_value<char> {
- void operator()( std::ostream& ostr, char t );
-};
-
-//____________________________________________________________________________//
-
-template<>
-struct BOOST_TEST_DECL print_log_value<unsigned char> {
- void operator()( std::ostream& ostr, unsigned char t );
-};
-
-//____________________________________________________________________________//
-
-template<>
-struct BOOST_TEST_DECL print_log_value<char const*> {
- void operator()( std::ostream& ostr, char const* t );
-};
-
-//____________________________________________________________________________//
-
-template<>
-struct BOOST_TEST_DECL print_log_value<wchar_t const*> {
- void operator()( std::ostream& ostr, wchar_t const* t );
-};
-
-//____________________________________________________________________________//
-
-namespace tt_detail {
-
-// ************************************************************************** //
-// ************** tools classification ************** //
-// ************************************************************************** //
-
-enum check_type {
- CHECK_PRED,
- CHECK_MSG,
- CHECK_EQUAL,
- CHECK_NE,
- CHECK_LT,
- CHECK_LE,
- CHECK_GT,
- CHECK_GE,
- CHECK_CLOSE,
- CHECK_CLOSE_FRACTION,
- CHECK_SMALL,
- CHECK_BITWISE_EQUAL,
- CHECK_PRED_WITH_ARGS,
- CHECK_EQUAL_COLL
-};
-
-enum tool_level {
- WARN, CHECK, REQUIRE, PASS
-};
-
-// ************************************************************************** //
-// ************** print_helper ************** //
-// ************************************************************************** //
-// Adds level of indirection to the output operation, allowing us to customize
-// it for types that do not support operator << directly or for any other reason
-
-template<typename T>
-struct print_helper_t {
- explicit print_helper_t( T const& t ) : m_t( t ) {}
-
- T const& m_t;
-};
-
-//____________________________________________________________________________//
-
-#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
-// Borland suffers premature pointer decay passing arrays by reference
-template<typename T, std::size_t N >
-struct print_helper_t< T[N] > {
- explicit print_helper_t( T const * t ) : m_t( t ) {}
+// Boost.Test
+// #define BOOST_TEST_NO_OLD_TOOLS
- T const * m_t;
-};
+#if defined(BOOST_TEST_NO_VARIADIC)
+# define BOOST_TEST_NO_NEW_TOOLS
#endif
-//____________________________________________________________________________//
-
-template<typename T>
-inline print_helper_t<T> print_helper( T const& t )
-{
- return print_helper_t<T>( t );
-}
-
-//____________________________________________________________________________//
-
-template<typename T>
-inline std::ostream&
-operator<<( std::ostream& ostr, print_helper_t<T> const& ph )
-{
- print_log_value<T>()( ostr, ph.m_t );
-
- return ostr;
-}
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** TOOL BOX Implementation ************** //
-// ************************************************************************** //
+// #define BOOST_TEST_TOOLS_UNDER_DEBUGGER
+// #define BOOST_TEST_TOOLS_DEBUGGABLE
-BOOST_TEST_DECL
-bool check_impl( predicate_result const& pr, ::boost::unit_test::lazy_ostream const& check_descr,
- const_string file_name, std::size_t line_num,
- tool_level tl, check_type ct,
- std::size_t num_args, ... );
+#include <boost/test/tools/context.hpp>
-//____________________________________________________________________________//
+#ifndef BOOST_TEST_NO_OLD_TOOLS
+# include <boost/test/tools/old/interface.hpp>
+# include <boost/test/tools/old/impl.hpp>
-#define TEMPL_PARAMS( z, m, dummy ) , typename BOOST_JOIN( Arg, m )
-#define FUNC_PARAMS( z, m, dummy ) \
- , BOOST_JOIN( Arg, m ) const& BOOST_JOIN( arg, m ) \
- , char const* BOOST_JOIN( BOOST_JOIN( arg, m ), _descr ) \
-/**/
-
-#define PRED_PARAMS( z, m, dummy ) BOOST_PP_COMMA_IF( m ) BOOST_JOIN( arg, m )
-
-#define ARG_INFO( z, m, dummy ) \
- , BOOST_JOIN( BOOST_JOIN( arg, m ), _descr ) \
- , &static_cast<const unit_test::lazy_ostream&>(unit_test::lazy_ostream::instance() \
- << ::boost::test_tools::tt_detail::print_helper( BOOST_JOIN( arg, m ) )) \
-/**/
-
-#define IMPL_FRWD( z, n, dummy ) \
-template<typename Pred \
- BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), TEMPL_PARAMS, _ )> \
-inline bool \
-check_frwd( Pred P, unit_test::lazy_ostream const& check_descr, \
- const_string file_name, std::size_t line_num, \
- tool_level tl, check_type ct \
- BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), FUNC_PARAMS, _ ) \
-) \
-{ \
- return \
- check_impl( P( BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), PRED_PARAMS, _ ) ), \
- check_descr, file_name, line_num, tl, ct, \
- BOOST_PP_ADD( n, 1 ) \
- BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), ARG_INFO, _ ) \
- ); \
-} \
-/**/
-
-#ifndef BOOST_TEST_MAX_PREDICATE_ARITY
-#define BOOST_TEST_MAX_PREDICATE_ARITY 5
+# include <boost/test/tools/detail/print_helper.hpp>
#endif
-BOOST_PP_REPEAT( BOOST_TEST_MAX_PREDICATE_ARITY, IMPL_FRWD, _ )
-
-#undef TEMPL_PARAMS
-#undef FUNC_PARAMS
-#undef PRED_INFO
-#undef ARG_INFO
-#undef IMPL_FRWD
-
-//____________________________________________________________________________//
-
-template <class Left, class Right>
-predicate_result equal_impl( Left const& left, Right const& right )
-{
- return left == right;
-}
-
-//____________________________________________________________________________//
-
-predicate_result BOOST_TEST_DECL equal_impl( char const* left, char const* right );
-inline predicate_result equal_impl( char* left, char const* right ) { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }
-inline predicate_result equal_impl( char const* left, char* right ) { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }
-inline predicate_result equal_impl( char* left, char* right ) { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }
-
-#if !defined( BOOST_NO_CWCHAR )
-predicate_result BOOST_TEST_DECL equal_impl( wchar_t const* left, wchar_t const* right );
-inline predicate_result equal_impl( wchar_t* left, wchar_t const* right ) { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
-inline predicate_result equal_impl( wchar_t const* left, wchar_t* right ) { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
-inline predicate_result equal_impl( wchar_t* left, wchar_t* right ) { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
+#ifndef BOOST_TEST_NO_NEW_TOOLS
+# include <boost/test/tools/interface.hpp>
+# include <boost/test/tools/assertion.hpp>
+# include <boost/test/tools/fpc_op.hpp>
+# include <boost/test/tools/collection_comparison_op.hpp>
+# include <boost/test/tools/cstring_comparison_op.hpp>
+
+# include <boost/test/tools/detail/fwd.hpp>
+# include <boost/test/tools/detail/print_helper.hpp>
+# include <boost/test/tools/detail/it_pair.hpp>
+
+# include <boost/test/tools/detail/bitwise_manip.hpp>
+# include <boost/test/tools/detail/tolerance_manip.hpp>
+# include <boost/test/tools/detail/per_element_manip.hpp>
+# include <boost/test/tools/detail/lexicographic_manip.hpp>
#endif
-//____________________________________________________________________________//
-
-struct equal_impl_frwd {
- template <typename Left, typename Right>
- inline predicate_result
- call_impl( Left const& left, Right const& right, mpl::false_ ) const
- {
- return equal_impl( left, right );
- }
-
- template <typename Left, typename Right>
- inline predicate_result
- call_impl( Left const& left, Right const& right, mpl::true_ ) const
- {
- return (*this)( right, &left[0] );
- }
-
- template <typename Left, typename Right>
- inline predicate_result
- operator()( Left const& left, Right const& right ) const
- {
- typedef typename is_array<Left>::type left_is_array;
- return call_impl( left, right, left_is_array() );
- }
-};
-
-//____________________________________________________________________________//
-
-struct ne_impl {
- template <class Left, class Right>
- predicate_result operator()( Left const& left, Right const& right )
- {
- return !equal_impl_frwd()( left, right );
- }
-};
-
-//____________________________________________________________________________//
-
-struct lt_impl {
- template <class Left, class Right>
- predicate_result operator()( Left const& left, Right const& right )
- {
- return left < right;
- }
-};
-
-//____________________________________________________________________________//
-
-struct le_impl {
- template <class Left, class Right>
- predicate_result operator()( Left const& left, Right const& right )
- {
- return left <= right;
- }
-};
-
-//____________________________________________________________________________//
-
-struct gt_impl {
- template <class Left, class Right>
- predicate_result operator()( Left const& left, Right const& right )
- {
- return left > right;
- }
-};
-
-//____________________________________________________________________________//
-
-struct ge_impl {
- template <class Left, class Right>
- predicate_result operator()( Left const& left, Right const& right )
- {
- return left >= right;
- }
-};
-
-//____________________________________________________________________________//
-
-template <typename Left, typename Right>
-inline predicate_result
-equal_coll_impl( Left left_begin, Left left_end, Right right_begin, Right right_end )
-{
- predicate_result res( true );
- std::size_t pos = 0;
-
- for( ; left_begin != left_end && right_begin != right_end; ++left_begin, ++right_begin, ++pos ) {
- if( *left_begin != *right_begin ) {
- res = false;
- res.message() << "\nMismatch in a position " << pos << ": " << *left_begin << " != " << *right_begin;
- }
- }
-
- if( left_begin != left_end ) {
- std::size_t r_size = pos;
- while( left_begin != left_end ) {
- ++pos;
- ++left_begin;
- }
-
- res = false;
- res.message() << "\nCollections size mismatch: " << pos << " != " << r_size;
- }
-
- if( right_begin != right_end ) {
- std::size_t l_size = pos;
- while( right_begin != right_end ) {
- ++pos;
- ++right_begin;
- }
-
- res = false;
- res.message() << "\nCollections size mismatch: " << l_size << " != " << pos;
- }
-
- return res;
-}
-
-//____________________________________________________________________________//
-
-template <class Left, class Right>
-inline predicate_result
-bitwise_equal_impl( Left const& left, Right const& right )
-{
- predicate_result res( true );
-
- std::size_t left_bit_size = sizeof(Left)*CHAR_BIT;
- std::size_t right_bit_size = sizeof(Right)*CHAR_BIT;
-
- static Left const leftOne( 1 );
- static Right const rightOne( 1 );
-
- std::size_t total_bits = left_bit_size < right_bit_size ? left_bit_size : right_bit_size;
-
- for( std::size_t counter = 0; counter < total_bits; ++counter ) {
- if( ( left & ( leftOne << counter ) ) != ( right & ( rightOne << counter ) ) ) {
- res = false;
- res.message() << "\nMismatch in a position " << counter;
- }
- }
-
- if( left_bit_size != right_bit_size ) {
- res = false;
- res.message() << "\nOperands bit sizes mismatch: " << left_bit_size << " != " << right_bit_size;
- }
-
- return res;
-}
-
-//____________________________________________________________________________//
-
-bool BOOST_TEST_DECL is_defined_impl( const_string symbol_name, const_string symbol_value );
-
-//____________________________________________________________________________//
-
-} // namespace tt_detail
-
-} // namespace test_tools
-
-namespace test_toolbox = test_tools;
-
-} // namespace boost
-
-//____________________________________________________________________________//
-
-#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_TEST_TEST_TOOLS_HPP_012705GER
+#endif // BOOST_TEST_TOOLS_HPP_111812GER
diff --git a/boost/test/tools/assertion.hpp b/boost/test/tools/assertion.hpp
new file mode 100644
index 0000000000..b46b6760e7
--- /dev/null
+++ b/boost/test/tools/assertion.hpp
@@ -0,0 +1,407 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+//!@file
+//!@brief Defines framework for automated assertion construction
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
+#define BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
+
+// Boost.Test
+#include <boost/test/tools/assertion_result.hpp>
+#include <boost/test/tools/detail/print_helper.hpp>
+#include <boost/test/tools/detail/fwd.hpp>
+
+// Boost
+#include <boost/type.hpp>
+#include <boost/type_traits/decay.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/utility/declval.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+// STL
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+#include <utility>
+#endif
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+namespace assertion {
+
+// ************************************************************************** //
+// ************** assertion::operators ************** //
+// ************************************************************************** //
+// precedence 4: ->*, .*
+// precedence 5: *, /, %
+// precedence 6: +, -
+// precedence 7: << , >>
+// precedence 8: <, <=, > and >=
+// precedence 9: == and !=
+// precedence 10: bitwise AND
+// precedence 11: bitwise XOR
+// precedence 12: bitwise OR
+// precedence 13: logical AND
+// disabled
+// precedence 14: logical OR
+// disabled
+// precedence 15: ternary conditional
+// disabled
+// precedence 16: = and OP= operators
+// precedence 17: throw operator
+// not supported
+// precedence 18: comma
+// not supported
+
+namespace op {
+
+#define BOOST_TEST_FOR_EACH_COMP_OP(action) \
+ action( < , LT, >= ) \
+ action( <=, LE, > ) \
+ action( > , GT, <= ) \
+ action( >=, GE, < ) \
+ action( ==, EQ, != ) \
+ action( !=, NE, == ) \
+/**/
+
+//____________________________________________________________________________//
+
+#ifndef BOOST_NO_CXX11_DECLTYPE
+
+#define BOOST_TEST_FOR_EACH_CONST_OP(action)\
+ action(->*, MEMP, ->* ) \
+ \
+ action( * , MUL, * ) \
+ action( / , DIV, / ) \
+ action( % , MOD, % ) \
+ \
+ action( + , ADD, + ) \
+ action( - , SUB, - ) \
+ \
+ action( <<, LSH, << ) \
+ action( >>, RSH, >> ) \
+ \
+ BOOST_TEST_FOR_EACH_COMP_OP(action) \
+ \
+ action( & , BAND, & ) \
+ action( ^ , XOR, ^ ) \
+ action( | , BOR, | ) \
+/**/
+
+#else
+
+#define BOOST_TEST_FOR_EACH_CONST_OP(action)\
+ BOOST_TEST_FOR_EACH_COMP_OP(action) \
+/**/
+
+#endif
+
+//____________________________________________________________________________//
+
+#define BOOST_TEST_FOR_EACH_MUT_OP(action) \
+ action( = , SET , = ) \
+ action( +=, IADD, += ) \
+ action( -=, ISUB, -= ) \
+ action( *=, IMUL, *= ) \
+ action( /=, IDIV, /= ) \
+ action( %=, IMOD, %= ) \
+ action(<<=, ILSH, <<=) \
+ action(>>=, IRSH, >>=) \
+ action( &=, IAND, &= ) \
+ action( ^=, IXOR, ^= ) \
+ action( |=, IOR , |= ) \
+/**/
+
+//____________________________________________________________________________//
+
+#ifndef BOOST_NO_CXX11_DECLTYPE
+# define DEDUCE_RESULT_TYPE( oper ) \
+ decltype(boost::declval<Lhs>() oper boost::declval<Rhs>() ) optype; \
+ typedef typename boost::remove_reference<optype>::type \
+/**/
+#else
+# define DEDUCE_RESULT_TYPE( oper ) bool
+#endif
+
+#define DEFINE_CONST_OPER( oper, name, rev ) \
+template<typename Lhs, typename Rhs, \
+ typename Enabler=void> \
+struct name { \
+ typedef DEDUCE_RESULT_TYPE( oper ) result_type; \
+ \
+ static result_type \
+ eval( Lhs const& lhs, Rhs const& rhs ) \
+ { \
+ return lhs oper rhs; \
+ } \
+ \
+ template<typename PrevExprType> \
+ static void \
+ report( std::ostream& ostr, \
+ PrevExprType const& lhs, \
+ Rhs const& rhs) \
+ { \
+ lhs.report( ostr ); \
+ ostr << revert() \
+ << tt_detail::print_helper( rhs ); \
+ } \
+ \
+ static char const* revert() \
+ { return " " #rev " "; } \
+}; \
+/**/
+
+BOOST_TEST_FOR_EACH_CONST_OP( DEFINE_CONST_OPER )
+
+#undef DEDUCE_RESULT_TYPE
+#undef DEFINE_CONST_OPER
+
+//____________________________________________________________________________//
+
+} // namespace op
+
+// ************************************************************************** //
+// ************** assertion::expression_base ************** //
+// ************************************************************************** //
+// Defines expression operators
+
+template<typename Lhs, typename Rhs, typename OP> class binary_expr;
+
+template<typename ExprType,typename ValType>
+class expression_base {
+public:
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#define ADD_OP_SUPPORT( oper, name, _ ) \
+ template<typename T> \
+ binary_expr<ExprType,T, \
+ op::name<ValType,typename remove_reference<T>::type> > \
+ operator oper( T&& rhs ) \
+ { \
+ return binary_expr<ExprType,T, \
+ op::name<ValType,typename remove_reference<T>::type> > \
+ ( std::forward<ExprType>( \
+ *static_cast<ExprType*>(this) ), \
+ std::forward<T>(rhs) ); \
+ } \
+/**/
+#else
+
+#define ADD_OP_SUPPORT( oper, name, _ ) \
+ template<typename T> \
+ binary_expr<ExprType,typename boost::decay<T const>::type, \
+ op::name<ValType,typename boost::decay<T const>::type> > \
+ operator oper( T const& rhs ) const \
+ { \
+ typedef typename boost::decay<T const>::type Rhs; \
+ return binary_expr<ExprType,Rhs,op::name<ValType,Rhs> > \
+ ( *static_cast<ExprType const*>(this), \
+ rhs ); \
+ } \
+/**/
+#endif
+
+ BOOST_TEST_FOR_EACH_CONST_OP( ADD_OP_SUPPORT )
+ #undef ADD_OP_SUPPORT
+
+#ifndef BOOST_NO_CXX11_AUTO_DECLARATIONS
+ // Disabled operators
+ template<typename T>
+ ExprType&
+ operator ||( T const& /*rhs*/ )
+ {
+ BOOST_MPL_ASSERT_MSG(false, CANT_USE_LOGICAL_OPERATOR_OR_WITHIN_THIS_TESTING_TOOL, () );
+
+ return *static_cast<ExprType*>(this);
+ }
+
+ template<typename T>
+ ExprType&
+ operator &&( T const& /*rhs*/ )
+ {
+ BOOST_MPL_ASSERT_MSG(false, CANT_USE_LOGICAL_OPERATOR_AND_WITHIN_THIS_TESTING_TOOL, () );
+
+ return *static_cast<ExprType*>(this);
+ }
+
+ operator bool()
+ {
+ BOOST_MPL_ASSERT_MSG(false, CANT_USE_TERNARY_OPERATOR_WITHIN_THIS_TESTING_TOOL, () );
+
+ return false;
+ }
+#endif
+};
+
+// ************************************************************************** //
+// ************** assertion::value_expr ************** //
+// ************************************************************************** //
+// simple value expression
+
+template<typename T>
+class value_expr : public expression_base<value_expr<T>,typename remove_reference<T>::type> {
+public:
+ // Public types
+ typedef T result_type;
+
+ // Constructor
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ value_expr( value_expr&& ve )
+ : m_value( std::forward<T>(ve.m_value) )
+ {}
+ explicit value_expr( T&& val )
+ : m_value( std::forward<T>(val) )
+ {}
+#else
+ explicit value_expr( T const& val )
+ : m_value( val )
+ {}
+#endif
+
+ // Specific expression interface
+ T const& value() const
+ {
+ return m_value;
+ }
+ void report( std::ostream& ostr ) const
+ {
+ ostr << tt_detail::print_helper( m_value );
+ }
+
+ // Mutating operators
+#define ADD_OP_SUPPORT( OPER, ID, _ ) \
+ template<typename U> \
+ value_expr<T>& \
+ operator OPER( U const& rhs ) \
+ { \
+ m_value OPER rhs; \
+ \
+ return *this; \
+ } \
+/**/
+
+ BOOST_TEST_FOR_EACH_MUT_OP( ADD_OP_SUPPORT )
+#undef ADD_OP_SUPPORT
+
+ // expression interface
+ assertion_result evaluate( bool no_message = false ) const
+ {
+ assertion_result res( value() );
+ if( no_message || res )
+ return res;
+
+ format_message( res.message(), value() );
+
+ return tt_detail::format_assertion_result( "", res.message().str() );
+ }
+
+private:
+ template<typename U>
+ static void format_message( wrap_stringstream& ostr, U const& v ) { ostr << "[(bool)" << v << " is false]"; }
+ static void format_message( wrap_stringstream& /*ostr*/, bool /*v*/ ) {}
+ static void format_message( wrap_stringstream& /*ostr*/, assertion_result const& /*v*/ ) {}
+
+ // Data members
+ T m_value;
+};
+
+// ************************************************************************** //
+// ************** assertion::binary_expr ************** //
+// ************************************************************************** //
+// binary expression
+
+template<typename LExpr, typename Rhs, typename OP>
+class binary_expr : public expression_base<binary_expr<LExpr,Rhs,OP>,typename OP::result_type> {
+public:
+ // Public types
+ typedef typename OP::result_type result_type;
+
+ // Constructor
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ binary_expr( binary_expr&& be )
+ : m_lhs( std::forward<LExpr>(be.m_lhs) )
+ , m_rhs( std::forward<Rhs>(be.m_rhs) )
+ {}
+ binary_expr( LExpr&& lhs, Rhs&& rhs )
+ : m_lhs( std::forward<LExpr>(lhs) )
+ , m_rhs( std::forward<Rhs>(rhs) )
+ {}
+#else
+ binary_expr( LExpr const& lhs, Rhs const& rhs )
+ : m_lhs( lhs )
+ , m_rhs( rhs )
+ {}
+#endif
+
+ // Specific expression interface
+ result_type value() const
+ {
+ return OP::eval( m_lhs.value(), m_rhs );
+ }
+ void report( std::ostream& ostr ) const
+ {
+ return OP::report( ostr, m_lhs, m_rhs );
+ }
+
+ assertion_result evaluate( bool no_message = false ) const
+ {
+ assertion_result const expr_res( value() );
+ if( no_message || expr_res )
+ return expr_res;
+
+ wrap_stringstream buff;
+ report( buff.stream() );
+
+ return tt_detail::format_assertion_result( buff.stream().str(), expr_res.message() );
+ }
+
+ // To support custom manipulators
+ LExpr const& lhs() const { return m_lhs; }
+ Rhs const& rhs() const { return m_rhs; }
+private:
+ // Data members
+ LExpr m_lhs;
+ Rhs m_rhs;
+};
+
+// ************************************************************************** //
+// ************** assertion::seed ************** //
+// ************************************************************************** //
+// seed added ot the input expression to form an assertion expression
+
+class seed {
+public:
+ // ->* is highest precedence left to right operator
+ template<typename T>
+ value_expr<T>
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ operator->*( T&& v ) const
+ {
+ return value_expr<T>( std::forward<T>( v ) );
+ }
+#else
+ operator->*( T const& v ) const
+ {
+ return value_expr<T>( v );
+ }
+#endif
+};
+
+#undef BOOST_TEST_FOR_EACH_CONST_OP
+
+} // namespace assertion
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
diff --git a/boost/test/tools/assertion_result.hpp b/boost/test/tools/assertion_result.hpp
new file mode 100644
index 0000000000..85cd18c0eb
--- /dev/null
+++ b/boost/test/tools/assertion_result.hpp
@@ -0,0 +1,90 @@
+// (C) Copyright Gennadiy Rozental 2001-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/test for the library home page.
+//
+/// @file
+/// Enhanced result for test predicate that include message explaining failure
+// ***************************************************************************
+
+#ifndef BOOST_TEST_PREDICATE_RESULT_HPP_012705GER
+#define BOOST_TEST_PREDICATE_RESULT_HPP_012705GER
+
+// Boost.Test
+#include <boost/test/utils/class_properties.hpp>
+#include <boost/test/utils/wrap_stringstream.hpp>
+#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
+
+// Boost
+#include <boost/shared_ptr.hpp>
+#include <boost/detail/workaround.hpp>
+
+// STL
+#include <cstddef> // for std::size_t
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+
+// ************************************************************************** //
+// ************** assertion_result ************** //
+// ************************************************************************** //
+
+//!@brief Type used for storing the result of an assertion.
+class BOOST_TEST_DECL assertion_result {
+
+ //!@internal
+ typedef unit_test::const_string const_string;
+
+ //!@internal
+ struct dummy { void nonnull() {} };
+
+ //!@internal
+ typedef void (dummy::*safe_bool)();
+
+public:
+ // Constructor
+ assertion_result( bool pv_ )
+ : p_predicate_value( pv_ )
+ {}
+
+ template<typename BoolConvertable>
+ assertion_result( BoolConvertable const& pv_ ) : p_predicate_value( !!pv_ ) {}
+
+ // Access methods
+ bool operator!() const { return !p_predicate_value; }
+ void operator=( bool pv_ ) { p_predicate_value.value = pv_; }
+ operator safe_bool() const { return !!p_predicate_value ? &dummy::nonnull : 0; }
+
+ // Public properties
+ BOOST_READONLY_PROPERTY( bool, (assertion_result) ) p_predicate_value;
+
+ // Access methods
+ bool has_empty_message() const { return !m_message; }
+ wrap_stringstream& message()
+ {
+ if( !m_message )
+ m_message.reset( new wrap_stringstream );
+
+ return *m_message;
+ }
+ const_string message() const { return !m_message ? const_string() : const_string( m_message->str() ); }
+
+private:
+ // Data members
+ shared_ptr<wrap_stringstream> m_message;
+};
+
+typedef assertion_result predicate_result;
+
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_PREDICATE_RESULT_HPP_012705GER
diff --git a/boost/test/tools/collection_comparison_op.hpp b/boost/test/tools/collection_comparison_op.hpp
new file mode 100644
index 0000000000..81a7046725
--- /dev/null
+++ b/boost/test/tools/collection_comparison_op.hpp
@@ -0,0 +1,375 @@
+// (C) Copyright Gennadiy Rozental 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/test for the library home page.
+//
+//!@file
+//!@brief Collection comparison with enhanced reporting
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_COLLECTION_COMPARISON_OP_HPP_050815GER
+#define BOOST_TEST_TOOLS_COLLECTION_COMPARISON_OP_HPP_050815GER
+
+// Boost.Test
+#include <boost/test/tools/assertion.hpp>
+
+#include <boost/test/utils/is_forward_iterable.hpp>
+
+// Boost
+#include <boost/mpl/bool.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/decay.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+namespace assertion {
+
+// ************************************************************************** //
+// ************* selectors for specialized comparizon routines ************** //
+// ************************************************************************** //
+
+template<typename T>
+struct specialized_compare : public mpl::false_ {};
+
+#define BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE(Col) \
+namespace boost { namespace test_tools { namespace assertion { \
+template<> \
+struct specialized_compare<Col> : public mpl::true_ {}; \
+}}} \
+/**/
+
+// ************************************************************************** //
+// ************** lexicographic_compare ************** //
+// ************************************************************************** //
+
+namespace op {
+
+template <typename OP, bool can_be_equal, bool prefer_shorter,
+ typename Lhs, typename Rhs>
+inline assertion_result
+lexicographic_compare( Lhs const& lhs, Rhs const& rhs )
+{
+ assertion_result ar( true );
+
+ typename Lhs::const_iterator first1 = lhs.begin();
+ typename Rhs::const_iterator first2 = rhs.begin();
+ typename Lhs::const_iterator last1 = lhs.end();
+ typename Rhs::const_iterator last2 = rhs.end();
+ std::size_t pos = 0;
+
+ for( ; (first1 != last1) && (first2 != last2); ++first1, ++first2, ++pos ) {
+ assertion_result const& element_ar = OP::eval(*first1, *first2);
+ if( !can_be_equal && element_ar )
+ return ar; // a < b
+
+ assertion_result const& reverse_ar = OP::eval(*first2, *first1);
+ if( element_ar && !reverse_ar )
+ return ar; // a<=b and !(b<=a) => a < b => return true
+
+ if( element_ar || !reverse_ar )
+ continue; // (a<=b and b<=a) or (!(a<b) and !(b<a)) => a == b => keep looking
+
+ // !(a<=b) and b<=a => b < a => return false
+ ar = false;
+ ar.message() << "\nFailure at position " << pos << ": "
+ << tt_detail::print_helper(*first1)
+ << OP::revert()
+ << tt_detail::print_helper(*first2)
+ << ". " << element_ar.message();
+ return ar;
+ }
+
+
+ if( first1 != last1 ) {
+ if( prefer_shorter ) {
+ ar = false;
+ ar.message() << "\nFirst collection has extra trailing elements.";
+ }
+ }
+ else if( first2 != last2 ) {
+ if( !prefer_shorter ) {
+ ar = false;
+ ar.message() << "\nSecond collection has extra trailing elements.";
+ }
+ }
+ else if( !can_be_equal ) {
+ ar = false;
+ ar.message() << "\nCollections appear to be equal.";
+ }
+
+ return ar;
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** equality_compare ************** //
+// ************************************************************************** //
+
+template <typename OP, typename Lhs, typename Rhs>
+inline assertion_result
+element_compare( Lhs const& lhs, Rhs const& rhs )
+{
+ assertion_result ar( true );
+
+ if( lhs.size() != rhs.size() ) {
+ ar = false;
+ ar.message() << "\nCollections size mismatch: " << lhs.size() << " != " << rhs.size();
+ return ar;
+ }
+
+ typename Lhs::const_iterator left = lhs.begin();
+ typename Rhs::const_iterator right = rhs.begin();
+ std::size_t pos = 0;
+
+ for( ; pos < lhs.size(); ++left, ++right, ++pos ) {
+ assertion_result const element_ar = OP::eval( *left, *right );
+ if( element_ar )
+ continue;
+
+ ar = false;
+ ar.message() << "\nMismatch at position " << pos << ": "
+ << tt_detail::print_helper(*left)
+ << OP::revert()
+ << tt_detail::print_helper(*right)
+ << ". " << element_ar.message();
+ }
+
+ return ar;
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** non_equality_compare ************** //
+// ************************************************************************** //
+
+template <typename OP, typename Lhs, typename Rhs>
+inline assertion_result
+non_equality_compare( Lhs const& lhs, Rhs const& rhs )
+{
+ assertion_result ar( true );
+
+ if( lhs.size() != rhs.size() )
+ return ar;
+
+ typename Lhs::const_iterator left = lhs.begin();
+ typename Rhs::const_iterator right = rhs.begin();
+ typename Lhs::const_iterator end = lhs.end();
+
+ for( ; left != end; ++left, ++right ) {
+ if( OP::eval( *left, *right ) )
+ return ar;
+ }
+
+ ar = false;
+ ar.message() << "\nCollections appear to be equal";
+
+ return ar;
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** cctraits ************** //
+// ************************************************************************** //
+// set of collection comparison traits per comparison OP
+
+template<typename OP>
+struct cctraits;
+
+template<typename Lhs, typename Rhs>
+struct cctraits<op::EQ<Lhs, Rhs> > {
+ typedef specialized_compare<Lhs> is_specialized;
+};
+
+template<typename Lhs, typename Rhs>
+struct cctraits<op::NE<Lhs, Rhs> > {
+ typedef specialized_compare<Lhs> is_specialized;
+};
+
+template<typename Lhs, typename Rhs>
+struct cctraits<op::LT<Lhs, Rhs> > {
+ static const bool can_be_equal = false;
+ static const bool prefer_short = true;
+
+ typedef specialized_compare<Lhs> is_specialized;
+};
+
+template<typename Lhs, typename Rhs>
+struct cctraits<op::LE<Lhs, Rhs> > {
+ static const bool can_be_equal = true;
+ static const bool prefer_short = true;
+
+ typedef specialized_compare<Lhs> is_specialized;
+};
+
+template<typename Lhs, typename Rhs>
+struct cctraits<op::GT<Lhs, Rhs> > {
+ static const bool can_be_equal = false;
+ static const bool prefer_short = false;
+
+ typedef specialized_compare<Lhs> is_specialized;
+};
+
+template<typename Lhs, typename Rhs>
+struct cctraits<op::GE<Lhs, Rhs> > {
+ static const bool can_be_equal = true;
+ static const bool prefer_short = false;
+
+ typedef specialized_compare<Lhs> is_specialized;
+};
+
+// ************************************************************************** //
+// ************** compare_collections ************** //
+// ************************************************************************** //
+// Overloaded set of functions dispatching to specific implementation of comparison
+
+template <typename Lhs, typename Rhs, typename L, typename R>
+inline assertion_result
+compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::EQ<L, R> >*, mpl::true_ )
+{
+ return assertion::op::element_compare<op::EQ<L, R> >( lhs, rhs );
+}
+
+//____________________________________________________________________________//
+
+template <typename Lhs, typename Rhs, typename L, typename R>
+inline assertion_result
+compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::EQ<L, R> >*, mpl::false_ )
+{
+ return lhs == rhs;
+}
+
+//____________________________________________________________________________//
+
+template <typename Lhs, typename Rhs, typename L, typename R>
+inline assertion_result
+compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::NE<L, R> >*, mpl::true_ )
+{
+ return assertion::op::non_equality_compare<op::NE<L, R> >( lhs, rhs );
+}
+
+//____________________________________________________________________________//
+
+template <typename Lhs, typename Rhs, typename L, typename R>
+inline assertion_result
+compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::NE<L, R> >*, mpl::false_ )
+{
+ return lhs != rhs;
+}
+
+//____________________________________________________________________________//
+
+template <typename OP, typename Lhs, typename Rhs>
+inline assertion_result
+lexicographic_compare( Lhs const& lhs, Rhs const& rhs )
+{
+ return assertion::op::lexicographic_compare<OP, cctraits<OP>::can_be_equal, cctraits<OP>::prefer_short>( lhs, rhs );
+}
+
+//____________________________________________________________________________//
+
+template <typename Lhs, typename Rhs, typename OP>
+inline assertion_result
+compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<OP>* tp, mpl::true_ )
+{
+ return lexicographic_compare<OP>( lhs, rhs );
+}
+
+//____________________________________________________________________________//
+
+template <typename Lhs, typename Rhs, typename L, typename R>
+inline assertion_result
+compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::LT<L, R> >* tp, mpl::false_ )
+{
+ return lhs < rhs;
+}
+
+//____________________________________________________________________________//
+
+template <typename Lhs, typename Rhs, typename L, typename R>
+inline assertion_result
+compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::LE<L, R> >* tp, mpl::false_ )
+{
+ return lhs <= rhs;
+}
+
+//____________________________________________________________________________//
+
+template <typename Lhs, typename Rhs, typename L, typename R>
+inline assertion_result
+compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::GT<L, R> >* tp, mpl::false_ )
+{
+ return lhs > rhs;
+}
+
+//____________________________________________________________________________//
+
+template <typename Lhs, typename Rhs, typename L, typename R>
+inline assertion_result
+compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::GE<L, R> >* tp, mpl::false_ )
+{
+ return lhs >= rhs;
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ********* specialization of comparison operators for collections ********* //
+// ************************************************************************** //
+
+#define DEFINE_COLLECTION_COMPARISON( oper, name, _ ) \
+template<typename Lhs,typename Rhs> \
+struct name<Lhs,Rhs,typename boost::enable_if_c< \
+ unit_test::is_forward_iterable<Lhs>::value && \
+ unit_test::is_forward_iterable<Rhs>::value>::type> { \
+public: \
+ typedef assertion_result result_type; \
+ \
+ typedef name<Lhs, Rhs> OP; \
+ typedef typename \
+ mpl::if_c<is_same<typename decay<Lhs>::type, \
+ typename decay<Rhs>::type>::value, \
+ typename cctraits<OP>::is_specialized, \
+ mpl::false_>::type is_specialized; \
+ \
+ typedef name<typename Lhs::value_type, \
+ typename Rhs::value_type> elem_op; \
+ \
+ static assertion_result \
+ eval( Lhs const& lhs, Rhs const& rhs) \
+ { \
+ return assertion::op::compare_collections( lhs, rhs, \
+ (boost::type<elem_op>*)0, \
+ is_specialized() ); \
+ } \
+ \
+ template<typename PrevExprType> \
+ static void \
+ report( std::ostream&, \
+ PrevExprType const&, \
+ Rhs const& ) {} \
+}; \
+/**/
+
+BOOST_TEST_FOR_EACH_COMP_OP( DEFINE_COLLECTION_COMPARISON )
+#undef DEFINE_COLLECTION_COMPARISON
+
+//____________________________________________________________________________//
+
+} // namespace op
+} // namespace assertion
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_COLLECTION_COMPARISON_OP_HPP_050815GER
+
diff --git a/boost/test/tools/context.hpp b/boost/test/tools/context.hpp
new file mode 100644
index 0000000000..38018b84b8
--- /dev/null
+++ b/boost/test/tools/context.hpp
@@ -0,0 +1,65 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 74248 $
+//
+// Description : test tools context interfaces
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_CONTEXT_HPP_111712GER
+#define BOOST_TEST_TOOLS_CONTEXT_HPP_111712GER
+
+// Boost.Test
+#include <boost/test/utils/lazy_ostream.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+namespace tt_detail {
+
+// ************************************************************************** //
+// ************** context_frame ************** //
+// ************************************************************************** //
+
+struct BOOST_TEST_DECL context_frame {
+ explicit context_frame( ::boost::unit_test::lazy_ostream const& context_descr );
+ ~context_frame();
+
+ operator bool();
+
+private:
+ // Data members
+ int m_frame_id;
+};
+
+//____________________________________________________________________________//
+
+#define BOOST_TEST_INFO( context_descr ) \
+ ::boost::unit_test::framework::add_context( BOOST_TEST_LAZY_MSG( context_descr ) , false ) \
+/**/
+
+//____________________________________________________________________________//
+
+#define BOOST_TEST_CONTEXT( context_descr ) \
+ if( ::boost::test_tools::tt_detail::context_frame BOOST_JOIN( context_frame_, __LINE__ ) = \
+ ::boost::test_tools::tt_detail::context_frame( BOOST_TEST_LAZY_MSG( context_descr ) ) ) \
+/**/
+
+//____________________________________________________________________________//
+
+} // namespace tt_detail
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_CONTEXT_HPP_111712GER
diff --git a/boost/test/tools/cstring_comparison_op.hpp b/boost/test/tools/cstring_comparison_op.hpp
new file mode 100644
index 0000000000..3b114e5977
--- /dev/null
+++ b/boost/test/tools/cstring_comparison_op.hpp
@@ -0,0 +1,91 @@
+// (C) Copyright Gennadiy Rozental 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/test for the library home page.
+//
+//!@file
+//!@brief C string comparison with enhanced reporting
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_CSTRING_COMPARISON_OP_HPP_050815GER
+#define BOOST_TEST_TOOLS_CSTRING_COMPARISON_OP_HPP_050815GER
+
+// Boost.Test
+#include <boost/test/tools/assertion.hpp>
+
+#include <boost/test/utils/is_cstring.hpp>
+#include <boost/test/utils/basic_cstring/compare.hpp>
+
+// Boost
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+namespace assertion {
+namespace op {
+
+
+
+// ************************************************************************** //
+// ************** string_compare ************** //
+// ************************************************************************** //
+
+#define DEFINE_CSTRING_COMPARISON( oper, name, rev ) \
+template<typename Lhs,typename Rhs> \
+struct name<Lhs,Rhs,typename boost::enable_if_c< \
+ unit_test::is_cstring<Lhs>::value && \
+ unit_test::is_cstring<Rhs>::value>::type> { \
+ typedef typename boost::add_const< \
+ typename remove_pointer< \
+ typename decay<Lhs>::type>::type>::type \
+ lhs_char_type; \
+ typedef typename boost::add_const< \
+ typename remove_pointer< \
+ typename decay<Rhs>::type>::type>::type \
+ rhs_char_type; \
+public: \
+ typedef assertion_result result_type; \
+ \
+ static bool \
+ eval( Lhs const& lhs, Rhs const& rhs) \
+ { \
+ return unit_test::basic_cstring<lhs_char_type>(lhs) oper \
+ unit_test::basic_cstring<rhs_char_type>(rhs); \
+ } \
+ \
+ template<typename PrevExprType> \
+ static void \
+ report( std::ostream& ostr, \
+ PrevExprType const& lhs, \
+ Rhs const& rhs) \
+ { \
+ lhs.report( ostr ); \
+ ostr << revert() \
+ << tt_detail::print_helper( rhs ); \
+ } \
+ \
+ static char const* revert() \
+ { return " " #rev " "; } \
+}; \
+/**/
+
+BOOST_TEST_FOR_EACH_COMP_OP( DEFINE_CSTRING_COMPARISON )
+#undef DEFINE_CSTRING_COMPARISON
+
+//____________________________________________________________________________//
+
+} // namespace op
+} // namespace assertion
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_CSTRING_COMPARISON_OP_HPP_050815GER
+
diff --git a/boost/test/tools/detail/bitwise_manip.hpp b/boost/test/tools/detail/bitwise_manip.hpp
new file mode 100644
index 0000000000..e0fd36acd4
--- /dev/null
+++ b/boost/test/tools/detail/bitwise_manip.hpp
@@ -0,0 +1,123 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+//! @file
+//! Bitwise comparison manipulator implementation
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_DETAIL_BITWISE_MANIP_HPP_012705GER
+#define BOOST_TEST_TOOLS_DETAIL_BITWISE_MANIP_HPP_012705GER
+
+// Boost Test
+#include <boost/test/tools/detail/fwd.hpp>
+#include <boost/test/tools/detail/indirections.hpp>
+
+#include <boost/test/tools/assertion_result.hpp>
+#include <boost/test/tools/assertion.hpp>
+
+// STL
+#include <climits> // for CHAR_BIT
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+
+// ************************************************************************** //
+// ************** bitwise comparison manipulator ************** //
+// ************************************************************************** //
+
+//! Bitwise comparison manipulator
+struct bitwise {};
+
+//____________________________________________________________________________//
+
+inline int
+operator<<( unit_test::lazy_ostream const&, bitwise ) { return 0; }
+
+//____________________________________________________________________________//
+
+namespace tt_detail {
+
+/*!@brief Bitwise comparison of two operands
+ *
+ * This class constructs an @ref assertion_result that contains precise bit comparison information.
+ * In particular the location of the mismatches (if any) are printed in the assertion result.
+ */
+template<typename Lhs, typename Rhs, typename E>
+inline assertion_result
+bitwise_compare(Lhs const& lhs, Rhs const& rhs, E const& expr )
+{
+ assertion_result pr( true );
+
+ std::size_t left_bit_size = sizeof(Lhs)*CHAR_BIT;
+ std::size_t right_bit_size = sizeof(Rhs)*CHAR_BIT;
+
+ static Lhs const leftOne( 1 );
+ static Rhs const rightOne( 1 );
+
+ std::size_t total_bits = left_bit_size < right_bit_size ? left_bit_size : right_bit_size;
+
+ for( std::size_t counter = 0; counter < total_bits; ++counter ) {
+ if( (lhs & ( leftOne << counter )) != (rhs & (rightOne << counter)) ) {
+ if( pr ) {
+ pr.message() << " [";
+ expr.report( pr.message().stream() );
+ pr.message() << "]. Bitwise comparison failed";
+ pr = false;
+ }
+ pr.message() << "\nMismatch at position " << counter;
+ }
+ }
+
+ if( left_bit_size != right_bit_size ) {
+ if( pr ) {
+ pr.message() << " [";
+ expr.report( pr.message().stream() );
+ pr.message() << "]. Bitwise comparison failed";
+ pr = false;
+ }
+ pr.message() << "\nOperands bit sizes mismatch: " << left_bit_size << " != " << right_bit_size;
+ }
+
+ return pr;
+}
+
+//____________________________________________________________________________//
+
+//! Returns an assertion_result using the bitwise comparison out of an expression
+//!
+//! This is used as a modifer of the normal operator<< on expressions to use the
+//! bitwise comparison.
+//!
+//! @note Available only for compilers supporting the @c auto declaration.
+template<typename T1, typename T2, typename T3, typename T4>
+inline assertion_result
+operator<<(assertion_evaluate_t<assertion::binary_expr<T1,T2,assertion::op::EQ<T3,T4> > > const& ae, bitwise )
+{
+ return bitwise_compare( ae.m_e.lhs().value(), ae.m_e.rhs(), ae.m_e );
+}
+
+//____________________________________________________________________________//
+
+inline check_type
+operator<<( assertion_type const& , bitwise )
+{
+ return CHECK_BUILT_ASSERTION;
+}
+
+//____________________________________________________________________________//
+
+} // namespace tt_detail
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_DETAIL_BITWISE_MANIP_HPP_012705GER
diff --git a/boost/test/tools/detail/expression_holder.hpp b/boost/test/tools/detail/expression_holder.hpp
new file mode 100644
index 0000000000..7d7efd04e6
--- /dev/null
+++ b/boost/test/tools/detail/expression_holder.hpp
@@ -0,0 +1,70 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 74248 $
+//
+// Description : toolbox implementation details
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_DETAIL_EXPRESSION_HOLDER_HPP_012705GER
+#define BOOST_TEST_TOOLS_DETAIL_EXPRESSION_HOLDER_HPP_012705GER
+
+#ifdef BOOST_NO_CXX11_AUTO_DECLARATIONS
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+namespace tt_detail {
+
+// ************************************************************************** //
+// ************** tt_detail::expression_holder ************** //
+// ************************************************************************** //
+
+class expression_holder {
+public:
+ virtual ~expression_holder() {}
+ virtual assertion_result evaluate( bool no_message = false ) const = 0;
+};
+
+//____________________________________________________________________________//
+
+template<typename E>
+class expression_holder_t: public expression_holder {
+public:
+ explicit expression_holder_t( E const& e ) : m_expr( e ) {}
+
+private:
+ virtual assertion_result evaluate( bool no_message = false ) const { return m_expr.evaluate( no_message ); }
+
+ E m_expr;
+};
+
+//____________________________________________________________________________//
+
+template<typename E>
+expression_holder_t<E>
+hold_expression( E const& e )
+{
+ return expression_holder_t<E>( e );
+}
+
+//____________________________________________________________________________//
+
+} // namespace tt_detail
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif
+
+#endif // BOOST_TEST_TOOLS_DETAIL_EXPRESSION_HOLDER_HPP_012705GER
diff --git a/boost/test/tools/detail/fwd.hpp b/boost/test/tools/detail/fwd.hpp
new file mode 100644
index 0000000000..d5915a1656
--- /dev/null
+++ b/boost/test/tools/detail/fwd.hpp
@@ -0,0 +1,121 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 74248 $
+//
+// Description : toolbox implementation types and forward declarations
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_DETAIL_FWD_HPP_012705GER
+#define BOOST_TEST_TOOLS_DETAIL_FWD_HPP_012705GER
+
+// Boost.Test
+#include <boost/test/detail/config.hpp>
+#include <boost/test/utils/basic_cstring/io.hpp>
+
+// STL
+#include <cstddef> // for std::size_t
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+
+class lazy_ostream;
+
+} // namespace unit_test
+
+namespace test_tools {
+
+using unit_test::const_string;
+class assertion_result;
+
+//____________________________________________________________________________//
+
+namespace tt_detail {
+
+inline bool dummy_cond() { return false; }
+
+// ************************************************************************** //
+// ************** types of supported assertions ************** //
+// ************************************************************************** //
+
+//____________________________________________________________________________//
+
+enum check_type {
+ CHECK_PRED,
+ CHECK_MSG,
+ CHECK_EQUAL,
+ CHECK_NE,
+ CHECK_LT,
+ CHECK_LE,
+ CHECK_GT,
+ CHECK_GE,
+ CHECK_CLOSE,
+ CHECK_CLOSE_FRACTION,
+ CHECK_SMALL,
+ CHECK_BITWISE_EQUAL,
+ CHECK_PRED_WITH_ARGS,
+ CHECK_EQUAL_COLL,
+ CHECK_BUILT_ASSERTION
+};
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** levels of supported assertions ************** //
+// ************************************************************************** //
+
+enum tool_level {
+ WARN, CHECK, REQUIRE, PASS
+};
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** Tools offline implementation ************** //
+// ************************************************************************** //
+
+BOOST_TEST_DECL bool
+report_assertion( assertion_result const& pr, unit_test::lazy_ostream const& assertion_descr,
+ const_string file_name, std::size_t line_num,
+ tool_level tl, check_type ct,
+ std::size_t num_args, ... );
+
+//____________________________________________________________________________//
+
+BOOST_TEST_DECL assertion_result
+format_assertion_result( const_string expr_val, const_string details );
+
+//____________________________________________________________________________//
+
+BOOST_TEST_DECL assertion_result
+format_fpc_report( const_string expr_val, const_string details );
+
+//____________________________________________________________________________//
+
+BOOST_TEST_DECL bool
+is_defined_impl( const_string symbol_name, const_string symbol_value );
+
+//____________________________________________________________________________//
+
+BOOST_TEST_DECL assertion_result
+equal_impl( char const* left, char const* right );
+
+//____________________________________________________________________________//
+
+} // namespace tt_detail
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_DETAIL_FWD_HPP_012705GER
diff --git a/boost/test/tools/detail/indirections.hpp b/boost/test/tools/detail/indirections.hpp
new file mode 100644
index 0000000000..429420f55a
--- /dev/null
+++ b/boost/test/tools/detail/indirections.hpp
@@ -0,0 +1,94 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 74248 $
+//
+// Description : inidiration interfaces to support manipulators and message output
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_DETAIL_INDIRECTIONS_HPP_112812GER
+#define BOOST_TEST_TOOLS_DETAIL_INDIRECTIONS_HPP_112812GER
+
+// Boost.Test
+#include <boost/test/tools/detail/fwd.hpp>
+
+#include <boost/test/tools/assertion_result.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+namespace tt_detail {
+
+// ************************************************************************** //
+// ************** assertion_evaluate indirection ************** //
+// ************************************************************************** //
+
+template<typename E>
+struct assertion_evaluate_t {
+ assertion_evaluate_t( E const& e ) : m_e( e ) {}
+ operator assertion_result() { return m_e.evaluate( true ); }
+
+ E const& m_e;
+};
+
+//____________________________________________________________________________//
+
+template<typename E>
+inline assertion_evaluate_t<E>
+assertion_evaluate( E const& e ) { return assertion_evaluate_t<E>( e ); }
+
+//____________________________________________________________________________//
+
+template<typename E, typename T>
+inline assertion_evaluate_t<E>
+operator<<( assertion_evaluate_t<E> const& ae, T const& ) { return ae; }
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** assertion_text indirection ************** //
+// ************************************************************************** //
+
+template<typename T>
+inline unit_test::lazy_ostream const&
+assertion_text( unit_test::lazy_ostream const& /*et*/, T const& m ) { return m; }
+
+//____________________________________________________________________________//
+
+inline unit_test::lazy_ostream const&
+assertion_text( unit_test::lazy_ostream const& et, int ) { return et; }
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** assertion_evaluate indirection ************** //
+// ************************************************************************** //
+
+struct assertion_type {
+ operator check_type() { return CHECK_MSG; }
+};
+
+//____________________________________________________________________________//
+
+template<typename T>
+inline assertion_type
+operator<<( assertion_type const& at, T const& ) { return at; }
+
+//____________________________________________________________________________//
+
+} // namespace tt_detail
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_DETAIL_INDIRECTIONS_HPP_112812GER
diff --git a/boost/test/tools/detail/it_pair.hpp b/boost/test/tools/detail/it_pair.hpp
new file mode 100644
index 0000000000..929bbae96d
--- /dev/null
+++ b/boost/test/tools/detail/it_pair.hpp
@@ -0,0 +1,74 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 74248 $
+//
+// Description : support for backward compatible collection comparison interface
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_DETAIL_IT_PAIR_HPP_112812GER
+#define BOOST_TEST_TOOLS_DETAIL_IT_PAIR_HPP_112812GER
+
+#ifdef BOOST_TEST_NO_OLD_TOOLS
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+namespace tt_detail {
+
+// ************************************************************************** //
+// ************** backward compatibility support ************** //
+// ************************************************************************** //
+
+template<typename It>
+struct it_pair {
+ typedef It const_iterator;
+ typedef typename std::iterator_traits<It>::value_type value_type;
+
+ it_pair( It const& b, It const& e ) : m_begin( b ), m_size( 0 )
+ {
+ It tmp = b;
+ while( tmp != e ) { ++m_size; ++tmp; }
+ }
+
+ It begin() const { return m_begin; }
+ It end() const { return m_begin + m_size; }
+ size_t size() const { return m_size; }
+
+private:
+ It m_begin;
+ size_t m_size;
+};
+
+//____________________________________________________________________________//
+
+template<typename It>
+it_pair<It>
+make_it_pair( It const& b, It const& e ) { return it_pair<It>( b, e ); }
+
+//____________________________________________________________________________//
+
+template<typename T>
+it_pair<T const*>
+make_it_pair( T const* b, T const* e ) { return it_pair<T const*>( b, e ); }
+
+//____________________________________________________________________________//
+
+} // namespace tt_detail
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_NO_OLD_TOOLS
+
+#endif // BOOST_TEST_TOOLS_DETAIL_IT_PAIR_HPP_112812GER
diff --git a/boost/test/tools/detail/lexicographic_manip.hpp b/boost/test/tools/detail/lexicographic_manip.hpp
new file mode 100644
index 0000000000..01d63a9e91
--- /dev/null
+++ b/boost/test/tools/detail/lexicographic_manip.hpp
@@ -0,0 +1,69 @@
+// (C) Copyright Gennadiy Rozental 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/test for the library home page.
+//
+//! @file
+//! Lexicographic comparison manipulator implementation
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_DETAIL_LEXICOGRAPHIC_MANIP_HPP_050815GER
+#define BOOST_TEST_TOOLS_DETAIL_LEXICOGRAPHIC_MANIP_HPP_050815GER
+
+// Boost Test
+#include <boost/test/tools/detail/fwd.hpp>
+#include <boost/test/tools/detail/indirections.hpp>
+
+#include <boost/test/tools/assertion.hpp>
+#include <boost/test/tools/collection_comparison_op.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+
+// ************************************************************************** //
+// ************** per element comparison manipulator ************** //
+// ************************************************************************** //
+
+//! Lexicographic comparison manipulator, for containers
+struct lexicographic {};
+
+//____________________________________________________________________________//
+
+inline int
+operator<<( unit_test::lazy_ostream const&, lexicographic ) { return 0; }
+
+//____________________________________________________________________________//
+
+namespace tt_detail {
+
+template<typename T1, typename T2, typename OP>
+inline assertion_result
+operator<<(assertion_evaluate_t<assertion::binary_expr<T1,T2,OP> > const& ae, lexicographic )
+{
+ typedef typename OP::elem_op elem_op;
+ return assertion::op::lexicographic_compare<elem_op>( ae.m_e.lhs().value(), ae.m_e.rhs() );
+}
+
+//____________________________________________________________________________//
+
+inline check_type
+operator<<( assertion_type const&, lexicographic )
+{
+ return CHECK_BUILT_ASSERTION;
+}
+
+//____________________________________________________________________________//
+
+} // namespace tt_detail
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_DETAIL_LEXICOGRAPHIC_MANIP_HPP_050815GER
diff --git a/boost/test/tools/detail/per_element_manip.hpp b/boost/test/tools/detail/per_element_manip.hpp
new file mode 100644
index 0000000000..efcd45e9b8
--- /dev/null
+++ b/boost/test/tools/detail/per_element_manip.hpp
@@ -0,0 +1,69 @@
+// (C) Copyright Gennadiy Rozental 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/test for the library home page.
+//
+//! @file
+//! Per element comparison manipulator implementation
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_DETAIL_PER_ELEMENT_MANIP_HPP_050815GER
+#define BOOST_TEST_TOOLS_DETAIL_PER_ELEMENT_MANIP_HPP_050815GER
+
+// Boost Test
+#include <boost/test/tools/detail/fwd.hpp>
+#include <boost/test/tools/detail/indirections.hpp>
+
+#include <boost/test/tools/assertion.hpp>
+#include <boost/test/tools/collection_comparison_op.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+
+// ************************************************************************** //
+// ************** per element comparison manipulator ************** //
+// ************************************************************************** //
+
+//! Per element comparison manipulator, for containers
+struct per_element {};
+
+//____________________________________________________________________________//
+
+inline int
+operator<<( unit_test::lazy_ostream const&, per_element ) { return 0; }
+
+//____________________________________________________________________________//
+
+namespace tt_detail {
+
+template<typename T1, typename T2, typename OP>
+inline assertion_result
+operator<<(assertion_evaluate_t<assertion::binary_expr<T1,T2,OP> > const& ae, per_element )
+{
+ typedef typename OP::elem_op elem_op;
+ return assertion::op::element_compare<elem_op>( ae.m_e.lhs().value(), ae.m_e.rhs() );
+}
+
+//____________________________________________________________________________//
+
+inline check_type
+operator<<( assertion_type const&, per_element )
+{
+ return CHECK_BUILT_ASSERTION;
+}
+
+//____________________________________________________________________________//
+
+} // namespace tt_detail
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_DETAIL_PER_ELEMENT_MANIP_HPP_050815GER
diff --git a/boost/test/tools/detail/print_helper.hpp b/boost/test/tools/detail/print_helper.hpp
new file mode 100644
index 0000000000..ab15146aa2
--- /dev/null
+++ b/boost/test/tools/detail/print_helper.hpp
@@ -0,0 +1,199 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 74248 $
+//
+// Description : defines level of indiration facilitating workarounds for non printable types
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_IMPL_COMMON_HPP_012705GER
+#define BOOST_TEST_TOOLS_IMPL_COMMON_HPP_012705GER
+
+// Boost.Test
+#include <boost/test/detail/config.hpp>
+#include <boost/test/detail/global_typedef.hpp>
+#include <boost/test/detail/workaround.hpp>
+
+// Boost
+#include <boost/mpl/or.hpp>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/is_function.hpp>
+#include <boost/type_traits/is_abstract.hpp>
+#include <limits>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+namespace tt_detail {
+
+// ************************************************************************** //
+// ************** print_log_value ************** //
+// ************************************************************************** //
+
+template<typename T>
+struct print_log_value {
+ void operator()( std::ostream& ostr, T const& t )
+ {
+ typedef typename mpl::or_<is_array<T>,is_function<T>,is_abstract<T> >::type cant_use_nl;
+
+ std::streamsize old_precision = set_precision( ostr, cant_use_nl() );
+
+ ostr << t;
+
+ if( old_precision != (std::streamsize)-1 )
+ ostr.precision( old_precision );
+ }
+
+ std::streamsize set_precision( std::ostream& ostr, mpl::false_ )
+ {
+ if( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 2 )
+ return ostr.precision( 2 + std::numeric_limits<T>::digits * 301/1000 );
+ else if ( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 10 ) {
+#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
+ // (was BOOST_NO_NUMERIC_LIMITS_LOWEST but now deprecated).
+ // No support for std::numeric_limits<double>::max_digits10,
+ // so guess that a couple of guard digits more than digits10 will display any difference.
+ return ostr.precision( 2 + std::numeric_limits<T>::digits10 );
+#else
+ // std::numeric_limits<double>::max_digits10; IS supported.
+ // Any noisy or guard digits needed to display any difference are included in max_digits10.
+ return ostr.precision( std::numeric_limits<T>::max_digits10 );
+#endif
+ }
+ // else if T is not specialized for std::numeric_limits<>,
+ // then will just get the default precision of 6 digits.
+ return (std::streamsize)-1;
+ }
+
+ std::streamsize set_precision( std::ostream&, mpl::true_ ) { return (std::streamsize)-1; }
+};
+
+//____________________________________________________________________________//
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+template<typename T, std::size_t N >
+struct print_log_value< T[N] > {
+ void operator()( std::ostream& ostr, T const* t )
+ {
+ ostr << t;
+ }
+};
+#endif
+
+//____________________________________________________________________________//
+
+template<>
+struct BOOST_TEST_DECL print_log_value<bool> {
+ void operator()( std::ostream& ostr, bool t )
+ {
+ ostr << std::boolalpha << t;
+ }
+};
+
+//____________________________________________________________________________//
+
+template<>
+struct BOOST_TEST_DECL print_log_value<char> {
+ void operator()( std::ostream& ostr, char t );
+};
+
+//____________________________________________________________________________//
+
+template<>
+struct BOOST_TEST_DECL print_log_value<unsigned char> {
+ void operator()( std::ostream& ostr, unsigned char t );
+};
+
+//____________________________________________________________________________//
+
+template<>
+struct BOOST_TEST_DECL print_log_value<char const*> {
+ void operator()( std::ostream& ostr, char const* t );
+};
+
+//____________________________________________________________________________//
+
+template<>
+struct BOOST_TEST_DECL print_log_value<wchar_t const*> {
+ void operator()( std::ostream& ostr, wchar_t const* t );
+};
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** print_helper ************** //
+// ************************************************************************** //
+// Adds level of indirection to the output operation, allowing us to customize
+// it for types that do not support operator << directly or for any other reason
+
+template<typename T>
+struct print_helper_t {
+ explicit print_helper_t( T const& t ) : m_t( t ) {}
+
+ T const& m_t;
+};
+
+//____________________________________________________________________________//
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+// Borland suffers premature pointer decay passing arrays by reference
+template<typename T, std::size_t N >
+struct print_helper_t< T[N] > {
+ explicit print_helper_t( T const * t ) : m_t( t ) {}
+
+ T const * m_t;
+};
+#endif
+
+//____________________________________________________________________________//
+
+template<typename T>
+inline print_helper_t<T>
+print_helper( T const& t )
+{
+ return print_helper_t<T>( t );
+}
+
+//____________________________________________________________________________//
+
+template<typename T>
+inline std::ostream&
+operator<<( std::ostream& ostr, print_helper_t<T> const& ph )
+{
+ print_log_value<T>()( ostr, ph.m_t );
+
+ return ostr;
+}
+
+//____________________________________________________________________________//
+
+} // namespace tt_detail
+
+// ************************************************************************** //
+// ************** BOOST_TEST_DONT_PRINT_LOG_VALUE ************** //
+// ************************************************************************** //
+
+#define BOOST_TEST_DONT_PRINT_LOG_VALUE( the_type ) \
+namespace boost{ namespace test_tools{ namespace tt_detail{ \
+template<> \
+struct print_log_value<the_type > { \
+ void operator()( std::ostream&, the_type const& ) {} \
+}; \
+}}} \
+/**/
+
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_IMPL_COMMON_HPP_012705GER
diff --git a/boost/test/tools/detail/tolerance_manip.hpp b/boost/test/tools/detail/tolerance_manip.hpp
new file mode 100644
index 0000000000..adb58f98d0
--- /dev/null
+++ b/boost/test/tools/detail/tolerance_manip.hpp
@@ -0,0 +1,130 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+//! @file
+//! @brief Floating point comparison tolerance manipulators
+//!
+//! This file defines several manipulators for floating point comparison. These
+//! manipulators are intended to be used with BOOST_TEST.
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER
+#define BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER
+
+// Boost Test
+#include <boost/test/tools/detail/fwd.hpp>
+#include <boost/test/tools/detail/indirections.hpp>
+
+#include <boost/test/tools/fpc_tolerance.hpp>
+#include <boost/test/tools/floating_point_comparison.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+namespace tt_detail {
+
+// ************************************************************************** //
+// ************** fpc tolerance manipulator ************** //
+// ************************************************************************** //
+
+template<typename FPT>
+struct tolerance_manip {
+ explicit tolerance_manip( FPT const & tol ) : m_value( tol ) {}
+
+ FPT m_value;
+};
+
+//____________________________________________________________________________//
+
+struct tolerance_manip_delay {};
+
+template<typename FPT>
+inline tolerance_manip<FPT>
+operator%( FPT v, tolerance_manip_delay const& )
+{
+ BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value),
+ "tolerance only for floating points" );
+
+ return tolerance_manip<FPT>( FPT(v / 100) );
+}
+
+//____________________________________________________________________________//
+
+template<typename E, typename FPT>
+inline assertion_result
+operator<<(assertion_evaluate_t<E> const& ae, tolerance_manip<FPT> const& tol)
+{
+ local_fpc_tolerance<FPT> lt( tol.m_value );
+
+ return ae.m_e.evaluate();
+}
+
+//____________________________________________________________________________//
+
+template<typename FPT>
+inline int
+operator<<( unit_test::lazy_ostream const&, tolerance_manip<FPT> const& ) { return 0; }
+
+//____________________________________________________________________________//
+
+template<typename FPT>
+inline check_type
+operator<<( assertion_type const& /*at*/, tolerance_manip<FPT> const& ) { return CHECK_BUILT_ASSERTION; }
+
+//____________________________________________________________________________//
+
+} // namespace tt_detail
+
+
+/*! Tolerance manipulator
+ *
+ * These functions return a manipulator that can be used in conjunction with BOOST_TEST
+ * in order to specify the tolerance with which floating point comparisons are made.
+ */
+template<typename FPT>
+inline tt_detail::tolerance_manip<FPT>
+tolerance( FPT v )
+{
+ BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value),
+ "tolerance only for floating points" );
+
+ return tt_detail::tolerance_manip<FPT>( v );
+}
+
+//____________________________________________________________________________//
+
+//! @overload tolerance( FPT v )
+template<typename FPT>
+inline tt_detail::tolerance_manip<FPT>
+tolerance( fpc::percent_tolerance_t<FPT> v )
+{
+ BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value),
+ "tolerance only for floating points" );
+
+ return tt_detail::tolerance_manip<FPT>( static_cast<FPT>(v.m_value / 100) );
+}
+
+//____________________________________________________________________________//
+
+//! @overload tolerance( FPT v )
+inline tt_detail::tolerance_manip_delay
+tolerance()
+{
+ return tt_detail::tolerance_manip_delay();
+}
+
+//____________________________________________________________________________//
+
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER
diff --git a/boost/test/tools/floating_point_comparison.hpp b/boost/test/tools/floating_point_comparison.hpp
new file mode 100644
index 0000000000..fac914c91d
--- /dev/null
+++ b/boost/test/tools/floating_point_comparison.hpp
@@ -0,0 +1,315 @@
+// (C) Copyright Gennadiy Rozental 2001-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/test for the library home page.
+//
+//!@file
+//!@brief algorithms for comparing floating point values
+// ***************************************************************************
+
+#ifndef BOOST_TEST_FLOATING_POINT_COMPARISON_HPP_071894GER
+#define BOOST_TEST_FLOATING_POINT_COMPARISON_HPP_071894GER
+
+// Boost.Test
+#include <boost/test/detail/global_typedef.hpp>
+#include <boost/test/tools/assertion_result.hpp>
+
+// Boost
+#include <boost/limits.hpp> // for std::numeric_limits
+#include <boost/static_assert.hpp>
+#include <boost/assert.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/type_traits/is_floating_point.hpp>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/conditional.hpp>
+#include <boost/utility/enable_if.hpp>
+
+// STL
+#include <iosfwd>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace math {
+namespace fpc {
+
+// ************************************************************************** //
+// ************** fpc::tolerance_based ************** //
+// ************************************************************************** //
+
+
+//! @internal
+//! Protects the instanciation of std::numeric_limits from non-supported types (eg. T=array)
+template <typename T, bool enabled>
+struct tolerance_based_delegate;
+
+template <typename T>
+struct tolerance_based_delegate<T, false> : mpl::false_ {};
+
+template <typename T>
+struct tolerance_based_delegate<T, true>
+: mpl::bool_<
+ is_floating_point<T>::value ||
+ (!std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_specialized && !std::numeric_limits<T>::is_exact)>
+{};
+
+
+/*!@brief Indicates if a type can be compared using a tolerance scheme
+ *
+ * This is a metafunction that should evaluate to @c mpl::true_ if the type
+ * @c T can be compared using a tolerance based method, typically for floating point
+ * types.
+ *
+ * This metafunction can be specialized further to declare user types that are
+ * floating point (eg. boost.multiprecision).
+ */
+template <typename T>
+struct tolerance_based : tolerance_based_delegate<T, !is_array<T>::value >::type {};
+
+// ************************************************************************** //
+// ************** fpc::strength ************** //
+// ************************************************************************** //
+
+//! Method for comparing floating point numbers
+enum strength {
+ FPC_STRONG, //!< "Very close" - equation 2' in docs, the default
+ FPC_WEAK //!< "Close enough" - equation 3' in docs.
+};
+
+
+// ************************************************************************** //
+// ************** tolerance presentation types ************** //
+// ************************************************************************** //
+
+template<typename FPT>
+struct percent_tolerance_t {
+ explicit percent_tolerance_t( FPT v ) : m_value( v ) {}
+
+ FPT m_value;
+};
+
+//____________________________________________________________________________//
+
+template<typename FPT>
+inline std::ostream& operator<<( std::ostream& out, percent_tolerance_t<FPT> t )
+{
+ return out << t.m_value;
+}
+
+//____________________________________________________________________________//
+
+template<typename FPT>
+inline percent_tolerance_t<FPT>
+percent_tolerance( FPT v )
+{
+ return percent_tolerance_t<FPT>( v );
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** details ************** //
+// ************************************************************************** //
+
+namespace fpc_detail {
+
+// FPT is Floating-Point Type: float, double, long double or User-Defined.
+template<typename FPT>
+inline FPT
+fpt_abs( FPT fpv )
+{
+ return fpv < static_cast<FPT>(0) ? -fpv : fpv;
+}
+
+//____________________________________________________________________________//
+
+template<typename FPT>
+struct fpt_specialized_limits
+{
+ static FPT min_value() { return (std::numeric_limits<FPT>::min)(); }
+ static FPT max_value() { return (std::numeric_limits<FPT>::max)(); }
+};
+
+template<typename FPT>
+struct fpt_non_specialized_limits
+{
+ static FPT min_value() { return static_cast<FPT>(0); }
+ static FPT max_value() { return static_cast<FPT>(1000000); } // for our purposes it doesn't really matter what value is returned here
+};
+
+template<typename FPT>
+struct fpt_limits : boost::conditional<std::numeric_limits<FPT>::is_specialized,
+ fpt_specialized_limits<FPT>,
+ fpt_non_specialized_limits<FPT>
+ >::type
+{};
+
+//____________________________________________________________________________//
+
+// both f1 and f2 are unsigned here
+template<typename FPT>
+inline FPT
+safe_fpt_division( FPT f1, FPT f2 )
+{
+ // Avoid overflow.
+ if( (f2 < static_cast<FPT>(1)) && (f1 > f2*fpt_limits<FPT>::max_value()) )
+ return fpt_limits<FPT>::max_value();
+
+ // Avoid underflow.
+ if( (f1 == static_cast<FPT>(0)) ||
+ ((f2 > static_cast<FPT>(1)) && (f1 < f2*fpt_limits<FPT>::min_value())) )
+ return static_cast<FPT>(0);
+
+ return f1/f2;
+}
+
+//____________________________________________________________________________//
+
+template<typename FPT, typename ToleranceType>
+inline FPT
+fraction_tolerance( ToleranceType tolerance )
+{
+ return static_cast<FPT>(tolerance);
+}
+
+//____________________________________________________________________________//
+
+template<typename FPT2, typename FPT>
+inline FPT2
+fraction_tolerance( percent_tolerance_t<FPT> tolerance )
+{
+ return FPT2(tolerance.m_value)*FPT2(0.01);
+}
+
+//____________________________________________________________________________//
+
+} // namespace fpc_detail
+
+// ************************************************************************** //
+// ************** close_at_tolerance ************** //
+// ************************************************************************** //
+
+
+/*!@brief Predicate for comparing floating point numbers
+ *
+ * This predicate is used to compare floating point numbers. In addition the comparison produces maximum
+ * related differnce, which can be used to generate detailed error message
+ * The methods for comparing floating points are detailed in the documentation. The method is chosen
+ * by the @ref boost::math::fpc::strength given at construction.
+ */
+template<typename FPT>
+class close_at_tolerance {
+public:
+ // Public typedefs
+ typedef bool result_type;
+
+ // Constructor
+ template<typename ToleranceType>
+ explicit close_at_tolerance( ToleranceType tolerance, fpc::strength fpc_strength = FPC_STRONG )
+ : m_fraction_tolerance( fpc_detail::fraction_tolerance<FPT>( tolerance ) )
+ , m_strength( fpc_strength )
+ , m_tested_rel_diff( 0 )
+ {
+ BOOST_ASSERT_MSG( m_fraction_tolerance >= FPT(0), "tolerance must not be negative!" ); // no reason for tolerance to be negative
+ }
+
+ // Access methods
+ //! Returns the tolerance
+ FPT fraction_tolerance() const { return m_fraction_tolerance; }
+
+ //! Returns the comparison method
+ fpc::strength strength() const { return m_strength; }
+
+ //! Returns the failing fraction
+ FPT tested_rel_diff() const { return m_tested_rel_diff; }
+
+ /*! Compares two floating point numbers a and b such that their "left" relative difference |a-b|/a and/or
+ * "right" relative difference |a-b|/b does not exceed specified relative (fraction) tolerance.
+ *
+ * @param[in] left first floating point number to be compared
+ * @param[in] right second floating point number to be compared
+ *
+ * What is reported by @c tested_rel_diff in case of failure depends on the comparison method:
+ * - for @c FPC_STRONG: the max of the two fractions
+ * - for @c FPC_WEAK: the min of the two fractions
+ * The rationale behind is to report the tolerance to set in order to make a test pass.
+ */
+ bool operator()( FPT left, FPT right ) const
+ {
+ FPT diff = fpc_detail::fpt_abs<FPT>( left - right );
+ FPT fraction_of_right = fpc_detail::safe_fpt_division( diff, fpc_detail::fpt_abs( right ) );
+ FPT fraction_of_left = fpc_detail::safe_fpt_division( diff, fpc_detail::fpt_abs( left ) );
+
+ FPT max_rel_diff = (std::max)( fraction_of_left, fraction_of_right );
+ FPT min_rel_diff = (std::min)( fraction_of_left, fraction_of_right );
+
+ m_tested_rel_diff = m_strength == FPC_STRONG ? max_rel_diff : min_rel_diff;
+
+ return m_tested_rel_diff <= m_fraction_tolerance;
+ }
+
+private:
+ // Data members
+ FPT m_fraction_tolerance;
+ fpc::strength m_strength;
+ mutable FPT m_tested_rel_diff;
+};
+
+// ************************************************************************** //
+// ************** small_with_tolerance ************** //
+// ************************************************************************** //
+
+
+/*!@brief Predicate for comparing floating point numbers against 0
+ *
+ * Serves the same purpose as boost::math::fpc::close_at_tolerance, but used when one
+ * of the operand is null.
+ */
+template<typename FPT>
+class small_with_tolerance {
+public:
+ // Public typedefs
+ typedef bool result_type;
+
+ // Constructor
+ explicit small_with_tolerance( FPT tolerance ) // <= absolute tolerance
+ : m_tolerance( tolerance )
+ {
+ BOOST_ASSERT( m_tolerance >= FPT(0) ); // no reason for the tolerance to be negative
+ }
+
+ // Action method
+ bool operator()( FPT fpv ) const
+ {
+ return fpc::fpc_detail::fpt_abs( fpv ) < m_tolerance;
+ }
+
+private:
+ // Data members
+ FPT m_tolerance;
+};
+
+// ************************************************************************** //
+// ************** is_small ************** //
+// ************************************************************************** //
+
+template<typename FPT>
+inline bool
+is_small( FPT fpv, FPT tolerance )
+{
+ return small_with_tolerance<FPT>( tolerance )( fpv );
+}
+
+//____________________________________________________________________________//
+
+} // namespace fpc
+} // namespace math
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_FLOATING_POINT_COMAPARISON_HPP_071894GER
diff --git a/boost/test/tools/fpc_op.hpp b/boost/test/tools/fpc_op.hpp
new file mode 100644
index 0000000000..a2513ccfa3
--- /dev/null
+++ b/boost/test/tools/fpc_op.hpp
@@ -0,0 +1,224 @@
+// (C) Copyright Gennadiy Rozental 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/test for the library home page.
+//
+//!@file
+//!@brief Floating point comparison with enhanced reporting
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_FPC_OP_HPP_050915GER
+#define BOOST_TEST_TOOLS_FPC_OP_HPP_050915GER
+
+// Boost.Test
+#include <boost/test/tools/assertion.hpp>
+
+#include <boost/test/tools/floating_point_comparison.hpp>
+#include <boost/test/tools/fpc_tolerance.hpp>
+
+// Boost
+#include <boost/type_traits/common_type.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+namespace assertion {
+namespace op {
+
+// ************************************************************************** //
+// ************** fpctraits ************** //
+// ************************************************************************** //
+// set of floating point comparison traits per comparison OP
+
+template<typename OP>
+struct fpctraits {
+ static const bool cmp_direct = true;
+};
+
+template <typename Lhs, typename Rhs>
+struct fpctraits<op::NE<Lhs,Rhs> > {
+ static const bool cmp_direct = false;
+};
+
+template <typename Lhs, typename Rhs>
+struct fpctraits<op::LT<Lhs,Rhs> > {
+ static const bool cmp_direct = false;
+};
+
+template <typename Lhs, typename Rhs>
+struct fpctraits<op::GT<Lhs,Rhs> > {
+ static const bool cmp_direct = false;
+};
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** set of overloads to select correct fpc algo ************** //
+// ************************************************************************** //
+// we really only care about EQ vs NE. All other comparisons use direct first
+// and then need EQ. For example a < b (tolerance t) IFF a < b OR a == b (tolerance t)
+
+template <typename FPT, typename Lhs, typename Rhs, typename OP>
+inline assertion_result
+compare_fpv( Lhs const& lhs, Rhs const& rhs, OP* )
+{
+ fpc::close_at_tolerance<FPT> P( fpc_tolerance<FPT>(), fpc::FPC_STRONG );
+
+ assertion_result ar( P( lhs, rhs ) );
+ if( !ar )
+ ar.message() << "Relative difference exceeds tolerance ["
+ << P.tested_rel_diff() << " > " << P.fraction_tolerance() << ']';
+ return ar;
+}
+
+//____________________________________________________________________________//
+
+template <typename FPT, typename OP>
+inline assertion_result
+compare_fpv_near_zero( FPT const& fpv, OP* )
+{
+ fpc::small_with_tolerance<FPT> P( fpc_tolerance<FPT>() );
+
+ assertion_result ar( P( fpv ) );
+ if( !ar )
+ ar.message() << "Absolute value exceeds tolerance [|" << fpv << "| > "<< fpc_tolerance<FPT>() << ']';
+
+ return ar;
+}
+
+//____________________________________________________________________________//
+
+template <typename FPT, typename Lhs, typename Rhs>
+inline assertion_result
+compare_fpv( Lhs const& lhs, Rhs const& rhs, op::NE<Lhs,Rhs>* )
+{
+ fpc::close_at_tolerance<FPT> P( fpc_tolerance<FPT>(), fpc::FPC_WEAK );
+
+ assertion_result ar( !P( lhs, rhs ) );
+ if( !ar )
+ ar.message() << "Relative difference is within tolerance ["
+ << P.tested_rel_diff() << " < " << fpc_tolerance<FPT>() << ']';
+
+ return ar;
+}
+
+//____________________________________________________________________________//
+
+template <typename FPT, typename Lhs, typename Rhs>
+inline assertion_result
+compare_fpv_near_zero( FPT const& fpv, op::NE<Lhs,Rhs>* )
+{
+ fpc::small_with_tolerance<FPT> P( fpc_tolerance<FPT>() );
+
+ assertion_result ar( !P( fpv ) );
+ if( !ar )
+ ar.message() << "Absolute value is within tolerance [|" << fpv << "| < "<< fpc_tolerance<FPT>() << ']';
+ return ar;
+}
+
+//____________________________________________________________________________//
+
+template <typename FPT, typename Lhs, typename Rhs>
+inline assertion_result
+compare_fpv( Lhs const& lhs, Rhs const& rhs, op::LT<Lhs,Rhs>* )
+{
+ return lhs >= rhs ? assertion_result( false ) : compare_fpv<FPT>( lhs, rhs, (op::NE<Lhs,Rhs>*)0 );
+}
+
+template <typename FPT, typename Lhs, typename Rhs>
+inline assertion_result
+compare_fpv_near_zero( FPT const& fpv, op::LT<Lhs,Rhs>* )
+{
+ return fpv >= 0 ? assertion_result( false ) : compare_fpv_near_zero( fpv, (op::NE<Lhs,Rhs>*)0 );
+}
+
+//____________________________________________________________________________//
+
+template <typename FPT, typename Lhs, typename Rhs>
+inline assertion_result
+compare_fpv( Lhs const& lhs, Rhs const& rhs, op::GT<Lhs,Rhs>* )
+{
+ return lhs <= rhs ? assertion_result( false ) : compare_fpv<FPT>( lhs, rhs, (op::NE<Lhs,Rhs>*)0 );
+}
+
+template <typename FPT, typename Lhs, typename Rhs>
+inline assertion_result
+compare_fpv_near_zero( FPT const& fpv, op::GT<Lhs,Rhs>* )
+{
+ return fpv <= 0 ? assertion_result( false ) : compare_fpv_near_zero( fpv, (op::NE<Lhs,Rhs>*)0 );
+}
+
+
+//____________________________________________________________________________//
+
+#define DEFINE_FPV_COMPARISON( oper, name, rev ) \
+template<typename Lhs,typename Rhs> \
+struct name<Lhs,Rhs,typename boost::enable_if_c< \
+ (fpc::tolerance_based<Lhs>::value && \
+ fpc::tolerance_based<Rhs>::value)>::type> { \
+public: \
+ typedef typename common_type<Lhs,Rhs>::type FPT; \
+ typedef name<Lhs,Rhs> OP; \
+ \
+ typedef assertion_result result_type; \
+ \
+ static bool \
+ eval_direct( Lhs const& lhs, Rhs const& rhs) \
+ { \
+ return lhs oper rhs; \
+ } \
+ \
+ static assertion_result \
+ eval( Lhs const& lhs, Rhs const& rhs) \
+ { \
+ if( lhs == 0 ) \
+ return compare_fpv_near_zero(rhs, (OP*)0); \
+ \
+ if( rhs == 0 ) \
+ return compare_fpv_near_zero(lhs, (OP*)0); \
+ \
+ bool direct_res = eval_direct( lhs, rhs ); \
+ \
+ if((direct_res && fpctraits<OP>::cmp_direct) \
+ || fpc_tolerance<FPT>() == FPT(0)) \
+ return direct_res; \
+ \
+ return compare_fpv<FPT>(lhs, rhs, (OP*)0); \
+ } \
+ \
+ template<typename PrevExprType> \
+ static void \
+ report( std::ostream& ostr, \
+ PrevExprType const& lhs, \
+ Rhs const& rhs ) \
+ { \
+ lhs.report( ostr ); \
+ ostr << revert() \
+ << tt_detail::print_helper( rhs ); \
+ } \
+ \
+ static char const* revert() \
+ { return " " #rev " "; } \
+}; \
+/**/
+
+BOOST_TEST_FOR_EACH_COMP_OP( DEFINE_FPV_COMPARISON )
+#undef DEFINE_FPV_COMPARISON
+
+//____________________________________________________________________________//
+
+} // namespace op
+} // namespace assertion
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_FPC_OP_HPP_050915GER
+
diff --git a/boost/test/tools/fpc_tolerance.hpp b/boost/test/tools/fpc_tolerance.hpp
new file mode 100644
index 0000000000..013b571ded
--- /dev/null
+++ b/boost/test/tools/fpc_tolerance.hpp
@@ -0,0 +1,103 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 74248 $
+//
+// Description : FPC tools tolerance holder
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_FPC_TOLERANCE_HPP_121612GER
+#define BOOST_TEST_TOOLS_FPC_TOLERANCE_HPP_121612GER
+
+// Boost Test
+#include <boost/test/tree/decorator.hpp>
+#include <boost/test/tools/floating_point_comparison.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+
+namespace fpc = math::fpc;
+
+// ************************************************************************** //
+// ************** floating point comparison tolerance ************** //
+// ************************************************************************** //
+
+template<typename FPT>
+inline FPT&
+fpc_tolerance()
+{
+ static FPT s_value = 0;
+ return s_value;
+}
+
+//____________________________________________________________________________//
+
+template<typename FPT>
+struct local_fpc_tolerance {
+ local_fpc_tolerance( FPT fraction_tolerance ) : m_old_tolerance( fpc_tolerance<FPT>() )
+ {
+ fpc_tolerance<FPT>() = fraction_tolerance;
+ }
+
+ ~local_fpc_tolerance()
+ {
+ if( m_old_tolerance != (FPT)-1 )
+ fpc_tolerance<FPT>() = m_old_tolerance;
+ }
+
+private:
+ // Data members
+ FPT m_old_tolerance;
+};
+
+//____________________________________________________________________________//
+
+} // namespace test_tools
+
+// ************************************************************************** //
+// ************** decorator::tolerance ************** //
+// ************************************************************************** //
+
+namespace unit_test {
+namespace decorator {
+
+template<typename FPT>
+inline fixture_t
+tolerance( FPT v )
+{
+ return fixture_t( test_unit_fixture_ptr(
+ new unit_test::class_based_fixture<test_tools::local_fpc_tolerance<FPT>,FPT>( v ) ) );
+}
+
+//____________________________________________________________________________//
+
+template<typename FPT>
+inline fixture_t
+tolerance( test_tools::fpc::percent_tolerance_t<FPT> v )
+{
+ return fixture_t( test_unit_fixture_ptr(
+ new unit_test::class_based_fixture<test_tools::local_fpc_tolerance<FPT>,FPT>( boost::math::fpc::fpc_detail::fraction_tolerance<FPT>( v ) ) ) );
+}
+
+//____________________________________________________________________________//
+
+} // namespace decorator
+
+using decorator::tolerance;
+
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_FPC_TOLERANCE_HPP_121612GER
diff --git a/boost/test/tools/interface.hpp b/boost/test/tools/interface.hpp
new file mode 100644
index 0000000000..fe51021303
--- /dev/null
+++ b/boost/test/tools/interface.hpp
@@ -0,0 +1,376 @@
+// (C) Copyright Gennadiy Rozental 2001-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 81247 $
+//
+// Description : contains definition for all test tools in test toolbox
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_INTERFACE_HPP_111712GER
+#define BOOST_TEST_TOOLS_INTERFACE_HPP_111712GER
+
+// Boost.Test
+#include <boost/test/unit_test_log.hpp>
+#ifdef BOOST_TEST_TOOLS_DEBUGGABLE
+#include <boost/test/debug.hpp>
+#endif
+#ifdef BOOST_NO_CXX11_AUTO_DECLARATIONS
+#include <boost/test/tools/detail/expression_holder.hpp>
+#endif
+
+#include <boost/test/detail/pp_variadic.hpp>
+
+#ifdef BOOST_TEST_NO_OLD_TOOLS
+#include <boost/preprocessor/seq/to_tuple.hpp>
+
+#include <iterator>
+#endif // BOOST_TEST_NO_OLD_TOOLS
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** BOOST_TEST_<level> ************** //
+// ************************************************************************** //
+
+#ifdef BOOST_NO_CXX11_AUTO_DECLARATIONS
+#define BOOST_TEST_BUILD_ASSERTION( P ) \
+ ::boost::test_tools::tt_detail::expression_holder const& E= \
+ ::boost::test_tools::tt_detail::hold_expression( \
+ ::boost::test_tools::assertion::seed() ->* P ) \
+/**/
+#else
+#define BOOST_TEST_BUILD_ASSERTION( P ) \
+ auto const& E = ::boost::test_tools::assertion::seed()->*P \
+/**/
+#endif
+
+//____________________________________________________________________________//
+
+// Implementation based on direct predicate evaluation
+#define BOOST_TEST_TOOL_DIRECT_IMPL( P, level, M ) \
+do { \
+ ::boost::test_tools::assertion_result res = (P); \
+ report_assertion( \
+ res, \
+ BOOST_TEST_LAZY_MSG( M ), \
+ BOOST_TEST_L(__FILE__), \
+ static_cast<std::size_t>(__LINE__), \
+ ::boost::test_tools::tt_detail::level, \
+ ::boost::test_tools::tt_detail::CHECK_MSG, \
+ 0 ); \
+} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
+/**/
+
+//____________________________________________________________________________//
+
+// Implementation based on expression template construction
+#define BOOST_TEST_TOOL_ET_IMPL( P, level ) \
+do { \
+ BOOST_TEST_PASSPOINT(); \
+ BOOST_TEST_BUILD_ASSERTION( P ); \
+ ::boost::test_tools::tt_detail:: \
+ report_assertion( \
+ E.evaluate(), \
+ BOOST_TEST_LAZY_MSG( BOOST_TEST_STRINGIZE( P ) ), \
+ BOOST_TEST_L(__FILE__), \
+ static_cast<std::size_t>(__LINE__), \
+ ::boost::test_tools::tt_detail::level, \
+ ::boost::test_tools::tt_detail::CHECK_BUILT_ASSERTION, \
+ 0 ); \
+} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
+/**/
+
+//____________________________________________________________________________//
+
+// Implementation based on expression template construction with extra tool arguments
+#define BOOST_TEST_TOOL_ET_IMPL_EX( P, level, arg ) \
+do { \
+ BOOST_TEST_PASSPOINT(); \
+ BOOST_TEST_BUILD_ASSERTION( P ); \
+ ::boost::test_tools::tt_detail:: \
+ report_assertion( \
+ ::boost::test_tools::tt_detail::assertion_evaluate(E) \
+ << arg, \
+ ::boost::test_tools::tt_detail::assertion_text( \
+ BOOST_TEST_LAZY_MSG( BOOST_TEST_STRINGIZE(P) ), \
+ BOOST_TEST_LAZY_MSG( arg ) ), \
+ BOOST_TEST_L(__FILE__), \
+ static_cast<std::size_t>(__LINE__), \
+ ::boost::test_tools::tt_detail::level, \
+ ::boost::test_tools::tt_detail::assertion_type() \
+ << arg, \
+ 0 ); \
+} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
+/**/
+
+//____________________________________________________________________________//
+
+#ifdef BOOST_TEST_TOOLS_UNDER_DEBUGGER
+
+#define BOOST_TEST_TOOL_UNIV( level, P ) \
+ BOOST_TEST_TOOL_DIRECT_IMPL( P, level, BOOST_TEST_STRINGIZE( P ) ) \
+/**/
+
+#define BOOST_TEST_TOOL_UNIV_EX( level, P, ... ) \
+ BOOST_TEST_TOOL_UNIV( level, P ) \
+/**/
+
+#elif defined(BOOST_TEST_TOOLS_DEBUGGABLE)
+
+#define BOOST_TEST_TOOL_UNIV( level, P ) \
+do { \
+ if( ::boost::debug::under_debugger() ) \
+ BOOST_TEST_TOOL_DIRECT_IMPL( P, level, BOOST_TEST_STRINGIZE( P ) ); \
+ else \
+ BOOST_TEST_TOOL_ET_IMPL( P, level ); \
+} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
+/**/
+
+#define BOOST_TEST_TOOL_UNIV_EX( level, P, ... ) \
+ BOOST_TEST_TOOL_UNIV( level, P ) \
+/**/
+
+#else
+
+#define BOOST_TEST_TOOL_UNIV( level, P ) \
+ BOOST_TEST_TOOL_ET_IMPL( P, level ) \
+/**/
+
+#define BOOST_TEST_TOOL_UNIV_EX( level, P, ... ) \
+ BOOST_TEST_TOOL_ET_IMPL_EX( P, level, __VA_ARGS__ ) \
+/**/
+
+#endif
+
+//____________________________________________________________________________//
+
+#define BOOST_TEST_WARN( ... ) BOOST_TEST_INVOKE_IF_N_ARGS( \
+ 2, BOOST_TEST_TOOL_UNIV, BOOST_TEST_TOOL_UNIV_EX, WARN, __VA_ARGS__ ) \
+/**/
+#define BOOST_TEST_CHECK( ... ) BOOST_TEST_INVOKE_IF_N_ARGS( \
+ 2, BOOST_TEST_TOOL_UNIV, BOOST_TEST_TOOL_UNIV_EX, CHECK, __VA_ARGS__ ) \
+/**/
+#define BOOST_TEST_REQUIRE( ... ) BOOST_TEST_INVOKE_IF_N_ARGS( \
+ 2, BOOST_TEST_TOOL_UNIV, BOOST_TEST_TOOL_UNIV_EX, REQUIRE, __VA_ARGS__ )\
+/**/
+
+#define BOOST_TEST( ... ) BOOST_TEST_INVOKE_IF_N_ARGS( \
+ 2, BOOST_TEST_TOOL_UNIV, BOOST_TEST_TOOL_UNIV_EX, CHECK, __VA_ARGS__ ) \
+/**/
+
+//____________________________________________________________________________//
+
+#define BOOST_TEST_ERROR( M ) BOOST_CHECK_MESSAGE( false, M )
+#define BOOST_TEST_FAIL( M ) BOOST_REQUIRE_MESSAGE( false, M )
+
+//____________________________________________________________________________//
+
+#define BOOST_TEST_IS_DEFINED( symb ) ::boost::test_tools::tt_detail::is_defined_impl( symb, BOOST_STRINGIZE(= symb) )
+
+//____________________________________________________________________________//
+
+#ifdef BOOST_TEST_NO_OLD_TOOLS
+
+#ifdef BOOST_TEST_TOOLS_UNDER_DEBUGGER
+
+#define BOOST_CHECK_THROW_IMPL(S, E, TL, Ppassed, Mpassed, Pcaught, Mcaught)\
+do { try { \
+ S; \
+ BOOST_TEST_TOOL_DIRECT_IMPL( Ppassed, TL, Mpassed ); \
+} catch( E ) { \
+ BOOST_TEST_TOOL_DIRECT_IMPL( Pcaught, TL, Mcaught ); \
+}} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
+/**/
+
+#elif defined(BOOST_TEST_TOOLS_DEBUGGABLE)
+
+#define BOOST_CHECK_THROW_IMPL(S, E, TL, Ppassed, Mpassed, Pcaught, Mcaught)\
+do { try { \
+ if( ::boost::debug::under_debugger() ) \
+ BOOST_TEST_PASSPOINT(); \
+ S; \
+ BOOST_TEST_TOOL_DIRECT_IMPL( Ppassed, TL, Mpassed ); \
+} catch( E ) { \
+ BOOST_TEST_TOOL_DIRECT_IMPL( Pcaught, TL, Mcaught ); \
+}} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
+/**/
+
+#else
+
+#define BOOST_CHECK_THROW_IMPL(S, E, TL, Ppassed, Mpassed, Pcaught, Mcaught)\
+do { try { \
+ BOOST_TEST_PASSPOINT(); \
+ S; \
+ BOOST_TEST_TOOL_DIRECT_IMPL( Ppassed, TL, Mpassed ); \
+} catch( E ) { \
+ BOOST_TEST_TOOL_DIRECT_IMPL( Pcaught, TL, Mcaught ); \
+}} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
+/**/
+
+#endif
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_THROW( S, E ) \
+ BOOST_CHECK_THROW_IMPL(S, E const&, WARN, \
+ false, "exception " BOOST_STRINGIZE(E) " is expected", \
+ true , "exception " BOOST_STRINGIZE(E) " is caught" ) \
+/**/
+#define BOOST_CHECK_THROW( S, E ) \
+ BOOST_CHECK_THROW_IMPL(S, E const&, CHECK, \
+ false, "exception " BOOST_STRINGIZE(E) " is expected", \
+ true , "exception " BOOST_STRINGIZE(E) " is caught" ) \
+/**/
+#define BOOST_REQUIRE_THROW( S, E ) \
+ BOOST_CHECK_THROW_IMPL(S, E const&, REQUIRE, \
+ false, "exception " BOOST_STRINGIZE(E) " is expected", \
+ true , "exception " BOOST_STRINGIZE(E) " is caught" ) \
+/**/
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_EXCEPTION( S, E, P ) \
+ BOOST_CHECK_THROW_IMPL(S, E const& ex, WARN, \
+ false, "exception " BOOST_STRINGIZE(E) " is expected", \
+ P(ex), "incorrect exception " BOOST_STRINGIZE(E) " is caught" ) \
+/**/
+#define BOOST_CHECK_EXCEPTION( S, E, P ) \
+ BOOST_CHECK_THROW_IMPL(S, E const& ex, CHECK, \
+ false, "exception " BOOST_STRINGIZE(E) " is expected", \
+ P(ex), "incorrect exception " BOOST_STRINGIZE(E) " is caught" ) \
+/**/
+#define BOOST_REQUIRE_EXCEPTION( S, E, P ) \
+ BOOST_CHECK_THROW_IMPL(S, E const& ex, REQUIRE, \
+ false, "exception " BOOST_STRINGIZE(E) " is expected", \
+ P(ex), "incorrect exception " BOOST_STRINGIZE(E) " is caught" ) \
+/**/
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_NO_THROW( S ) \
+ BOOST_CHECK_THROW_IMPL(S, ..., WARN, \
+ true , "no exceptions thrown by " BOOST_STRINGIZE( S ), \
+ false, "exception thrown by " BOOST_STRINGIZE( S ) ) \
+/**/
+#define BOOST_CHECK_NO_THROW( S ) \
+ BOOST_CHECK_THROW_IMPL(S, ..., CHECK, \
+ true , "no exceptions thrown by " BOOST_STRINGIZE( S ), \
+ false, "exception thrown by " BOOST_STRINGIZE( S ) ) \
+/**/
+#define BOOST_REQUIRE_NO_THROW( S ) \
+ BOOST_CHECK_THROW_IMPL(S, ..., REQUIRE, \
+ true , "no exceptions thrown by " BOOST_STRINGIZE( S ), \
+ false, "exception thrown by " BOOST_STRINGIZE( S ) ) \
+/**/
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_MESSAGE( P, M ) BOOST_TEST_TOOL_DIRECT_IMPL( P, WARN, M )
+#define BOOST_CHECK_MESSAGE( P, M ) BOOST_TEST_TOOL_DIRECT_IMPL( P, CHECK, M )
+#define BOOST_REQUIRE_MESSAGE( P, M ) BOOST_TEST_TOOL_DIRECT_IMPL( P, REQUIRE, M )
+
+//____________________________________________________________________________//
+
+////////////////////////////////////////////////////////////////////////////////
+///////////////////////////// DEPRECATED TOOLS /////////////////////////////
+
+#define BOOST_WARN( P ) BOOST_TEST_WARN( P )
+#define BOOST_CHECK( P ) BOOST_TEST_CHECK( P )
+#define BOOST_REQUIRE( P ) BOOST_TEST_REQUIRE( P )
+
+//____________________________________________________________________________//
+
+#define BOOST_ERROR( M ) BOOST_TEST_ERROR( M )
+#define BOOST_FAIL( M ) BOOST_TEST_FAIL( M )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_EQUAL( L, R ) BOOST_TEST_WARN( L == R )
+#define BOOST_CHECK_EQUAL( L, R ) BOOST_TEST_CHECK( L == R )
+#define BOOST_REQUIRE_EQUAL( L, R ) BOOST_TEST_REQUIRE( L == R )
+
+#define BOOST_WARN_NE( L, R ) BOOST_TEST_WARN( L != R )
+#define BOOST_CHECK_NE( L, R ) BOOST_TEST_CHECK( L != R )
+#define BOOST_REQUIRE_NE( L, R ) BOOST_TEST_REQUIRE( L != R )
+
+#define BOOST_WARN_LT( L, R ) BOOST_TEST_WARN( L < R )
+#define BOOST_CHECK_LT( L, R ) BOOST_TEST_CHECK( L < R )
+#define BOOST_REQUIRE_LT( L, R ) BOOST_TEST_REQUIRE( L < R )
+
+#define BOOST_WARN_LE( L, R ) BOOST_TEST_WARN( L <= R )
+#define BOOST_CHECK_LE( L, R ) BOOST_TEST_CHECK( L <= R )
+#define BOOST_REQUIRE_LE( L, R ) BOOST_TEST_REQUIRE( L <= R )
+
+#define BOOST_WARN_GT( L, R ) BOOST_TEST_WARN( L > R )
+#define BOOST_CHECK_GT( L, R ) BOOST_TEST_CHECK( L > R )
+#define BOOST_REQUIRE_GT( L, R ) BOOST_TEST_REQUIRE( L > R )
+
+#define BOOST_WARN_GE( L, R ) BOOST_TEST_WARN( L >= R )
+#define BOOST_CHECK_GE( L, R ) BOOST_TEST_CHECK( L >= R )
+#define BOOST_REQUIRE_GE( L, R ) BOOST_TEST_REQUIRE( L >= R )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_CLOSE( L, R, T ) BOOST_TEST_WARN( L == R, T % ::boost::test_tools::tolerance() )
+#define BOOST_CHECK_CLOSE( L, R, T ) BOOST_TEST_CHECK( L == R, T % ::boost::test_tools::tolerance() )
+#define BOOST_REQUIRE_CLOSE( L, R, T ) BOOST_TEST_REQUIRE( L == R, T % ::boost::test_tools::tolerance() )
+
+#define BOOST_WARN_CLOSE_FRACTION(L, R, T) BOOST_TEST_WARN( L == R, ::boost::test_tools::tolerance( T ) )
+#define BOOST_CHECK_CLOSE_FRACTION(L, R, T) BOOST_TEST_CHECK( L == R, ::boost::test_tools::tolerance( T ) )
+#define BOOST_REQUIRE_CLOSE_FRACTION(L,R,T) BOOST_TEST_REQUIRE( L == R, ::boost::test_tools::tolerance( T ) )
+
+#define BOOST_WARN_SMALL( FPV, T ) BOOST_TEST_WARN( FPV == 0., ::boost::test_tools::tolerance( T ) )
+#define BOOST_CHECK_SMALL( FPV, T ) BOOST_TEST_CHECK( FPV == 0., ::boost::test_tools::tolerance( T ) )
+#define BOOST_REQUIRE_SMALL( FPV, T ) BOOST_TEST_REQUIRE( FPV == 0., ::boost::test_tools::tolerance( T ) )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
+ BOOST_TEST_WARN( ::boost::test_tools::tt_detail::make_it_pair(L_begin, L_end) ==\
+ ::boost::test_tools::tt_detail::make_it_pair(R_begin, R_end), \
+ ::boost::test_tools::per_element() ) \
+/**/
+
+#define BOOST_CHECK_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
+ BOOST_TEST_CHECK( ::boost::test_tools::tt_detail::make_it_pair(L_begin, L_end) ==\
+ ::boost::test_tools::tt_detail::make_it_pair(R_begin, R_end), \
+ ::boost::test_tools::per_element() ) \
+/**/
+
+#define BOOST_REQUIRE_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
+ BOOST_TEST_REQUIRE( ::boost::test_tools::tt_detail::make_it_pair(L_begin, L_end) ==\
+ ::boost::test_tools::tt_detail::make_it_pair(R_begin, R_end), \
+ ::boost::test_tools::per_element() ) \
+/**/
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_BITWISE_EQUAL( L, R ) BOOST_TEST_WARN( L == R, ::boost::test_tools::bitwise() )
+#define BOOST_CHECK_BITWISE_EQUAL( L, R ) BOOST_TEST_CHECK( L == R, ::boost::test_tools::bitwise() )
+#define BOOST_REQUIRE_BITWISE_EQUAL( L, R ) BOOST_TEST_REQUIRE( L == R, ::boost::test_tools::bitwise() )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_PREDICATE( P, ARGS ) BOOST_TEST_WARN( P BOOST_PP_SEQ_TO_TUPLE(ARGS) )
+#define BOOST_CHECK_PREDICATE( P, ARGS ) BOOST_TEST_CHECK( P BOOST_PP_SEQ_TO_TUPLE(ARGS) )
+#define BOOST_REQUIRE_PREDICATE( P, ARGS ) BOOST_TEST_REQUIRE( P BOOST_PP_SEQ_TO_TUPLE(ARGS) )
+
+//____________________________________________________________________________//
+
+#define BOOST_IS_DEFINED( symb ) ::boost::test_tools::tt_detail::is_defined_impl( #symb, BOOST_STRINGIZE(= symb) )
+
+//____________________________________________________________________________//
+
+#endif // BOOST_TEST_NO_OLD_TOOLS
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_INTERFACE_HPP_111712GER
diff --git a/boost/test/tools/old/impl.hpp b/boost/test/tools/old/impl.hpp
new file mode 100644
index 0000000000..e5414f566e
--- /dev/null
+++ b/boost/test/tools/old/impl.hpp
@@ -0,0 +1,358 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 74248 $
+//
+// Description : implementation details for old toolbox
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_OLD_IMPL_HPP_012705GER
+#define BOOST_TEST_TOOLS_OLD_IMPL_HPP_012705GER
+
+// Boost.Test
+#include <boost/test/unit_test_log.hpp>
+#include <boost/test/tools/assertion_result.hpp>
+#include <boost/test/tools/floating_point_comparison.hpp>
+
+#include <boost/test/tools/detail/fwd.hpp>
+#include <boost/test/tools/detail/print_helper.hpp>
+
+// Boost
+#include <boost/limits.hpp>
+#include <boost/numeric/conversion/conversion_traits.hpp> // for numeric::conversion_traits
+#include <boost/type_traits/is_array.hpp>
+
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/arithmetic/add.hpp>
+
+// STL
+#include <cstddef> // for std::size_t
+#include <climits> // for CHAR_BIT
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+namespace tt_detail {
+
+// ************************************************************************** //
+// ************** old TOOLBOX Implementation ************** //
+// ************************************************************************** //
+
+// This function adds level of indirection, but it makes sure we evaluate predicate
+// arguments only once
+
+#ifndef BOOST_TEST_PROD
+#define TEMPL_PARAMS( z, m, dummy ) , typename BOOST_JOIN( Arg, m )
+
+#define FUNC_PARAMS( z, m, dummy ) \
+ , BOOST_JOIN( Arg, m ) const& BOOST_JOIN( arg, m ) \
+ , char const* BOOST_JOIN( BOOST_JOIN( arg, m ), _descr ) \
+/**/
+
+#define PRED_PARAMS( z, m, dummy ) BOOST_PP_COMMA_IF( m ) BOOST_JOIN( arg, m )
+
+#define ARG_INFO( z, m, dummy ) \
+ , BOOST_JOIN( BOOST_JOIN( arg, m ), _descr ) \
+ , &static_cast<const unit_test::lazy_ostream&>(unit_test::lazy_ostream::instance() \
+ << ::boost::test_tools::tt_detail::print_helper( BOOST_JOIN( arg, m ) )) \
+/**/
+
+#define IMPL_FRWD( z, n, dummy ) \
+template<typename Pred \
+ BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), TEMPL_PARAMS, _ )> \
+inline bool \
+check_frwd( Pred P, unit_test::lazy_ostream const& assertion_descr, \
+ const_string file_name, std::size_t line_num, \
+ tool_level tl, check_type ct \
+ BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), FUNC_PARAMS, _ ) \
+) \
+{ \
+ return \
+ report_assertion( P( BOOST_PP_REPEAT_ ## z(BOOST_PP_ADD(n, 1), PRED_PARAMS,_) ),\
+ assertion_descr, file_name, line_num, tl, ct, \
+ BOOST_PP_ADD( n, 1 ) \
+ BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), ARG_INFO, _ ) \
+ ); \
+} \
+/**/
+
+#ifndef BOOST_TEST_MAX_PREDICATE_ARITY
+#define BOOST_TEST_MAX_PREDICATE_ARITY 5
+#endif
+
+BOOST_PP_REPEAT( BOOST_TEST_MAX_PREDICATE_ARITY, IMPL_FRWD, _ )
+
+#undef TEMPL_PARAMS
+#undef FUNC_PARAMS
+#undef PRED_INFO
+#undef ARG_INFO
+#undef IMPL_FRWD
+
+#endif
+
+//____________________________________________________________________________//
+
+template <class Left, class Right>
+inline assertion_result equal_impl( Left const& left, Right const& right )
+{
+ return left == right;
+}
+
+//____________________________________________________________________________//
+
+inline assertion_result equal_impl( char* left, char const* right ) { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }
+inline assertion_result equal_impl( char const* left, char* right ) { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }
+inline assertion_result equal_impl( char* left, char* right ) { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }
+
+#if !defined( BOOST_NO_CWCHAR )
+assertion_result BOOST_TEST_DECL equal_impl( wchar_t const* left, wchar_t const* right );
+inline assertion_result equal_impl( wchar_t* left, wchar_t const* right ) { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
+inline assertion_result equal_impl( wchar_t const* left, wchar_t* right ) { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
+inline assertion_result equal_impl( wchar_t* left, wchar_t* right ) { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
+#endif
+
+//____________________________________________________________________________//
+
+struct equal_impl_frwd {
+ template <typename Left, typename Right>
+ inline assertion_result
+ call_impl( Left const& left, Right const& right, mpl::false_ ) const
+ {
+ return equal_impl( left, right );
+ }
+
+ template <typename Left, typename Right>
+ inline assertion_result
+ call_impl( Left const& left, Right const& right, mpl::true_ ) const
+ {
+ return (*this)( right, &left[0] );
+ }
+
+ template <typename Left, typename Right>
+ inline assertion_result
+ operator()( Left const& left, Right const& right ) const
+ {
+ typedef typename is_array<Left>::type left_is_array;
+ return call_impl( left, right, left_is_array() );
+ }
+};
+
+//____________________________________________________________________________//
+
+struct ne_impl {
+ template <class Left, class Right>
+ assertion_result operator()( Left const& left, Right const& right )
+ {
+ return !equal_impl_frwd()( left, right );
+ }
+};
+
+//____________________________________________________________________________//
+
+struct lt_impl {
+ template <class Left, class Right>
+ assertion_result operator()( Left const& left, Right const& right )
+ {
+ return left < right;
+ }
+};
+
+//____________________________________________________________________________//
+
+struct le_impl {
+ template <class Left, class Right>
+ assertion_result operator()( Left const& left, Right const& right )
+ {
+ return left <= right;
+ }
+};
+
+//____________________________________________________________________________//
+
+struct gt_impl {
+ template <class Left, class Right>
+ assertion_result operator()( Left const& left, Right const& right )
+ {
+ return left > right;
+ }
+};
+
+//____________________________________________________________________________//
+
+struct ge_impl {
+ template <class Left, class Right>
+ assertion_result operator()( Left const& left, Right const& right )
+ {
+ return left >= right;
+ }
+};
+
+//____________________________________________________________________________//
+
+struct equal_coll_impl {
+ template <typename Left, typename Right>
+ assertion_result operator()( Left left_begin, Left left_end, Right right_begin, Right right_end )
+ {
+ assertion_result pr( true );
+ std::size_t pos = 0;
+
+ for( ; left_begin != left_end && right_begin != right_end; ++left_begin, ++right_begin, ++pos ) {
+ if( *left_begin != *right_begin ) {
+ pr = false;
+ pr.message() << "\nMismatch at position " << pos << ": "
+ << ::boost::test_tools::tt_detail::print_helper(*left_begin)
+ << " != "
+ << ::boost::test_tools::tt_detail::print_helper(*right_begin);
+ }
+ }
+
+ if( left_begin != left_end ) {
+ std::size_t r_size = pos;
+ while( left_begin != left_end ) {
+ ++pos;
+ ++left_begin;
+ }
+
+ pr = false;
+ pr.message() << "\nCollections size mismatch: " << pos << " != " << r_size;
+ }
+
+ if( right_begin != right_end ) {
+ std::size_t l_size = pos;
+ while( right_begin != right_end ) {
+ ++pos;
+ ++right_begin;
+ }
+
+ pr = false;
+ pr.message() << "\nCollections size mismatch: " << l_size << " != " << pos;
+ }
+
+ return pr;
+ }
+};
+
+//____________________________________________________________________________//
+
+struct bitwise_equal_impl {
+ template <class Left, class Right>
+ assertion_result operator()( Left const& left, Right const& right )
+ {
+ assertion_result pr( true );
+
+ std::size_t left_bit_size = sizeof(Left)*CHAR_BIT;
+ std::size_t right_bit_size = sizeof(Right)*CHAR_BIT;
+
+ static Left const leftOne( 1 );
+ static Right const rightOne( 1 );
+
+ std::size_t total_bits = left_bit_size < right_bit_size ? left_bit_size : right_bit_size;
+
+ for( std::size_t counter = 0; counter < total_bits; ++counter ) {
+ if( ( left & ( leftOne << counter ) ) != ( right & ( rightOne << counter ) ) ) {
+ pr = false;
+ pr.message() << "\nMismatch at position " << counter;
+ }
+ }
+
+ if( left_bit_size != right_bit_size ) {
+ pr = false;
+ pr.message() << "\nOperands bit sizes mismatch: " << left_bit_size << " != " << right_bit_size;
+ }
+
+ return pr;
+ }
+};
+
+//____________________________________________________________________________//
+
+template<typename FPT1, typename FPT2>
+struct comp_supertype {
+ // deduce "better" type from types of arguments being compared
+ // if one type is floating and the second integral we use floating type and
+ // value of integral type is promoted to the floating. The same for float and double
+ // But we don't want to compare two values of integral types using this tool.
+ typedef typename numeric::conversion_traits<FPT1,FPT2>::supertype type;
+ BOOST_STATIC_ASSERT_MSG( !is_integral<type>::value, "Only floating-point types can be compared!");
+};
+
+} // namespace tt_detail
+
+namespace fpc = math::fpc;
+
+// ************************************************************************** //
+// ************** check_is_close ************** //
+// ************************************************************************** //
+
+struct BOOST_TEST_DECL check_is_close_t {
+ // Public typedefs
+ typedef assertion_result result_type;
+
+ template<typename FPT1, typename FPT2, typename ToleranceType>
+ assertion_result
+ operator()( FPT1 left, FPT2 right, ToleranceType tolerance ) const
+ {
+ fpc::close_at_tolerance<typename tt_detail::comp_supertype<FPT1,FPT2>::type> pred( tolerance, fpc::FPC_STRONG );
+
+ assertion_result ar( pred( left, right ) );
+
+ if( !ar )
+ ar.message() << pred.tested_rel_diff();
+
+ return ar;
+ }
+};
+
+//____________________________________________________________________________//
+
+template<typename FPT1, typename FPT2, typename ToleranceType>
+inline assertion_result
+check_is_close( FPT1 left, FPT2 right, ToleranceType tolerance )
+{
+ return check_is_close_t()( left, right, tolerance );
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** check_is_small ************** //
+// ************************************************************************** //
+
+struct BOOST_TEST_DECL check_is_small_t {
+ // Public typedefs
+ typedef bool result_type;
+
+ template<typename FPT>
+ bool
+ operator()( FPT fpv, FPT tolerance ) const
+ {
+ return fpc::is_small( fpv, tolerance );
+ }
+};
+
+//____________________________________________________________________________//
+
+template<typename FPT>
+inline bool
+check_is_small( FPT fpv, FPT tolerance )
+{
+ return fpc::is_small( fpv, tolerance );
+}
+
+//____________________________________________________________________________//
+
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_OLD_IMPL_HPP_012705GER
diff --git a/boost/test/tools/old/interface.hpp b/boost/test/tools/old/interface.hpp
new file mode 100644
index 0000000000..0c35c82b87
--- /dev/null
+++ b/boost/test/tools/old/interface.hpp
@@ -0,0 +1,278 @@
+// (C) Copyright Gennadiy Rozental 2001-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 81247 $
+//
+// Description : contains definition for all test tools in old test toolbox
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_OLD_INTERFACE_HPP_111712GER
+#define BOOST_TEST_TOOLS_OLD_INTERFACE_HPP_111712GER
+
+// Boost
+#include <boost/preprocessor/seq/for_each.hpp>
+#include <boost/preprocessor/seq/size.hpp>
+#include <boost/preprocessor/seq/to_tuple.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** TOOL BOX ************** //
+// ************************************************************************** //
+
+// In macros below following argument abbreviations are used:
+// P - predicate
+// M - message
+// S - statement
+// E - exception
+// L - left argument
+// R - right argument
+// TL - tool level
+// CT - check type
+// ARGS - arguments list (as PP sequence)
+
+// frwd_type:
+// 0 - args exists and need to be forwarded; call check_frwd
+// 1 - args exists, but do not need to be forwarded; call report_assertion directly
+// 2 - no arguments; call report_assertion directly
+
+#define BOOST_TEST_TOOL_PASS_PRED0( P, ARGS ) P
+#define BOOST_TEST_TOOL_PASS_PRED1( P, ARGS ) P BOOST_PP_SEQ_TO_TUPLE(ARGS)
+#define BOOST_TEST_TOOL_PASS_PRED2( P, ARGS ) P
+
+#define BOOST_TEST_TOOL_PASS_ARG( r, _, arg ) , arg, BOOST_STRINGIZE( arg )
+#define BOOST_TEST_TOOL_PASS_ARG_DSCR( r, _, arg ) , BOOST_STRINGIZE( arg )
+
+#define BOOST_TEST_TOOL_PASS_ARGS0( ARGS ) \
+ BOOST_PP_SEQ_FOR_EACH( BOOST_TEST_TOOL_PASS_ARG, _, ARGS )
+#define BOOST_TEST_TOOL_PASS_ARGS1( ARGS ) \
+ , BOOST_PP_SEQ_SIZE(ARGS) BOOST_PP_SEQ_FOR_EACH( BOOST_TEST_TOOL_PASS_ARG_DSCR, _, ARGS )
+#define BOOST_TEST_TOOL_PASS_ARGS2( ARGS ) \
+ , 0
+
+#define BOOST_TEST_TOOL_IMPL( frwd_type, P, assertion_descr, TL, CT, ARGS ) \
+do { \
+ BOOST_TEST_PASSPOINT(); \
+ ::boost::test_tools::tt_detail:: \
+ BOOST_PP_IF( frwd_type, report_assertion, check_frwd ) ( \
+ BOOST_JOIN( BOOST_TEST_TOOL_PASS_PRED, frwd_type )( P, ARGS ), \
+ BOOST_TEST_LAZY_MSG( assertion_descr ), \
+ BOOST_TEST_L(__FILE__), \
+ static_cast<std::size_t>(__LINE__), \
+ ::boost::test_tools::tt_detail::TL, \
+ ::boost::test_tools::tt_detail::CT \
+ BOOST_JOIN( BOOST_TEST_TOOL_PASS_ARGS, frwd_type )( ARGS ) ); \
+} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
+/**/
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN( P ) BOOST_TEST_TOOL_IMPL( 2, \
+ (P), BOOST_TEST_STRINGIZE( P ), WARN, CHECK_PRED, _ )
+#define BOOST_CHECK( P ) BOOST_TEST_TOOL_IMPL( 2, \
+ (P), BOOST_TEST_STRINGIZE( P ), CHECK, CHECK_PRED, _ )
+#define BOOST_REQUIRE( P ) BOOST_TEST_TOOL_IMPL( 2, \
+ (P), BOOST_TEST_STRINGIZE( P ), REQUIRE, CHECK_PRED, _ )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_MESSAGE( P, M ) BOOST_TEST_TOOL_IMPL( 2, (P), M, WARN, CHECK_MSG, _ )
+#define BOOST_CHECK_MESSAGE( P, M ) BOOST_TEST_TOOL_IMPL( 2, (P), M, CHECK, CHECK_MSG, _ )
+#define BOOST_REQUIRE_MESSAGE( P, M ) BOOST_TEST_TOOL_IMPL( 2, (P), M, REQUIRE, CHECK_MSG, _ )
+
+//____________________________________________________________________________//
+
+#define BOOST_ERROR( M ) BOOST_CHECK_MESSAGE( false, M )
+#define BOOST_FAIL( M ) BOOST_REQUIRE_MESSAGE( false, M )
+
+//____________________________________________________________________________//
+
+#define BOOST_CHECK_THROW_IMPL( S, E, P, prefix, TL ) \
+do { \
+ try { \
+ BOOST_TEST_PASSPOINT(); \
+ S; \
+ BOOST_TEST_TOOL_IMPL( 2, false, "exception " BOOST_STRINGIZE(E) " is expected", \
+ TL, CHECK_MSG, _ ); \
+ } catch( E const& ex ) { \
+ ::boost::unit_test::ut_detail::ignore_unused_variable_warning( ex ); \
+ BOOST_TEST_TOOL_IMPL( 2, P, prefix BOOST_STRINGIZE( E ) " is caught", \
+ TL, CHECK_MSG, _ ); \
+ } \
+} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
+/**/
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", WARN )
+#define BOOST_CHECK_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", CHECK )
+#define BOOST_REQUIRE_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", REQUIRE )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", WARN )
+#define BOOST_CHECK_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", CHECK )
+#define BOOST_REQUIRE_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", REQUIRE )
+
+//____________________________________________________________________________//
+
+#define BOOST_CHECK_NO_THROW_IMPL( S, TL ) \
+do { \
+ try { \
+ S; \
+ BOOST_TEST_TOOL_IMPL( 2, true, "no exceptions thrown by " BOOST_STRINGIZE( S ), \
+ TL, CHECK_MSG, _ ); \
+ } catch( ... ) { \
+ BOOST_TEST_TOOL_IMPL( 2, false, "exception thrown by " BOOST_STRINGIZE( S ), \
+ TL, CHECK_MSG, _ ); \
+ } \
+} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
+/**/
+
+#define BOOST_WARN_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, WARN )
+#define BOOST_CHECK_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, CHECK )
+#define BOOST_REQUIRE_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, REQUIRE )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_EQUAL( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::equal_impl_frwd(), "", WARN, CHECK_EQUAL, (L)(R) )
+#define BOOST_CHECK_EQUAL( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::equal_impl_frwd(), "", CHECK, CHECK_EQUAL, (L)(R) )
+#define BOOST_REQUIRE_EQUAL( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::equal_impl_frwd(), "", REQUIRE, CHECK_EQUAL, (L)(R) )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_NE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::ne_impl(), "", WARN, CHECK_NE, (L)(R) )
+#define BOOST_CHECK_NE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::ne_impl(), "", CHECK, CHECK_NE, (L)(R) )
+#define BOOST_REQUIRE_NE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::ne_impl(), "", REQUIRE, CHECK_NE, (L)(R) )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_LT( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::lt_impl(), "", WARN, CHECK_LT, (L)(R) )
+#define BOOST_CHECK_LT( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::lt_impl(), "", CHECK, CHECK_LT, (L)(R) )
+#define BOOST_REQUIRE_LT( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::lt_impl(), "", REQUIRE, CHECK_LT, (L)(R) )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_LE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::le_impl(), "", WARN, CHECK_LE, (L)(R) )
+#define BOOST_CHECK_LE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::le_impl(), "", CHECK, CHECK_LE, (L)(R) )
+#define BOOST_REQUIRE_LE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::le_impl(), "", REQUIRE, CHECK_LE, (L)(R) )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_GT( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::gt_impl(), "", WARN, CHECK_GT, (L)(R) )
+#define BOOST_CHECK_GT( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::gt_impl(), "", CHECK, CHECK_GT, (L)(R) )
+#define BOOST_REQUIRE_GT( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::gt_impl(), "", REQUIRE, CHECK_GT, (L)(R) )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_GE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::ge_impl(), "", WARN, CHECK_GE, (L)(R) )
+#define BOOST_CHECK_GE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::ge_impl(), "", CHECK, CHECK_GE, (L)(R) )
+#define BOOST_REQUIRE_GE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::tt_detail::ge_impl(), "", REQUIRE, CHECK_GE, (L)(R) )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_CLOSE( L, R, T ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::check_is_close_t(), "", WARN, CHECK_CLOSE, (L)(R)(::boost::math::fpc::percent_tolerance(T)) )
+#define BOOST_CHECK_CLOSE( L, R, T ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::check_is_close_t(), "", CHECK, CHECK_CLOSE, (L)(R)(::boost::math::fpc::percent_tolerance(T)) )
+#define BOOST_REQUIRE_CLOSE( L, R, T ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::check_is_close_t(), "", REQUIRE, CHECK_CLOSE, (L)(R)(::boost::math::fpc::percent_tolerance(T)) )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_CLOSE_FRACTION(L, R, T) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::check_is_close_t(), "", WARN, CHECK_CLOSE_FRACTION, (L)(R)(T) )
+#define BOOST_CHECK_CLOSE_FRACTION(L, R, T) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::check_is_close_t(), "", CHECK, CHECK_CLOSE_FRACTION, (L)(R)(T) )
+#define BOOST_REQUIRE_CLOSE_FRACTION(L,R,T) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::check_is_close_t(), "", REQUIRE, CHECK_CLOSE_FRACTION, (L)(R)(T) )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_SMALL( FPV, T ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::check_is_small_t(), "", WARN, CHECK_SMALL, (FPV)(T) )
+#define BOOST_CHECK_SMALL( FPV, T ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::check_is_small_t(), "", CHECK, CHECK_SMALL, (FPV)(T) )
+#define BOOST_REQUIRE_SMALL( FPV, T ) BOOST_TEST_TOOL_IMPL( 0, \
+ ::boost::test_tools::check_is_small_t(), "", REQUIRE, CHECK_SMALL, (FPV)(T) )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_PREDICATE( P, ARGS ) BOOST_TEST_TOOL_IMPL( 0, \
+ P, BOOST_TEST_STRINGIZE( P ), WARN, CHECK_PRED_WITH_ARGS, ARGS )
+#define BOOST_CHECK_PREDICATE( P, ARGS ) BOOST_TEST_TOOL_IMPL( 0, \
+ P, BOOST_TEST_STRINGIZE( P ), CHECK, CHECK_PRED_WITH_ARGS, ARGS )
+#define BOOST_REQUIRE_PREDICATE( P, ARGS ) BOOST_TEST_TOOL_IMPL( 0, \
+ P, BOOST_TEST_STRINGIZE( P ), REQUIRE, CHECK_PRED_WITH_ARGS, ARGS )
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
+ BOOST_TEST_TOOL_IMPL( 1, ::boost::test_tools::tt_detail::equal_coll_impl(), \
+ "", WARN, CHECK_EQUAL_COLL, (L_begin)(L_end)(R_begin)(R_end) ) \
+/**/
+#define BOOST_CHECK_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
+ BOOST_TEST_TOOL_IMPL( 1, ::boost::test_tools::tt_detail::equal_coll_impl(), \
+ "", CHECK, CHECK_EQUAL_COLL, (L_begin)(L_end)(R_begin)(R_end) ) \
+/**/
+#define BOOST_REQUIRE_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
+ BOOST_TEST_TOOL_IMPL( 1, ::boost::test_tools::tt_detail::equal_coll_impl(), \
+ "", REQUIRE, CHECK_EQUAL_COLL, (L_begin)(L_end)(R_begin)(R_end) ) \
+/**/
+
+//____________________________________________________________________________//
+
+#define BOOST_WARN_BITWISE_EQUAL( L, R ) BOOST_TEST_TOOL_IMPL( 1, \
+ ::boost::test_tools::tt_detail::bitwise_equal_impl(), "", WARN, CHECK_BITWISE_EQUAL, (L)(R) )
+#define BOOST_CHECK_BITWISE_EQUAL( L, R ) BOOST_TEST_TOOL_IMPL( 1, \
+ ::boost::test_tools::tt_detail::bitwise_equal_impl(), "", CHECK, CHECK_BITWISE_EQUAL, (L)(R) )
+#define BOOST_REQUIRE_BITWISE_EQUAL( L, R ) BOOST_TEST_TOOL_IMPL( 1, \
+ ::boost::test_tools::tt_detail::bitwise_equal_impl(), "", REQUIRE, CHECK_BITWISE_EQUAL, (L)(R) )
+
+//____________________________________________________________________________//
+
+#define BOOST_IS_DEFINED( symb ) ::boost::test_tools::tt_detail::is_defined_impl( #symb, BOOST_STRINGIZE(= symb) )
+
+//____________________________________________________________________________//
+
+#ifdef BOOST_TEST_NO_NEW_TOOLS
+
+#define BOOST_TEST_WARN( P ) BOOST_WARN( P )
+#define BOOST_TEST_CHECK( P ) BOOST_CHECK( P )
+#define BOOST_TEST_REQUIRE( P ) BOOST_REQUIRE( P )
+
+#define BOOST_TEST( P ) BOOST_CHECK( P )
+
+#endif
+
+//____________________________________________________________________________//
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_OLD_INTERFACE_HPP_111712GER
diff --git a/boost/test/tools/output_test_stream.hpp b/boost/test/tools/output_test_stream.hpp
new file mode 100644
index 0000000000..89c9ad1919
--- /dev/null
+++ b/boost/test/tools/output_test_stream.hpp
@@ -0,0 +1,96 @@
+// (C) Copyright Gennadiy Rozental 2001-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/test for the library home page.
+//
+/// @file
+/// @brief output_test_stream class definition
+// ***************************************************************************
+
+#ifndef BOOST_TEST_OUTPUT_TEST_STREAM_HPP_012705GER
+#define BOOST_TEST_OUTPUT_TEST_STREAM_HPP_012705GER
+
+// Boost.Test
+#include <boost/test/detail/global_typedef.hpp>
+#include <boost/test/utils/wrap_stringstream.hpp>
+#include <boost/test/tools/assertion_result.hpp>
+
+// STL
+#include <cstddef> // for std::size_t
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** output_test_stream ************** //
+// ************************************************************************** //
+
+
+
+namespace boost {
+namespace test_tools {
+
+//! Class to be used to simplify testing of ostream-based output operations
+class BOOST_TEST_DECL output_test_stream : public wrap_stringstream::wrapped_stream {
+ typedef unit_test::const_string const_string;
+public:
+ //! Constructor
+ //!
+ //!@param[in] pattern_file_name indicates the name of the file for matching. If the
+ //! string is empty, the standard input or output streams are used instead
+ //! (depending on match_or_save)
+ //!@param[in] match_or_save if true, the pattern file will be read, otherwise it will be
+ //! written
+ //!@param[in] text_or_binary if false, opens the stream in binary mode. Otherwise the stream
+ //! is opened with default flags and the carriage returns are ignored.
+ explicit output_test_stream( const_string pattern_file_name = const_string(),
+ bool match_or_save = true,
+ bool text_or_binary = true );
+
+ // Destructor
+ ~output_test_stream();
+
+ //! Checks if the stream is empty
+ //!
+ //!@param[in] flush_stream if true, flushes the stream after the call
+ assertion_result is_empty( bool flush_stream = true );
+
+ //! Checks the length of the stream
+ //!
+ //!@param[in] length target length
+ //!@param[in] flush_stream if true, flushes the stream after the call. Set to false to call
+ //! additional checks on the same content.
+ assertion_result check_length( std::size_t length, bool flush_stream = true );
+
+ //! Checks the content of the stream against a string
+ //!
+ //!@param[in] arg_ the target stream
+ //!@param[in] flush_stream if true, flushes the stream after the call.
+ assertion_result is_equal( const_string arg_, bool flush_stream = true );
+
+ //! Checks the content of the stream against a pattern file
+ //!
+ //!@param[in] flush_stream if true, flushes the stream after the call.
+ assertion_result match_pattern( bool flush_stream = true );
+
+ //! Flushes the stream
+ void flush();
+
+private:
+ // helper functions
+ std::size_t length();
+ void sync();
+
+ struct Impl;
+ Impl* m_pimpl;
+};
+
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_OUTPUT_TEST_STREAM_HPP_012705GER
diff --git a/boost/test/tree/auto_registration.hpp b/boost/test/tree/auto_registration.hpp
new file mode 100644
index 0000000000..a32e6b8ad1
--- /dev/null
+++ b/boost/test/tree/auto_registration.hpp
@@ -0,0 +1,53 @@
+// (C) Copyright Gennadiy Rozental 2001-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 74640 $
+//
+// Description : defines auto_test_unit_registrar
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TREE_AUTO_REGISTRATION_HPP_100211GER
+#define BOOST_TEST_TREE_AUTO_REGISTRATION_HPP_100211GER
+
+// Boost.Test
+#include <boost/test/detail/config.hpp>
+#include <boost/test/tree/decorator.hpp>
+#include <boost/test/tree/test_unit.hpp>
+
+// STL
+#include <list>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace ut_detail {
+
+// ************************************************************************** //
+// ************** auto_test_unit_registrar ************** //
+// ************************************************************************** //
+
+struct BOOST_TEST_DECL auto_test_unit_registrar {
+ // Constructors
+ auto_test_unit_registrar( test_case* tc, decorator::collector& decorators, counter_t exp_fail = 0 );
+ explicit auto_test_unit_registrar( const_string ts_name, const_string ts_file, std::size_t ts_line, decorator::collector& decorators );
+ explicit auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector& decorators );
+ explicit auto_test_unit_registrar( int );
+};
+
+} // namespace ut_detail
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TREE_AUTO_REGISTRATION_HPP_100211GER
+
diff --git a/boost/test/tree/decorator.hpp b/boost/test/tree/decorator.hpp
new file mode 100644
index 0000000000..c24a0210ad
--- /dev/null
+++ b/boost/test/tree/decorator.hpp
@@ -0,0 +1,277 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 62016 $
+//
+// Description : defines decorators to be using with auto registered test units
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TREE_DECORATOR_HPP_091911GER
+#define BOOST_TEST_TREE_DECORATOR_HPP_091911GER
+
+// Boost.Test
+#include <boost/test/detail/config.hpp>
+#include <boost/test/detail/global_typedef.hpp>
+
+#include <boost/test/tree/fixture.hpp>
+
+#include <boost/test/tools/assertion_result.hpp>
+
+#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
+#include <boost/test/utils/trivial_singleton.hpp>
+
+// Boost
+#include <boost/shared_ptr.hpp>
+#include <boost/function/function0.hpp>
+#include <boost/function/function1.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+// STL
+#include <vector>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+
+class test_unit;
+
+namespace decorator {
+
+// ************************************************************************** //
+// ************** decorator::collector ************** //
+// ************************************************************************** //
+
+class base;
+typedef boost::shared_ptr<base> base_ptr;
+
+class BOOST_TEST_DECL collector : public singleton<collector> {
+public:
+ collector& operator*( base const& d );
+
+ void store_in( test_unit& tu );
+
+ void reset();
+
+private:
+ BOOST_TEST_SINGLETON_CONS( collector )
+
+ // Data members
+ std::vector<base_ptr> m_tu_decorators;
+};
+
+// ************************************************************************** //
+// ************** decorator::base ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL base {
+public:
+ // composition interface
+ collector& operator*() const;
+
+ // application interface
+ virtual void apply( test_unit& tu ) = 0;
+
+ // deep cloning interface
+ virtual base_ptr clone() const = 0;
+
+protected:
+ virtual ~base() {}
+};
+
+// ************************************************************************** //
+// ************** decorator::label ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL label : public decorator::base {
+public:
+ explicit label( const_string l ) : m_label( l ) {}
+
+private:
+ // decorator::base interface
+ virtual void apply( test_unit& tu );
+ virtual base_ptr clone() const { return base_ptr(new label( m_label )); }
+
+ // Data members
+ const_string m_label;
+};
+
+// ************************************************************************** //
+// ************** decorator::expected_failures ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL expected_failures : public decorator::base {
+public:
+ explicit expected_failures( counter_t ef ) : m_exp_fail( ef ) {}
+
+private:
+ // decorator::base interface
+ virtual void apply( test_unit& tu );
+ virtual base_ptr clone() const { return base_ptr(new expected_failures( m_exp_fail )); }
+
+ // Data members
+ counter_t m_exp_fail;
+};
+
+// ************************************************************************** //
+// ************** decorator::timeout ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL timeout : public decorator::base {
+public:
+ explicit timeout( unsigned t ) : m_timeout( t ) {}
+
+private:
+ // decorator::base interface
+ virtual void apply( test_unit& tu );
+ virtual base_ptr clone() const { return base_ptr(new timeout( m_timeout )); }
+
+ // Data members
+ unsigned m_timeout;
+};
+
+// ************************************************************************** //
+// ************** decorator::description ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL description : public decorator::base {
+public:
+ explicit description( const_string descr ) : m_description( descr ) {}
+
+private:
+ // decorator::base interface
+ virtual void apply( test_unit& tu );
+ virtual base_ptr clone() const { return base_ptr(new description( m_description )); }
+
+ // Data members
+ const_string m_description;
+};
+
+// ************************************************************************** //
+// ************** decorator::depends_on ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL depends_on : public decorator::base {
+public:
+ explicit depends_on( const_string dependency ) : m_dependency( dependency ) {}
+
+private:
+ // decorator::base interface
+ virtual void apply( test_unit& tu );
+ virtual base_ptr clone() const { return base_ptr(new depends_on( m_dependency )); }
+
+ // Data members
+ const_string m_dependency;
+};
+
+// ************************************************************************** //
+// ************** decorator::enable_if/enabled/disabled ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL enable_if_impl : public decorator::base {
+protected:
+ void apply_impl( test_unit& tu, bool condition );
+};
+
+template<bool condition>
+class enable_if : public enable_if_impl {
+private:
+ // decorator::base interface
+ virtual void apply( test_unit& tu ) { this->apply_impl( tu, condition ); }
+ virtual base_ptr clone() const { return base_ptr(new enable_if<condition>()); }
+};
+
+typedef enable_if<true> enabled;
+typedef enable_if<false> disabled;
+
+// ************************************************************************** //
+// ************** decorator::fixture ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL fixture_t : public decorator::base {
+public:
+ // Constructor
+ explicit fixture_t( test_unit_fixture_ptr impl ) : m_impl( impl ) {}
+
+private:
+ // decorator::base interface
+ virtual void apply( test_unit& tu );
+ virtual base_ptr clone() const { return base_ptr(new fixture_t( m_impl )); }
+
+ // Data members
+ test_unit_fixture_ptr m_impl;
+};
+
+//____________________________________________________________________________//
+
+template<typename F>
+inline fixture_t
+fixture()
+{
+ return fixture_t( test_unit_fixture_ptr( new unit_test::class_based_fixture<F>() ) );
+}
+
+//____________________________________________________________________________//
+
+template<typename F, typename Arg>
+inline fixture_t
+fixture( Arg const& arg )
+{
+ return fixture_t( test_unit_fixture_ptr( new unit_test::class_based_fixture<F,Arg>( arg ) ) );
+}
+
+//____________________________________________________________________________//
+
+inline fixture_t
+fixture( boost::function<void()> const& setup, boost::function<void()> const& teardown = boost::function<void()>() )
+{
+ return fixture_t( test_unit_fixture_ptr( new unit_test::function_based_fixture( setup, teardown ) ) );
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** decorator::depends_on ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL precondition : public decorator::base {
+public:
+ typedef boost::function<test_tools::assertion_result (test_unit_id)> predicate_t;
+
+ explicit precondition( predicate_t p ) : m_precondition( p ) {}
+
+private:
+ // decorator::base interface
+ virtual void apply( test_unit& tu );
+ virtual base_ptr clone() const { return base_ptr(new precondition( m_precondition )); }
+
+ // Data members
+ predicate_t m_precondition;
+};
+
+} // namespace decorator
+
+using decorator::label;
+using decorator::expected_failures;
+using decorator::timeout;
+using decorator::description;
+using decorator::depends_on;
+using decorator::enable_if;
+using decorator::enabled;
+using decorator::disabled;
+using decorator::fixture;
+using decorator::precondition;
+
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TREE_DECORATOR_HPP_091911GER
diff --git a/boost/test/tree/fixture.hpp b/boost/test/tree/fixture.hpp
new file mode 100644
index 0000000000..da6befbae7
--- /dev/null
+++ b/boost/test/tree/fixture.hpp
@@ -0,0 +1,116 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 74640 $
+//
+// Description : defines fixture interface and object makers
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TREE_FIXTURE_HPP_100311GER
+#define BOOST_TEST_TREE_FIXTURE_HPP_100311GER
+
+// Boost.Test
+#include <boost/test/detail/config.hpp>
+
+// Boost
+#include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/function/function0.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+
+// ************************************************************************** //
+// ************** test_unit_fixture ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL test_unit_fixture {
+public:
+ virtual ~test_unit_fixture() {}
+
+ // Fixture interface
+ virtual void setup() = 0;
+ virtual void teardown() = 0;
+};
+
+typedef shared_ptr<test_unit_fixture> test_unit_fixture_ptr;
+
+// ************************************************************************** //
+// ************** class_based_fixture ************** //
+// ************************************************************************** //
+
+template<typename F, typename Arg=void>
+class class_based_fixture : public test_unit_fixture {
+public:
+ // Constructor
+ explicit class_based_fixture( Arg const& arg ) : m_inst(), m_arg( arg ) {}
+
+private:
+ // Fixture interface
+ virtual void setup() { m_inst.reset( new F( m_arg ) ); }
+ virtual void teardown() { m_inst.reset(); }
+
+ // Data members
+ scoped_ptr<F> m_inst;
+ Arg m_arg;
+};
+
+//____________________________________________________________________________//
+
+template<typename F>
+class class_based_fixture<F,void> : public test_unit_fixture {
+public:
+ // Constructor
+ class_based_fixture() : m_inst( 0 ) {}
+
+private:
+ // Fixture interface
+ virtual void setup() { m_inst.reset( new F ); }
+ virtual void teardown() { m_inst.reset(); }
+
+ // Data members
+ scoped_ptr<F> m_inst;
+};
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// ************** function_based_fixture ************** //
+// ************************************************************************** //
+
+class function_based_fixture : public test_unit_fixture {
+public:
+ // Constructor
+ function_based_fixture( boost::function<void ()> const& setup_, boost::function<void ()> const& teardown_ )
+ : m_setup( setup_ )
+ , m_teardown( teardown_ )
+ {
+ }
+
+private:
+ // Fixture interface
+ virtual void setup() { if( m_setup ) m_setup(); }
+ virtual void teardown() { if( m_teardown ) m_teardown(); }
+
+ // Data members
+ boost::function<void ()> m_setup;
+ boost::function<void ()> m_teardown;
+};
+
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TREE_FIXTURE_HPP_100311GER
+
diff --git a/boost/test/tree/global_fixture.hpp b/boost/test/tree/global_fixture.hpp
new file mode 100644
index 0000000000..9ba4462a5c
--- /dev/null
+++ b/boost/test/tree/global_fixture.hpp
@@ -0,0 +1,68 @@
+// (C) Copyright Gennadiy Rozental 2001-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 74640 $
+//
+// Description : defines global_fixture
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TREE_GLOBAL_FIXTURE_HPP_091911GER
+#define BOOST_TEST_TREE_GLOBAL_FIXTURE_HPP_091911GER
+
+// Boost.Test
+#include <boost/test/detail/config.hpp>
+#include <boost/test/detail/global_typedef.hpp>
+
+#include <boost/test/tree/observer.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+
+// ************************************************************************** //
+// ************** global_fixture ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL global_fixture : public test_observer {
+public:
+ // Constructor
+ global_fixture();
+};
+
+//____________________________________________________________________________//
+
+namespace ut_detail {
+
+template<typename F>
+struct global_fixture_impl : public global_fixture {
+ // Constructor
+ global_fixture_impl() : m_fixture( 0 ) {}
+
+ // test observer interface
+ virtual void test_start( counter_t ) { m_fixture = new F; }
+ virtual void test_finish() { delete m_fixture; m_fixture = 0; }
+ virtual void test_aborted() { delete m_fixture; m_fixture = 0; }
+
+private:
+ // Data members
+ F* m_fixture;
+};
+
+} // namespace ut_detail
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TREE_GLOBAL_FIXTURE_HPP_091911GER
+
diff --git a/boost/test/test_observer.hpp b/boost/test/tree/observer.hpp
index 4ae152c7b6..3ae96c488d 100644
--- a/boost/test/test_observer.hpp
+++ b/boost/test/tree/observer.hpp
@@ -1,15 +1,12 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : defines abstract interface for test observer
+//!@file
+//!@brief defines abstract interface for test observer
// ***************************************************************************
#ifndef BOOST_TEST_TEST_OBSERVER_HPP_021005GER
@@ -25,7 +22,6 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
// ************************************************************************** //
@@ -41,24 +37,33 @@ public:
virtual void test_unit_start( test_unit const& ) {}
virtual void test_unit_finish( test_unit const&, unsigned long /* elapsed */ ) {}
- virtual void test_unit_skipped( test_unit const& ) {}
+ virtual void test_unit_skipped( test_unit const& tu, const_string ) { test_unit_skipped( tu ); }
+ virtual void test_unit_skipped( test_unit const& ) {} ///< backward compartibility
virtual void test_unit_aborted( test_unit const& ) {}
- virtual void assertion_result( bool /* passed */ ) {}
+ virtual void assertion_result( unit_test::assertion_result ar )
+ {
+ switch( ar ) {
+ case AR_PASSED: assertion_result( true ); break;
+ case AR_FAILED: assertion_result( false ); break;
+ case AR_TRIGGERED: break;
+ default: break;
+ }
+ }
virtual void exception_caught( execution_exception const& ) {}
virtual int priority() { return 0; }
protected:
+ // depracated now
+ virtual void assertion_result( bool /* passed */ ) {}
+
BOOST_TEST_PROTECTED_VIRTUAL ~test_observer() {}
};
-} // unit_test
-
+} // namespace unit_test
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TEST_OBSERVER_HPP_021005GER
diff --git a/boost/test/tree/test_case_counter.hpp b/boost/test/tree/test_case_counter.hpp
new file mode 100644
index 0000000000..f9fa2d2bd2
--- /dev/null
+++ b/boost/test/tree/test_case_counter.hpp
@@ -0,0 +1,54 @@
+// (C) Copyright Gennadiy Rozental 2001-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: 74640 $
+//
+// Description : defines test_case_counter
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TREE_TEST_CASE_COUNTER_HPP_100211GER
+#define BOOST_TEST_TREE_TEST_CASE_COUNTER_HPP_100211GER
+
+// Boost.Test
+#include <boost/test/detail/config.hpp>
+#include <boost/test/utils/class_properties.hpp>
+
+#include <boost/test/tree/test_unit.hpp>
+#include <boost/test/tree/visitor.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+
+// ************************************************************************** //
+// ************** test_case_counter ************** //
+// ************************************************************************** //
+
+class test_case_counter : public test_tree_visitor {
+public:
+ // Constructor
+ test_case_counter() : p_count( 0 ) {}
+
+ BOOST_READONLY_PROPERTY( counter_t, (test_case_counter)) p_count;
+private:
+ // test tree visitor interface
+ virtual void visit( test_case const& tc ) { if( tc.is_enabled() ) ++p_count.value; }
+ virtual bool test_suite_start( test_suite const& ts ) { return ts.is_enabled(); }
+};
+
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TREE_TEST_CASE_COUNTER_HPP_100211GER
+
diff --git a/boost/test/tree/test_case_template.hpp b/boost/test/tree/test_case_template.hpp
new file mode 100644
index 0000000000..ef2881588a
--- /dev/null
+++ b/boost/test/tree/test_case_template.hpp
@@ -0,0 +1,144 @@
+// (C) Copyright Gennadiy Rozental 2001-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: -1 $
+//
+// Description : defines template_test_case_gen
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TREE_TEST_CASE_TEMPLATE_HPP_091911GER
+#define BOOST_TEST_TREE_TEST_CASE_TEMPLATE_HPP_091911GER
+
+// Boost.Test
+#include <boost/test/detail/config.hpp>
+#include <boost/test/detail/global_typedef.hpp>
+#include <boost/test/detail/fwd_decl.hpp>
+#include <boost/test/detail/workaround.hpp>
+
+#include <boost/test/utils/class_properties.hpp>
+
+#include <boost/test/tree/observer.hpp>
+
+
+// Boost
+#include <boost/shared_ptr.hpp>
+#include <boost/mpl/for_each.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/function/function0.hpp>
+
+#ifndef BOOST_NO_RTTI
+#include <typeinfo> // for typeid
+#else
+#include <boost/current_function.hpp>
+#endif
+
+// STL
+#include <string> // for std::string
+#include <list> // for std::list
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace ut_detail {
+
+// ************************************************************************** //
+// ************** test_case_template_invoker ************** //
+// ************************************************************************** //
+
+template<typename TestCaseTemplate,typename TestType>
+class test_case_template_invoker {
+public:
+ void operator()() { TestCaseTemplate::run( (boost::type<TestType>*)0 ); }
+};
+
+// ************************************************************************** //
+// ************** generate_test_case_4_type ************** //
+// ************************************************************************** //
+
+template<typename Generator,typename TestCaseTemplate>
+struct generate_test_case_4_type {
+ explicit generate_test_case_4_type( const_string tc_name, const_string tc_file, std::size_t tc_line, Generator& G )
+ : m_test_case_name( tc_name )
+ , m_test_case_file( tc_file )
+ , m_test_case_line( tc_line )
+ , m_holder( G )
+ {}
+
+ template<typename TestType>
+ void operator()( mpl::identity<TestType> )
+ {
+ std::string full_name;
+ assign_op( full_name, m_test_case_name, 0 );
+ full_name += '<';
+#ifndef BOOST_NO_RTTI
+ full_name += typeid(TestType).name();
+#else
+ full_name += BOOST_CURRENT_FUNCTION;
+#endif
+ if( boost::is_const<TestType>::value )
+ full_name += "_const";
+ full_name += '>';
+
+ m_holder.m_test_cases.push_back( new test_case( ut_detail::normalize_test_case_name( full_name ),
+ m_test_case_file,
+ m_test_case_line,
+ test_case_template_invoker<TestCaseTemplate,TestType>() ) );
+ }
+
+private:
+ // Data members
+ const_string m_test_case_name;
+ const_string m_test_case_file;
+ std::size_t m_test_case_line;
+ Generator& m_holder;
+};
+
+// ************************************************************************** //
+// ************** test_case_template ************** //
+// ************************************************************************** //
+
+template<typename TestCaseTemplate,typename TestTypesList>
+class template_test_case_gen : public test_unit_generator {
+public:
+ // Constructor
+ template_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line )
+ {
+ typedef generate_test_case_4_type<template_test_case_gen<TestCaseTemplate,TestTypesList>,TestCaseTemplate> single_test_gen;
+
+ mpl::for_each<TestTypesList,mpl::make_identity<mpl::_> >( single_test_gen( tc_name, tc_file, tc_line, *this ) );
+ }
+
+ virtual test_unit* next() const
+ {
+ if( m_test_cases.empty() )
+ return 0;
+
+ test_unit* res = m_test_cases.front();
+ m_test_cases.pop_front();
+
+ return res;
+ }
+
+ // Data members
+ mutable std::list<test_unit*> m_test_cases;
+};
+
+} // namespace ut_detail
+} // unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TREE_TEST_CASE_TEMPLATE_HPP_091911GER
diff --git a/boost/test/tree/test_unit.hpp b/boost/test/tree/test_unit.hpp
new file mode 100644
index 0000000000..4791bd15ac
--- /dev/null
+++ b/boost/test/tree/test_unit.hpp
@@ -0,0 +1,275 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+/// @file
+/// Defines @ref boost::unit_test::test_unit "test_unit", @ref boost::unit_test::test_case "test_case",
+/// @ref boost::unit_test::test_suite "test_suite" and @ref boost::unit_test::master_test_suite_t "master_test_suite_t"
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER
+#define BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER
+
+// Boost.Test
+#include <boost/test/detail/config.hpp>
+#include <boost/test/detail/global_typedef.hpp>
+#include <boost/test/detail/fwd_decl.hpp>
+
+#include <boost/test/tree/decorator.hpp>
+#include <boost/test/tree/fixture.hpp>
+
+#include <boost/test/tools/assertion_result.hpp>
+
+#include <boost/test/utils/class_properties.hpp>
+
+// Boost
+#include <boost/function/function0.hpp>
+#include <boost/function/function1.hpp>
+
+// STL
+#include <vector>
+#include <string>
+#include <map>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+
+namespace framework {
+class state;
+}
+
+// ************************************************************************** //
+// ************** test_unit ************** //
+// ************************************************************************** //
+
+typedef std::vector<test_unit_id> test_unit_id_list;
+
+class BOOST_TEST_DECL test_unit {
+public:
+ enum { type = TUT_ANY };
+ enum run_status { RS_DISABLED, RS_ENABLED, RS_INHERIT, RS_INVALID };
+
+ typedef std::vector<test_unit_id> id_list;
+ typedef std::vector<test_unit_fixture_ptr> fixture_list_t;
+ typedef BOOST_READONLY_PROPERTY(test_unit_id,(framework::state)) id_t;
+ typedef BOOST_READONLY_PROPERTY(test_unit_id,(test_suite)) parent_id_t;
+ typedef BOOST_READONLY_PROPERTY(id_list,(test_unit)) id_list_t;
+ typedef std::vector<decorator::base_ptr> decor_list_t;
+ typedef BOOST_READONLY_PROPERTY(std::vector<std::string>,(test_unit)) label_list_t;
+
+ typedef boost::function<test_tools::assertion_result (test_unit_id)> precondition_t;
+ typedef BOOST_READONLY_PROPERTY(std::vector<precondition_t>,(test_unit)) precond_list_t;
+
+ // preconditions management
+ void depends_on( test_unit* tu );
+ void add_precondition( precondition_t const& );
+ test_tools::assertion_result check_preconditions() const;
+
+ // labels management
+ void add_label( const_string l );
+ bool has_label( const_string l ) const;
+
+ // helper access methods
+ void increase_exp_fail( counter_t num );
+ bool is_enabled() const { return p_run_status == RS_ENABLED; }
+ std::string full_name() const;
+
+ // Public r/o properties
+ readonly_property<test_unit_type> p_type; ///< type for this test unit
+ readonly_property<const_string> p_type_name; ///< "case"/"suite"/"module"
+ readonly_property<const_string> p_file_name;
+ readonly_property<std::size_t> p_line_num;
+ id_t p_id; ///< unique id for this test unit
+ parent_id_t p_parent_id; ///< parent test suite id
+ label_list_t p_labels; ///< list of labels associated with this test unit
+
+ id_list_t p_dependencies; ///< list of test units this one depends on
+ precond_list_t p_preconditions; ///< user supplied preconditions for this test unit;
+
+ // Public r/w properties
+ readwrite_property<std::string> p_name; ///< name for this test unit
+ readwrite_property<std::string> p_description; ///< description for this test unit
+ readwrite_property<unsigned> p_timeout; ///< timeout for the test unit execution in seconds
+ readwrite_property<counter_t> p_expected_failures; ///< number of expected failures in this test unit
+
+ readwrite_property<run_status> p_default_status; ///< run status obtained by this unit during setup phase
+ readwrite_property<run_status> p_run_status; ///< run status assigned to this unit before execution phase after applying all filters
+
+ readwrite_property<counter_t> p_sibling_rank; ///< rank of this test unit amoung siblings of the same parent
+
+ readwrite_property<decor_list_t> p_decorators; ///< automatically assigned decorators; execution is delayed till framework::finalize_setup_phase function
+ readwrite_property<fixture_list_t> p_fixtures; ///< fixtures associated with this test unit
+
+protected:
+ ~test_unit();
+ // Constructor
+ test_unit( const_string tu_name, const_string tc_file, std::size_t tc_line, test_unit_type t );
+ // Master test suite constructor
+ explicit test_unit( const_string module_name );
+
+private:
+};
+
+// ************************************************************************** //
+// ************** test_unit_generator ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL test_unit_generator {
+public:
+ virtual test_unit* next() const = 0;
+
+protected:
+ BOOST_TEST_PROTECTED_VIRTUAL ~test_unit_generator() {}
+};
+
+// ************************************************************************** //
+// ************** test_case ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL test_case : public test_unit {
+public:
+ enum { type = TUT_CASE };
+
+ // Constructor
+ test_case( const_string tc_name, boost::function<void ()> const& test_func );
+ test_case( const_string tc_name, const_string tc_file, std::size_t tc_line, boost::function<void ()> const& test_func );
+
+ // Public property
+ typedef BOOST_READONLY_PROPERTY(boost::function<void ()>,(test_case)) test_func;
+
+ test_func p_test_func;
+
+private:
+ friend class framework::state;
+ ~test_case() {}
+};
+
+// ************************************************************************** //
+// ************** test_suite ************** //
+// ************************************************************************** //
+
+//! Class representing test suites
+class BOOST_TEST_DECL test_suite : public test_unit {
+public:
+ enum { type = TUT_SUITE };
+
+ // Constructor
+ explicit test_suite( const_string ts_name, const_string ts_file, std::size_t ts_line );
+
+ // test unit list management
+
+ /*!@brief Adds a test unit to a test suite.
+ *
+ * It is possible to specify the timeout and the expected failures.
+ */
+ void add( test_unit* tu, counter_t expected_failures = 0, unsigned timeout = 0 );
+
+ /// @overload
+ void add( test_unit_generator const& gen, unsigned timeout = 0 );
+
+ /// @overload
+ void add( test_unit_generator const& gen, decorator::collector& decorators );
+
+ //! Removes a test from the test suite.
+ void remove( test_unit_id id );
+
+
+ // access methods
+ test_unit_id get( const_string tu_name ) const;
+ std::size_t size() const { return m_children.size(); }
+
+protected:
+ // Master test suite constructor
+ explicit test_suite( const_string module_name );
+
+ friend BOOST_TEST_DECL
+ void traverse_test_tree( test_suite const&, test_tree_visitor&, bool );
+ friend class framework::state;
+ virtual ~test_suite() {}
+
+ typedef std::multimap<counter_t,test_unit_id> children_per_rank;
+ // Data members
+
+ test_unit_id_list m_children;
+ children_per_rank m_ranked_children; ///< maps child sibling rank to list of children with that rank
+};
+
+// ************************************************************************** //
+// ************** master_test_suite ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL master_test_suite_t : public test_suite {
+public:
+ master_test_suite_t();
+
+ // Data members
+ int argc;
+ char** argv;
+};
+
+// ************************************************************************** //
+// ************** user_tc_method_invoker ************** //
+// ************************************************************************** //
+
+namespace ut_detail {
+
+BOOST_TEST_DECL std::string normalize_test_case_name( const_string tu_name );
+
+//____________________________________________________________________________//
+
+template<typename InstanceType,typename UserTestCase>
+struct user_tc_method_invoker {
+ typedef void (UserTestCase::*TestMethod )();
+
+ user_tc_method_invoker( shared_ptr<InstanceType> inst, TestMethod test_method )
+ : m_inst( inst ), m_test_method( test_method ) {}
+
+ void operator()() { ((*m_inst).*m_test_method)(); }
+
+ shared_ptr<InstanceType> m_inst;
+ TestMethod m_test_method;
+};
+
+} // namespace ut_detail
+
+// ************************************************************************** //
+// ************** make_test_case ************** //
+// ************************************************************************** //
+
+inline test_case*
+make_test_case( boost::function<void ()> const& test_func, const_string tc_name, const_string tc_file, std::size_t tc_line )
+{
+ return new test_case( ut_detail::normalize_test_case_name( tc_name ), tc_file, tc_line, test_func );
+}
+
+//____________________________________________________________________________//
+
+template<typename UserTestCase, typename InstanceType>
+inline test_case*
+make_test_case( void (UserTestCase::* test_method )(),
+ const_string tc_name,
+ const_string tc_file,
+ std::size_t tc_line,
+ boost::shared_ptr<InstanceType> user_test_case )
+{
+ return new test_case( ut_detail::normalize_test_case_name( tc_name ),
+ tc_file,
+ tc_line,
+ ut_detail::user_tc_method_invoker<InstanceType,UserTestCase>( user_test_case, test_method ) );
+}
+
+//____________________________________________________________________________//
+
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER
diff --git a/boost/test/tree/traverse.hpp b/boost/test/tree/traverse.hpp
new file mode 100644
index 0000000000..461ff89ba4
--- /dev/null
+++ b/boost/test/tree/traverse.hpp
@@ -0,0 +1,58 @@
+// (C) Copyright Gennadiy Rozental 2001-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: -1 $
+//
+// Description : defines traverse_test_tree algorithm
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TREE_TRAVERSE_HPP_100211GER
+#define BOOST_TEST_TREE_TRAVERSE_HPP_100211GER
+
+// Boost.Test
+#include <boost/test/detail/config.hpp>
+
+#include <boost/test/tree/test_unit.hpp>
+#include <boost/test/tree/visitor.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+
+// ************************************************************************** //
+// ************** traverse_test_tree ************** //
+// ************************************************************************** //
+
+BOOST_TEST_DECL void traverse_test_tree( test_case const&, test_tree_visitor&, bool ignore_status = false );
+BOOST_TEST_DECL void traverse_test_tree( test_suite const&, test_tree_visitor&, bool ignore_status = false );
+BOOST_TEST_DECL void traverse_test_tree( test_unit_id , test_tree_visitor&, bool ignore_status = false );
+
+//____________________________________________________________________________//
+
+inline void
+traverse_test_tree( test_unit const& tu, test_tree_visitor& V, bool ignore_status = false )
+{
+ if( tu.p_type == TUT_CASE )
+ traverse_test_tree( static_cast<test_case const&>( tu ), V, ignore_status );
+ else
+ traverse_test_tree( static_cast<test_suite const&>( tu ), V, ignore_status );
+}
+
+//____________________________________________________________________________//
+
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TREE_TRAVERSE_HPP_100211GER
diff --git a/boost/test/tree/visitor.hpp b/boost/test/tree/visitor.hpp
new file mode 100644
index 0000000000..0dd864063b
--- /dev/null
+++ b/boost/test/tree/visitor.hpp
@@ -0,0 +1,52 @@
+// (C) Copyright Gennadiy Rozental 2011-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision: -1 $
+//
+// Description : defines test_tree_visitor
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TREE_VISITOR_HPP_100211GER
+#define BOOST_TEST_TREE_VISITOR_HPP_100211GER
+
+// Boost.Test
+#include <boost/test/detail/config.hpp>
+
+#include <boost/test/tree/test_unit.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+
+// ************************************************************************** //
+// ************** test_tree_visitor ************** //
+// ************************************************************************** //
+
+class BOOST_TEST_DECL test_tree_visitor {
+public:
+ // test tree visitor interface
+ virtual bool visit( test_unit const& ) { return true; }
+ virtual void visit( test_case const& tc ) { visit( (test_unit const&)tc ); }
+ virtual bool test_suite_start( test_suite const& ts ){ return visit( (test_unit const&)ts ); }
+ virtual void test_suite_finish( test_suite const& ) {}
+
+protected:
+ BOOST_TEST_PROTECTED_VIRTUAL ~test_tree_visitor() {}
+};
+
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TREE_VISITOR_HPP_100211GER
+
diff --git a/boost/test/unit_test.hpp b/boost/test/unit_test.hpp
index c93e2b69ff..6181355316 100644
--- a/boost/test/unit_test.hpp
+++ b/boost/test/unit_test.hpp
@@ -1,15 +1,14 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : Entry point for the end user into the Unit Test Framework.
+/// @file
+/// @brief Entry point into the Unit Test Framework
+///
+/// This header should be the only header necessary to include to start using the framework
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_HPP_071894GER
@@ -45,7 +44,12 @@ namespace boost { namespace unit_test {
int BOOST_TEST_DECL unit_test_main( init_unit_test_func init_func, int argc, char* argv[] );
-}}
+}
+
+// !! ?? to remove
+namespace unit_test_framework=unit_test;
+
+}
#if defined(BOOST_TEST_DYN_LINK) && defined(BOOST_TEST_MAIN) && !defined(BOOST_TEST_NO_MAIN)
diff --git a/boost/test/unit_test_log.hpp b/boost/test/unit_test_log.hpp
index 8d9eac6a9e..76817ffcb8 100644
--- a/boost/test/unit_test_log.hpp
+++ b/boost/test/unit_test_log.hpp
@@ -1,24 +1,21 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : defines singleton class unit_test_log and all manipulators.
-// unit_test_log has output stream like interface. It's implementation is
-// completely hidden with pimple idiom
+/// @file
+/// @brief defines singleton class unit_test_log and all manipulators.
+/// unit_test_log has output stream like interface. It's implementation is
+/// completely hidden with pimple idiom
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_LOG_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_LOG_HPP_071894GER
// Boost.Test
-#include <boost/test/test_observer.hpp>
+#include <boost/test/tree/observer.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/log_level.hpp>
@@ -29,7 +26,6 @@
#include <boost/test/utils/lazy_ostream.hpp>
// Boost
-#include <boost/utility.hpp>
// STL
#include <iosfwd> // for std::ostream&
@@ -39,7 +35,6 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
// ************************************************************************** //
@@ -93,17 +88,15 @@ private:
class BOOST_TEST_DECL unit_test_log_t : public test_observer, public singleton<unit_test_log_t> {
public:
// test_observer interface implementation
- void test_start( counter_t test_cases_amount );
- void test_finish();
- void test_aborted();
+ virtual void test_start( counter_t test_cases_amount );
+ virtual void test_finish();
+ virtual void test_aborted();
- void test_unit_start( test_unit const& );
- void test_unit_finish( test_unit const&, unsigned long elapsed );
- void test_unit_skipped( test_unit const& );
- void test_unit_aborted( test_unit const& );
+ virtual void test_unit_start( test_unit const& );
+ virtual void test_unit_finish( test_unit const&, unsigned long elapsed );
+ virtual void test_unit_skipped( test_unit const&, const_string );
- void assertion_result( bool passed );
- void exception_caught( execution_exception const& );
+ virtual void exception_caught( execution_exception const& ex );
virtual int priority() { return 1; }
@@ -117,7 +110,7 @@ public:
void set_checkpoint( const_string file, std::size_t line_num, const_string msg = const_string() );
// entry logging
- unit_test_log_t& operator<<( log::begin const& ); // begin entry
+ unit_test_log_t& operator<<( log::begin const& ); // begin entry
unit_test_log_t& operator<<( log::end const& ); // end entry
unit_test_log_t& operator<<( log_level ); // set entry level
unit_test_log_t& operator<<( const_string ); // log entry value
@@ -126,9 +119,12 @@ public:
ut_detail::entry_value_collector operator()( log_level ); // initiate entry collection
private:
- bool log_entry_start();
+ // Implementation helpers
+ bool log_entry_start();
+ void log_entry_context( log_level l );
+ void clear_entry_context();
- BOOST_TEST_SINGLETON_CONS( unit_test_log_t );
+ BOOST_TEST_SINGLETON_CONS( unit_test_log_t )
}; // unit_test_log_t
BOOST_TEST_SINGLETON_INST( unit_test_log )
@@ -140,7 +136,6 @@ BOOST_TEST_SINGLETON_INST( unit_test_log )
/**/
} // namespace unit_test
-
} // namespace boost
// ************************************************************************** //
@@ -149,7 +144,7 @@ BOOST_TEST_SINGLETON_INST( unit_test_log )
#define BOOST_TEST_MESSAGE( M ) \
BOOST_TEST_LOG_ENTRY( ::boost::unit_test::log_messages ) \
- << (::boost::unit_test::lazy_ostream::instance() << M) \
+ << BOOST_TEST_LAZY_MSG( M ) \
/**/
//____________________________________________________________________________//
diff --git a/boost/test/unit_test_log_formatter.hpp b/boost/test/unit_test_log_formatter.hpp
index 81f156b4b9..f89b74bd17 100644
--- a/boost/test/unit_test_log_formatter.hpp
+++ b/boost/test/unit_test_log_formatter.hpp
@@ -1,15 +1,15 @@
-// (C) Copyright Gennadiy Rozental 2003-2008.
+// (C) Copyright Gennadiy Rozental 2003-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description :
+/// @file
+/// @brief Defines unit test log formatter interface
+///
+/// You can define a class with implements this interface and use an instance of it
+/// as a Unit Test Framework log formatter
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_LOG_FORMATTER_HPP_071894GER
@@ -20,8 +20,6 @@
#include <boost/test/detail/log_level.hpp>
#include <boost/test/detail/fwd_decl.hpp>
-#include <boost/test/execution_monitor.hpp>
-
// STL
#include <iosfwd>
#include <string> // for std::string
@@ -31,11 +29,10 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
// ************************************************************************** //
-// ************** log_entry_data ************** //
+/// Collection of log entry attributes
// ************************************************************************** //
struct BOOST_TEST_DECL log_entry_data {
@@ -44,9 +41,9 @@ struct BOOST_TEST_DECL log_entry_data {
m_file_name.reserve( 200 );
}
- std::string m_file_name;
- std::size_t m_line_num;
- log_level m_level;
+ std::string m_file_name; ///< log entry file name
+ std::size_t m_line_num; ///< log entry line number
+ log_level m_level; ///< log entry level
void clear()
{
@@ -57,62 +54,190 @@ struct BOOST_TEST_DECL log_entry_data {
};
// ************************************************************************** //
-// ************** checkpoint_data ************** //
+/// Collection of log checkpoint attributes
// ************************************************************************** //
struct BOOST_TEST_DECL log_checkpoint_data
{
- const_string m_file_name;
- std::size_t m_line_num;
- std::string m_message;
+ const_string m_file_name; ///< log checkpoint file name
+ std::size_t m_line_num; ///< log checkpoint file name
+ std::string m_message; ///< log checkpoint message
void clear()
{
m_file_name.clear();
- m_line_num = 0;
- m_message = std::string();
+ m_line_num = 0;
+ m_message = std::string();
}
};
// ************************************************************************** //
-// ************** unit_test_log_formatter ************** //
-// ************************************************************************** //
-
+/// Abstract Unit Test Framework log formatter interface
+
+/// During the test module execution Unit Test Framework can report messages about success or failure of assertions,
+/// which test suites are being run and more (specifically which messages are reported depends on log level threshold selected by the user).
+/// All these messages constitute Unit Test Framework log. There are many ways (formats) to present these messages to the user. Boost.Test comes with
+/// two formats: "Compiler-like log format" and "XML based log format". Former is intended for human consumption and later is intended for processing
+/// by automated regression test systems. If you want to produce some other format you need to implement class with specific interface and use
+/// method unit_test_log_t::set_formatter during a test module initialization to set an active formatter. The class unit_test_log_formatter defines this
+/// interface.
+///
+/// This interface requires you to format all possible messages being produced in the log. These includes error messages about failed assertions, messages
+/// about caught exceptions and information messages about test units being started/ended. All the methods in this interface takes a reference to standard
+/// stream as a first argument. This is where final messages needs to be directed to. Also you are given all the information necessary to produce a message.
class BOOST_TEST_DECL unit_test_log_formatter {
public:
- enum log_entry_types { BOOST_UTL_ET_INFO,
- BOOST_UTL_ET_MESSAGE,
- BOOST_UTL_ET_WARNING,
- BOOST_UTL_ET_ERROR,
- BOOST_UTL_ET_FATAL_ERROR };
+ /// Types of log entries (messages written into a log)
+ enum log_entry_types { BOOST_UTL_ET_INFO, ///< Information message from the framework
+ BOOST_UTL_ET_MESSAGE, ///< Information message from the user
+ BOOST_UTL_ET_WARNING, ///< Warning (non error) condition notification message
+ BOOST_UTL_ET_ERROR, ///< Non fatal error notification message
+ BOOST_UTL_ET_FATAL_ERROR ///< Fatal error notification message
+ };
// Destructor
virtual ~unit_test_log_formatter() {}
- // Formatter interface
- virtual void log_start( std::ostream&, counter_t test_cases_amount ) = 0;
- virtual void log_finish( std::ostream& ) = 0;
- virtual void log_build_info( std::ostream& ) = 0;
+ // @name Test start/finish
+
+ /// Invoked at the beginning of test module execution
+
+ /// @param[in] os output stream to write a messages to
+ /// @param[in] test_cases_amount total test case amount to be run
+ /// @see log_finish
+ virtual void log_start( std::ostream& os, counter_t test_cases_amount ) = 0;
+
+ /// Invoked at the end of test module execution
+
+ /// @param[in] os output stream to write a messages into
+ /// @see log_start
+ virtual void log_finish( std::ostream& os ) = 0;
- virtual void test_unit_start( std::ostream&, test_unit const& tu ) = 0;
- virtual void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed ) = 0;
- virtual void test_unit_skipped( std::ostream&, test_unit const& ) = 0;
+ /// Invoked when Unit Test Framework build information is requested
- virtual void log_exception( std::ostream& os, log_checkpoint_data const& cd, execution_exception const& ex )
+ /// @param[in] os output stream to write a messages into
+ virtual void log_build_info( std::ostream& os ) = 0;
+ // @}
+
+ // @name Test unit start/finish
+
+ /// Invoked when test unit starts (either test suite or test case)
+
+ /// @param[in] os output stream to write a messages into
+ /// @param[in] tu test unit being started
+ /// @see test_unit_finish
+ virtual void test_unit_start( std::ostream& os, test_unit const& tu ) = 0;
+
+ /// Invoked when test unit finishes
+
+ /// @param[in] os output stream to write a messages into
+ /// @param[in] tu test unit being finished
+ /// @param[in] elapsed time in milliseconds spend executing this test unit
+ /// @see test_unit_start
+ virtual void test_unit_finish( std::ostream& os, test_unit const& tu, unsigned long elapsed ) = 0;
+
+ /// Invoked if test unit skipped for any reason
+
+ /// @param[in] os output stream to write a messages into
+ /// @param[in] tu skipped test unit
+ /// @param[in] reason explanation why was it skipped
+ virtual void test_unit_skipped( std::ostream& os, test_unit const& tu, const_string reason )
{
- // for backward compatibility
- log_exception( os, cd, ex.what() );
+ test_unit_skipped( os, tu );
}
- virtual void log_exception( std::ostream&, log_checkpoint_data const&, const_string /* explanation */ ) {}
- virtual void log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let ) = 0;
- virtual void log_entry_value( std::ostream&, const_string value ) = 0;
- virtual void log_entry_value( std::ostream&, lazy_ostream const& value ); // there is a default impl
- virtual void log_entry_finish( std::ostream& ) = 0;
+ /// Deprecated version of this interface
+ virtual void test_unit_skipped( std::ostream& os, test_unit const& tu ) {}
+
+ // @}
+
+ // @name Uncaught exception report
+
+ /// Invoked when Unit Test Framework detects uncaught exception
+
+ /// Call to this function starts uncaught exception report. It is going to followed by context information. Report is finalized by call to
+ /// log_exception_finish.
+ /// @param[in] os output stream to write a messages into
+ /// @param[in] lcd information about the last checkpoint before the exception was triggered
+ /// @param[in] ex information about the caught exception
+ /// @see log_exception_finish
+ virtual void log_exception_start( std::ostream& os, log_checkpoint_data const& lcd, execution_exception const& ex ) = 0;
+
+ /// Invoked when Unit Test Framework detects uncaught exception
+
+ /// Call to this function finishes uncaught exception report.
+ /// @param[in] os output stream to write a messages into
+ /// @see log_exception_start
+ virtual void log_exception_finish( std::ostream& os ) = 0;
+ // @}
+
+ // @name Regular log entry
+
+ /// Invoked by Unit Test Framework to start new log entry
+
+ /// Call to this function starts new log entry. It is followed by series of log_entry_value calls and finally call to log_entry_finish.
+ /// A log entry may consist of one or more values being reported. Some of these values will be plain strings, while others can be complicated
+ /// expressions in a form of "lazy" expression template lazy_ostream.
+ /// @param[in] os output stream to write a messages into
+ /// @param[in] led log entry attributes
+ /// @param[in] let log entry type log_entry_finish
+ /// @see log_entry_value, log_entry_finish
+ virtual void log_entry_start( std::ostream& os, log_entry_data const& led, log_entry_types let ) = 0;
+
+ /// Invoked by Unit Test Framework to report a log entry content
+
+ /// This is one of two overloaded methods to report log entry content. This one is used to report plain string value.
+ /// @param[in] os output stream to write a messages into.
+ /// @param[in] value log entry string value
+ /// @see log_entry_start, log_entry_finish
+ virtual void log_entry_value( std::ostream& os, const_string value ) = 0;
+
+ /// Invoked by Unit Test Framework to report a log entry content
+
+ /// This is one of two overloaded methods to report log entry content. This one is used to report some complicated expression passed as
+ /// an expression template lazy_ostream. In most cases default implementation provided by the framework should work as is (it just converts
+ /// the lazy expression into a string.
+ /// @param[in] os output stream to write a messages into
+ /// @param[in] value log entry "lazy" value
+ /// @see log_entry_start, log_entry_finish
+ virtual void log_entry_value( std::ostream& os, lazy_ostream const& value ); // there is a default impl
+
+ /// Invoked by Unit Test Framework to finish a log entry report
+
+ /// @param[in] os output stream to write a messages into
+ /// @see log_entry_start, log_entry_start
+ virtual void log_entry_finish( std::ostream& os ) = 0;
+ // @}
+
+ // @name Log entry context report
+
+ /// Invoked by Unit Test Framework to start log entry context report
+
+ /// Unit Test Framework logs for failed assertions and uncaught exceptions context if one was defined by a test module.
+ /// Context consists of multiple "scopes" identified by description messages assigned by the test module using
+ /// BOOST_TEST_INFO/BOOST_TEST_CONTEXT statements.
+ /// @param[in] os output stream to write a messages into
+ /// @param[in] l entry log_leveg, to be used to fine tune the message
+ /// @see log_entry_context, entry_context_finish
+ virtual void entry_context_start( std::ostream& os, log_level l ) = 0;
+
+ /// Invoked by Unit Test Framework to report log entry context "scope" description
+
+ /// Each "scope" description is reported by separate call to log_entry_context.
+ /// @param[in] os output stream to write a messages into
+ /// @param[in] value context "scope" description
+ /// @see log_entry_start, entry_context_finish
+ virtual void log_entry_context( std::ostream& os, const_string value ) = 0;
+
+ /// Invoked by Unit Test Framework to finish log entry context report
+
+ /// @param[in] os output stream to write a messages into
+ /// @see log_entry_start, entry_context_context
+ virtual void entry_context_finish( std::ostream& os ) = 0;
+ // @}
};
} // namespace unit_test
-
} // namespace boost
//____________________________________________________________________________//
diff --git a/boost/test/unit_test_monitor.hpp b/boost/test/unit_test_monitor.hpp
index 9ac1e139f3..b0358352e9 100644
--- a/boost/test/unit_test_monitor.hpp
+++ b/boost/test/unit_test_monitor.hpp
@@ -1,16 +1,14 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : defines specific version of execution monitor used to managed
-// run unit of test cases. Translates execution exception into error level
+/// @file
+/// @brief defines specific version of execution monitor used to managed run unit of test cases
+///
+/// Translates execution exception into error level
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_MONITOR_HPP_020905GER
@@ -20,14 +18,12 @@
#include <boost/test/execution_monitor.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/utils/trivial_singleton.hpp>
-#include <boost/test/utils/callback.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
// ************************************************************************** //
@@ -36,34 +32,29 @@ namespace unit_test {
class BOOST_TEST_DECL unit_test_monitor_t : public singleton<unit_test_monitor_t>, public execution_monitor {
public:
- enum error_level {
- test_fail = 1,
+ enum error_level {
test_ok = 0,
- constructor_error = -1,
- unexpected_exception = -2,
- os_exception = -3,
- os_timeout = -4,
- fatal_error = -5, // includes both system and user
- destructor_error = -6
+ precondition_failure = -1,
+ unexpected_exception = -2,
+ os_exception = -3,
+ os_timeout = -4,
+ fatal_error = -5 // includes both system and user
};
static bool is_critical_error( error_level e ) { return e <= fatal_error; }
// monitor method
- error_level execute_and_translate( test_case const& );
+ error_level execute_and_translate( boost::function<void ()> const& func, unsigned timeout = 0 );
private:
- BOOST_TEST_SINGLETON_CONS( unit_test_monitor_t );
+ BOOST_TEST_SINGLETON_CONS( unit_test_monitor_t )
};
BOOST_TEST_SINGLETON_INST( unit_test_monitor )
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_MONITOR_HPP_020905GER
diff --git a/boost/test/unit_test_parameters.hpp b/boost/test/unit_test_parameters.hpp
new file mode 100644
index 0000000000..31f76d7b2f
--- /dev/null
+++ b/boost/test/unit_test_parameters.hpp
@@ -0,0 +1,92 @@
+// (C) Copyright Gennadiy Rozental 2001-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/test for the library home page.
+//
+/// @file
+/// @brief Provides access to various Unit Test Framework runtime parameters
+///
+/// Primarily for use by the framework itself
+// ***************************************************************************
+
+#ifndef BOOST_TEST_UNIT_TEST_PARAMETERS_HPP_071894GER
+#define BOOST_TEST_UNIT_TEST_PARAMETERS_HPP_071894GER
+
+#include <boost/test/detail/global_typedef.hpp>
+#include <boost/test/detail/log_level.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+// STL
+#include <iosfwd>
+#include <list>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace runtime_config {
+
+// ************************************************************************** //
+// ************** runtime_config ************** //
+// ************************************************************************** //
+
+BOOST_TEST_DECL void init( int& argc, char** argv );
+
+/// Automatically attach debugger in a location of fatal error
+BOOST_TEST_DECL bool auto_start_dbg();
+BOOST_TEST_DECL const_string break_exec_path();
+/// Should we catch system errors/sygnals?
+BOOST_TEST_DECL bool catch_sys_errors();
+/// Should we try to produce color output?
+BOOST_TEST_DECL bool color_output();
+/// Should we detect floating point exceptions?
+BOOST_TEST_DECL bool detect_fp_exceptions();
+/// Should we detect memory leaks (>0)? And if yes, which specific memory allocation should we break.
+BOOST_TEST_DECL long detect_memory_leaks();
+/// List content of test tree?
+BOOST_TEST_DECL output_format list_content();
+/// List available labels?
+BOOST_TEST_DECL bool list_labels();
+/// Which output format to use
+BOOST_TEST_DECL output_format log_format();
+/// Which log level to set
+BOOST_TEST_DECL unit_test::log_level log_level();
+/// Where to direct log stream into
+BOOST_TEST_DECL std::ostream* log_sink();
+/// If memory leak detection, where to direct the report
+BOOST_TEST_DECL const_string memory_leaks_report_file();
+/// Do not prodce result code
+BOOST_TEST_DECL bool no_result_code();
+/// Random seed to use to randomize order of test units being run
+BOOST_TEST_DECL unsigned random_seed();
+/// Which format to use to report results
+BOOST_TEST_DECL output_format report_format();
+/// Wht lever of report format to set
+BOOST_TEST_DECL unit_test::report_level report_level();
+/// Where to direct results report into
+BOOST_TEST_DECL std::ostream* report_sink();
+/// Should we save pattern (true) or match against existing pattern (used by output validation tool)
+BOOST_TEST_DECL bool save_pattern();
+/// Should Unit Test framework show the build information?
+BOOST_TEST_DECL bool show_build_info();
+/// Tells Unit Test Framework to show test progress (forces specific log level)
+BOOST_TEST_DECL bool show_progress();
+/// Specific test units to run/exclude
+BOOST_TEST_DECL std::list<std::string> const& test_to_run();
+/// Should execution monitor use alternative stack for signal handling
+BOOST_TEST_DECL bool use_alt_stack();
+/// Tells Unit Test Framework to wait for debugger to attach
+BOOST_TEST_DECL bool wait_for_debugger();
+
+} // namespace runtime_config
+} // namespace unit_test
+} // namespace boost
+
+//____________________________________________________________________________//
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_UNIT_TEST_PARAMETERS_HPP_071894GER
diff --git a/boost/test/unit_test_suite.hpp b/boost/test/unit_test_suite.hpp
index 048a75f676..41d6151354 100644
--- a/boost/test/unit_test_suite.hpp
+++ b/boost/test/unit_test_suite.hpp
@@ -1,23 +1,24 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : defines Unit Test Framework public API
+/// @file
+/// @brief Defines Unit Test Framework public API
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER
// Boost.Test
-#include <boost/test/unit_test_suite_impl.hpp>
#include <boost/test/framework.hpp>
+#include <boost/test/tree/auto_registration.hpp>
+#include <boost/test/tree/test_case_template.hpp>
+#include <boost/test/tree/global_fixture.hpp>
+
+#include <boost/test/detail/pp_variadic.hpp>
//____________________________________________________________________________//
@@ -25,36 +26,90 @@
// ************** Non-auto (explicit) test case interface ************** //
// ************************************************************************** //
-#define BOOST_TEST_CASE( test_function ) \
-boost::unit_test::make_test_case( boost::unit_test::callback0<>(test_function), BOOST_TEST_STRINGIZE( test_function ) )
-#define BOOST_CLASS_TEST_CASE( test_function, tc_instance ) \
-boost::unit_test::make_test_case((test_function), BOOST_TEST_STRINGIZE( test_function ), tc_instance )
+#define BOOST_TEST_CASE( test_function ) \
+boost::unit_test::make_test_case( boost::function<void ()>(test_function), \
+ BOOST_TEST_STRINGIZE( test_function ), \
+ __FILE__, __LINE__ )
+#define BOOST_CLASS_TEST_CASE( test_function, tc_instance ) \
+boost::unit_test::make_test_case( (test_function), \
+ BOOST_TEST_STRINGIZE( test_function ), \
+ __FILE__, __LINE__, tc_instance )
// ************************************************************************** //
// ************** BOOST_TEST_SUITE ************** //
// ************************************************************************** //
#define BOOST_TEST_SUITE( testsuite_name ) \
-( new boost::unit_test::test_suite( testsuite_name ) )
+( new boost::unit_test::test_suite( testsuite_name, __FILE__, __LINE__ ) )
// ************************************************************************** //
// ************** BOOST_AUTO_TEST_SUITE ************** //
// ************************************************************************** //
-#define BOOST_AUTO_TEST_SUITE( suite_name ) \
+#define BOOST_AUTO_TEST_SUITE_WITH_DECOR( suite_name, decorators ) \
namespace suite_name { \
-BOOST_AUTO_TU_REGISTRAR( suite_name )( BOOST_STRINGIZE( suite_name ) ); \
+BOOST_AUTO_TU_REGISTRAR( suite_name )( \
+ BOOST_STRINGIZE( suite_name ), \
+ __FILE__, __LINE__, \
+ decorators ); \
/**/
+#define BOOST_AUTO_TEST_SUITE_NO_DECOR( suite_name ) \
+ BOOST_AUTO_TEST_SUITE_WITH_DECOR( \
+ suite_name, \
+ boost::unit_test::decorator::collector::instance() ) \
+/**/
+
+#if BOOST_PP_VARIADICS
+#define BOOST_AUTO_TEST_SUITE( ... ) \
+ BOOST_TEST_INVOKE_IF_N_ARGS( 1, \
+ BOOST_AUTO_TEST_SUITE_NO_DECOR, \
+ BOOST_AUTO_TEST_SUITE_WITH_DECOR, \
+ __VA_ARGS__) \
+/**/
+
+#else /* BOOST_PP_VARIADICS */
+
+#define BOOST_AUTO_TEST_SUITE( suite_name ) \
+ BOOST_AUTO_TEST_SUITE_NO_DECOR( suite_name ) \
+/**/
+
+
+#endif /* BOOST_PP_VARIADICS */
+
// ************************************************************************** //
// ************** BOOST_FIXTURE_TEST_SUITE ************** //
// ************************************************************************** //
-#define BOOST_FIXTURE_TEST_SUITE( suite_name, F ) \
-BOOST_AUTO_TEST_SUITE( suite_name ) \
+#define BOOST_FIXTURE_TEST_SUITE_WITH_DECOR(suite_name, F, decorators) \
+ BOOST_AUTO_TEST_SUITE_WITH_DECOR( suite_name, decorators ) \
+typedef F BOOST_AUTO_TEST_CASE_FIXTURE; \
+/**/
+
+#define BOOST_FIXTURE_TEST_SUITE_NO_DECOR( suite_name, F ) \
+ BOOST_AUTO_TEST_SUITE_NO_DECOR( suite_name ) \
typedef F BOOST_AUTO_TEST_CASE_FIXTURE; \
/**/
+#if BOOST_PP_VARIADICS
+
+#define BOOST_FIXTURE_TEST_SUITE( ... ) \
+ BOOST_TEST_INVOKE_IF_N_ARGS( 2, \
+ BOOST_FIXTURE_TEST_SUITE_NO_DECOR, \
+ BOOST_FIXTURE_TEST_SUITE_WITH_DECOR, \
+ __VA_ARGS__) \
+/**/
+
+#else /* BOOST_PP_VARIADICS */
+
+#define BOOST_FIXTURE_TEST_SUITE( suite_name, F ) \
+ BOOST_FIXTURE_TEST_SUITE_NO_DECOR( suite_name, F ) \
+/**/
+
+
+#endif /* BOOST_PP_VARIADICS */
+
+
// ************************************************************************** //
// ************** BOOST_AUTO_TEST_SUITE_END ************** //
// ************************************************************************** //
@@ -68,53 +123,93 @@ BOOST_AUTO_TU_REGISTRAR( BOOST_JOIN( end_suite, __LINE__ ) )( 1 ); \
// ************** BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES ************** //
// ************************************************************************** //
+/// @deprecated use decorator instead
#define BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( test_name, n ) \
-struct BOOST_AUTO_TC_UNIQUE_ID( test_name ); \
- \
-static struct BOOST_JOIN( test_name, _exp_fail_num_spec ) \
-: boost::unit_test::ut_detail:: \
- auto_tc_exp_fail<BOOST_AUTO_TC_UNIQUE_ID( test_name ) > \
-{ \
- BOOST_JOIN( test_name, _exp_fail_num_spec )() \
- : boost::unit_test::ut_detail:: \
- auto_tc_exp_fail<BOOST_AUTO_TC_UNIQUE_ID( test_name ) >( n ) \
- {} \
-} BOOST_JOIN( test_name, _exp_fail_num_spec_inst ); \
- \
+BOOST_TEST_DECORATOR( * boost::unit_test::expected_failures( n ) ) \
/**/
// ************************************************************************** //
// ************** BOOST_FIXTURE_TEST_CASE ************** //
// ************************************************************************** //
-#define BOOST_FIXTURE_TEST_CASE( test_name, F ) \
+#define BOOST_FIXTURE_TEST_CASE_WITH_DECOR( test_name, F, decorators ) \
struct test_name : public F { void test_method(); }; \
\
static void BOOST_AUTO_TC_INVOKER( test_name )() \
{ \
+ BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture entry."); \
test_name t; \
+ BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry."); \
t.test_method(); \
+ BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit."); \
} \
\
struct BOOST_AUTO_TC_UNIQUE_ID( test_name ) {}; \
\
BOOST_AUTO_TU_REGISTRAR( test_name )( \
boost::unit_test::make_test_case( \
- &BOOST_AUTO_TC_INVOKER( test_name ), #test_name ), \
- boost::unit_test::ut_detail::auto_tc_exp_fail< \
- BOOST_AUTO_TC_UNIQUE_ID( test_name )>::instance()->value() ); \
+ &BOOST_AUTO_TC_INVOKER( test_name ), \
+ #test_name, __FILE__, __LINE__ ), \
+ decorators ); \
\
void test_name::test_method() \
/**/
+#define BOOST_FIXTURE_TEST_CASE_NO_DECOR( test_name, F ) \
+BOOST_FIXTURE_TEST_CASE_WITH_DECOR( test_name, F, \
+ boost::unit_test::decorator::collector::instance() ) \
+/**/
+
+#if BOOST_PP_VARIADICS
+
+#define BOOST_FIXTURE_TEST_CASE( ... ) \
+ BOOST_TEST_INVOKE_IF_N_ARGS( 2, \
+ BOOST_FIXTURE_TEST_CASE_NO_DECOR, \
+ BOOST_FIXTURE_TEST_CASE_WITH_DECOR, \
+ __VA_ARGS__) \
+/**/
+
+#else /* BOOST_PP_VARIADICS */
+
+#define BOOST_FIXTURE_TEST_CASE( test_name, F ) \
+ BOOST_FIXTURE_TEST_CASE_NO_DECOR(test_name, F) \
+/**/
+
+
+#endif /* BOOST_PP_VARIADICS */
+
// ************************************************************************** //
// ************** BOOST_AUTO_TEST_CASE ************** //
// ************************************************************************** //
+#define BOOST_AUTO_TEST_CASE_NO_DECOR( test_name ) \
+ BOOST_FIXTURE_TEST_CASE_NO_DECOR( test_name, \
+ BOOST_AUTO_TEST_CASE_FIXTURE ) \
+/**/
+
+#define BOOST_AUTO_TEST_CASE_WITH_DECOR( test_name, decorators ) \
+ BOOST_FIXTURE_TEST_CASE_WITH_DECOR( test_name, \
+ BOOST_AUTO_TEST_CASE_FIXTURE, decorators ) \
+/**/
+
+#if BOOST_PP_VARIADICS
+
+#define BOOST_AUTO_TEST_CASE( ... ) \
+ BOOST_TEST_INVOKE_IF_N_ARGS( 1, \
+ BOOST_AUTO_TEST_CASE_NO_DECOR, \
+ BOOST_AUTO_TEST_CASE_WITH_DECOR, \
+ __VA_ARGS__) \
+/**/
+
+#else /* BOOST_PP_VARIADICS */
+
#define BOOST_AUTO_TEST_CASE( test_name ) \
-BOOST_FIXTURE_TEST_CASE( test_name, BOOST_AUTO_TEST_CASE_FIXTURE )
+ BOOST_AUTO_TEST_CASE_NO_DECOR( test_name ) \
/**/
+
+#endif /* BOOST_PP_VARIADICS */
+
// ************************************************************************** //
// ************** BOOST_FIXTURE_TEST_CASE_TEMPLATE ************** //
// ************************************************************************** //
@@ -128,15 +223,19 @@ struct BOOST_AUTO_TC_INVOKER( test_name ) { \
template<typename TestType> \
static void run( boost::type<TestType>* = 0 ) \
{ \
+ BOOST_TEST_CHECKPOINT('"' << #test_name <<"\" fixture entry."); \
test_name<TestType> t; \
+ BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry."); \
t.test_method(); \
+ BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit."); \
} \
}; \
\
BOOST_AUTO_TU_REGISTRAR( test_name )( \
boost::unit_test::ut_detail::template_test_case_gen< \
BOOST_AUTO_TC_INVOKER( test_name ),TL >( \
- BOOST_STRINGIZE( test_name ) ) ); \
+ BOOST_STRINGIZE( test_name ), __FILE__, __LINE__ ), \
+ boost::unit_test::decorator::collector::instance() ); \
\
template<typename type_name> \
void test_name<type_name>::test_method() \
@@ -147,43 +246,54 @@ void test_name<type_name>::test_method() \
// ************************************************************************** //
#define BOOST_AUTO_TEST_CASE_TEMPLATE( test_name, type_name, TL ) \
-BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_name, type_name, TL, BOOST_AUTO_TEST_CASE_FIXTURE )
+BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_name, type_name, TL, \
+ BOOST_AUTO_TEST_CASE_FIXTURE ) \
+/**/
// ************************************************************************** //
// ************** BOOST_TEST_CASE_TEMPLATE ************** //
// ************************************************************************** //
-#define BOOST_TEST_CASE_TEMPLATE( name, typelist ) \
- boost::unit_test::ut_detail::template_test_case_gen<name,typelist >( \
- BOOST_TEST_STRINGIZE( name ) ) \
+#define BOOST_TEST_CASE_TEMPLATE( name, typelist ) \
+ boost::unit_test::ut_detail::template_test_case_gen<name,typelist>( \
+ BOOST_TEST_STRINGIZE( name ), __FILE__, __LINE__ ) \
/**/
// ************************************************************************** //
// ************** BOOST_TEST_CASE_TEMPLATE_FUNCTION ************** //
// ************************************************************************** //
-#define BOOST_TEST_CASE_TEMPLATE_FUNCTION( name, type_name ) \
-template<typename type_name> \
-void BOOST_JOIN( name, _impl )( boost::type<type_name>* ); \
- \
-struct name { \
- template<typename TestType> \
- static void run( boost::type<TestType>* frwrd = 0 ) \
- { \
- BOOST_JOIN( name, _impl )( frwrd ); \
- } \
-}; \
- \
-template<typename type_name> \
-void BOOST_JOIN( name, _impl )( boost::type<type_name>* ) \
+#define BOOST_TEST_CASE_TEMPLATE_FUNCTION( name, type_name ) \
+template<typename type_name> \
+void BOOST_JOIN( name, _impl )( boost::type<type_name>* ); \
+ \
+struct name { \
+ template<typename TestType> \
+ static void run( boost::type<TestType>* frwrd = 0 ) \
+ { \
+ BOOST_JOIN( name, _impl )( frwrd ); \
+ } \
+}; \
+ \
+template<typename type_name> \
+void BOOST_JOIN( name, _impl )( boost::type<type_name>* ) \
/**/
// ************************************************************************** //
-// ************** BOOST_GLOBAL_FIXURE ************** //
+// ************** BOOST_GLOBAL_FIXTURE ************** //
// ************************************************************************** //
#define BOOST_GLOBAL_FIXTURE( F ) \
-static boost::unit_test::ut_detail::global_fixture_impl<F> BOOST_JOIN( gf_, F ) ; \
+static boost::unit_test::ut_detail::global_fixture_impl<F> BOOST_JOIN( gf_, F ) \
+/**/
+
+// ************************************************************************** //
+// ************** BOOST_TEST_DECORATOR ************** //
+// ************************************************************************** //
+
+#define BOOST_TEST_DECORATOR( D ) \
+static boost::unit_test::decorator::collector const& \
+BOOST_JOIN(decorator_collector,__LINE__) = D; \
/**/
// ************************************************************************** //
@@ -198,15 +308,17 @@ struct nil_t {};
} // unit_test
} // namespace boost
-// Intentionally is in global namespace, so that FIXURE_TEST_SUITE can reset it in user code.
+// Intentionally is in global namespace, so that FIXTURE_TEST_SUITE can reset it in user code.
typedef ::boost::unit_test::ut_detail::nil_t BOOST_AUTO_TEST_CASE_FIXTURE;
// ************************************************************************** //
// ************** Auto registration facility helper macros ************** //
// ************************************************************************** //
-#define BOOST_AUTO_TU_REGISTRAR( test_name ) \
-static boost::unit_test::ut_detail::auto_test_unit_registrar BOOST_JOIN( BOOST_JOIN( test_name, _registrar ), __LINE__ )
+#define BOOST_AUTO_TU_REGISTRAR( test_name ) \
+static boost::unit_test::ut_detail::auto_test_unit_registrar \
+BOOST_JOIN( BOOST_JOIN( test_name, _registrar ), __LINE__ ) \
+/**/
#define BOOST_AUTO_TC_INVOKER( test_name ) BOOST_JOIN( test_name, _invoker )
#define BOOST_AUTO_TC_UNIQUE_ID( test_name ) BOOST_JOIN( test_name, _id )
@@ -226,7 +338,7 @@ init_unit_test_suite( int, char* [] ) {
#ifdef BOOST_TEST_MODULE
using namespace ::boost::unit_test;
assign_op( framework::master_test_suite().p_name.value, BOOST_TEST_STRINGIZE( BOOST_TEST_MODULE ).trim( "\"" ), 0 );
-
+
#endif
#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
diff --git a/boost/test/unit_test_suite_impl.hpp b/boost/test/unit_test_suite_impl.hpp
deleted file mode 100644
index e3573dd9d7..0000000000
--- a/boost/test/unit_test_suite_impl.hpp
+++ /dev/null
@@ -1,434 +0,0 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
-// Distributed under the Boost 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/test for the library home page.
-//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : defines test_unit, test_case, test_case_results, test_suite and test_tree_visitor
-// ***************************************************************************
-
-#ifndef BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER
-#define BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER
-
-// Boost.Test
-#include <boost/test/detail/config.hpp>
-#include <boost/test/detail/global_typedef.hpp>
-#include <boost/test/utils/class_properties.hpp>
-#include <boost/test/utils/callback.hpp>
-#include <boost/test/detail/fwd_decl.hpp>
-#include <boost/test/detail/workaround.hpp>
-#include <boost/test/test_observer.hpp>
-
-// Boost
-#include <boost/shared_ptr.hpp>
-#include <boost/mpl/for_each.hpp>
-#include <boost/mpl/identity.hpp>
-#include <boost/type.hpp>
-#include <boost/type_traits/is_const.hpp>
-
-// STL
-#include <typeinfo> // for typeid
-#include <string> // for std::string
-#include <list> // for std::list
-#include <vector> // for std::vector
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-//____________________________________________________________________________//
-
-namespace boost {
-
-namespace unit_test {
-
-// ************************************************************************** //
-// ************** test_unit ************** //
-// ************************************************************************** //
-
-class BOOST_TEST_DECL test_unit {
-public:
- enum { type = tut_any };
-
- // Constructor
- test_unit( const_string tu_name, test_unit_type t );
-
- // dependencies management
- void depends_on( test_unit* tu );
- bool check_dependencies() const;
-
- // Public r/o properties
- typedef BOOST_READONLY_PROPERTY(test_unit_id,(framework_impl)) id_t;
- typedef BOOST_READONLY_PROPERTY(test_unit_id,(test_suite)) parent_id_t;
- readonly_property<test_unit_type> p_type; // type for this test unit
- readonly_property<const_string> p_type_name; // "case"/"suite"
- id_t p_id; // unique id for this test unit
- parent_id_t p_parent_id; // parent test suite id
-
- // Public r/w properties
- readwrite_property<std::string> p_name; // name for this test unit
- readwrite_property<unsigned> p_timeout; // timeout for the test unit execution
- readwrite_property<counter_t> p_expected_failures; // number of expected failures in this test unit
- mutable readwrite_property<bool> p_enabled; // enabled status for this unit
-
- void increase_exp_fail( unsigned num );
-
-protected:
- ~test_unit();
-
-private:
- // Data members
- std::list<test_unit_id> m_dependencies;
-};
-
-// ************************************************************************** //
-// ************** test_case_generator ************** //
-// ************************************************************************** //
-
-class BOOST_TEST_DECL test_unit_generator {
-public:
- virtual test_unit* next() const = 0;
-
-protected:
- BOOST_TEST_PROTECTED_VIRTUAL ~test_unit_generator() {}
-};
-
-// ************************************************************************** //
-// ************** test_case ************** //
-// ************************************************************************** //
-
-class BOOST_TEST_DECL test_case : public test_unit {
-public:
- enum { type = tut_case };
-
- // Constructor
- test_case( const_string tc_name, callback0<> const& test_func );
-
- // Access methods
- callback0<> const& test_func() const { return m_test_func; }
-
-private:
- friend class framework_impl;
- ~test_case() {}
-
- // BOOST_MSVC <= 1200 have problems with callback as property
- // Data members
- callback0<> m_test_func;
-};
-
-// ************************************************************************** //
-// ************** test_suite ************** //
-// ************************************************************************** //
-
-class BOOST_TEST_DECL test_suite : public test_unit {
-public:
- enum { type = tut_suite };
-
- // Constructor
- explicit test_suite( const_string ts_name );
-
- // test unit list management
- void add( test_unit* tu, counter_t expected_failures = 0, unsigned timeout = 0 );
- void add( test_unit_generator const& gen, unsigned timeout = 0 );
- void remove( test_unit_id id );
-
- // access methods
- test_unit_id get( const_string tu_name ) const;
- std::size_t size() const { return m_members.size(); }
-
-protected:
- friend BOOST_TEST_DECL
- void traverse_test_tree( test_suite const&, test_tree_visitor& );
- friend class framework_impl;
- virtual ~test_suite() {}
-
- // Data members
- std::vector<test_unit_id> m_members;
-};
-
-// ************************************************************************** //
-// ************** master_test_suite ************** //
-// ************************************************************************** //
-
-class BOOST_TEST_DECL master_test_suite_t : public test_suite {
-public:
- master_test_suite_t() : test_suite( "Master Test Suite" )
- , argc( 0 )
- , argv( 0 )
- {}
-
- // Data members
- int argc;
- char** argv;
-};
-
-
-// ************************************************************************** //
-// ************** test_tree_visitor ************** //
-// ************************************************************************** //
-
-class BOOST_TEST_DECL test_tree_visitor {
-public:
- // test tree visitor interface
- virtual void visit( test_case const& ) {}
- virtual bool test_suite_start( test_suite const& ) { return true; }
- virtual void test_suite_finish( test_suite const& ) {}
-
-protected:
- BOOST_TEST_PROTECTED_VIRTUAL ~test_tree_visitor() {}
-};
-
-// ************************************************************************** //
-// ************** traverse_test_tree ************** //
-// ************************************************************************** //
-
-BOOST_TEST_DECL void traverse_test_tree( test_case const&, test_tree_visitor& );
-BOOST_TEST_DECL void traverse_test_tree( test_suite const&, test_tree_visitor& );
-BOOST_TEST_DECL void traverse_test_tree( test_unit_id , test_tree_visitor& );
-
-//____________________________________________________________________________//
-
-inline void
-traverse_test_tree( test_unit const& tu, test_tree_visitor& V )
-{
- if( tu.p_type == tut_case )
- traverse_test_tree( static_cast<test_case const&>( tu ), V );
- else
- traverse_test_tree( static_cast<test_suite const&>( tu ), V );
-}
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** test_case_counter ************** //
-// ************************************************************************** //
-
-class test_case_counter : public test_tree_visitor {
-public:
- // Constructor
- test_case_counter() : p_count( 0 ) {}
-
- BOOST_READONLY_PROPERTY( counter_t, (test_case_counter)) p_count;
-private:
- // test tree visitor interface
- virtual void visit( test_case const& );
- virtual bool test_suite_start( test_suite const& ts ) { return ts.p_enabled; }
-};
-
-// ************************************************************************** //
-// ************** test_being_aborted ************** //
-// ************************************************************************** //
-
-struct BOOST_TEST_DECL test_being_aborted {};
-
-// ************************************************************************** //
-// ************** object generators ************** //
-// ************************************************************************** //
-
-namespace ut_detail {
-
-BOOST_TEST_DECL std::string normalize_test_case_name( const_string tu_name );
-
-template<typename InstanceType,typename UserTestCase>
-struct user_tc_method_invoker {
- typedef void (UserTestCase::*TestMethod )();
-
- user_tc_method_invoker( shared_ptr<InstanceType> inst, TestMethod test_method )
- : m_inst( inst ), m_test_method( test_method ) {}
-
- void operator()() { ((*m_inst).*m_test_method)(); }
-
- shared_ptr<InstanceType> m_inst;
- TestMethod m_test_method;
-};
-
-} // namespace ut_detail
-
-//____________________________________________________________________________//
-
-inline test_case*
-make_test_case( callback0<> const& test_func, const_string tc_name )
-{
- return new test_case( ut_detail::normalize_test_case_name( tc_name ), test_func );
-}
-
-//____________________________________________________________________________//
-
-template<typename UserTestCase, typename InstanceType>
-inline test_case*
-make_test_case( void (UserTestCase::* test_method )(),
- const_string tc_name,
- boost::shared_ptr<InstanceType> user_test_case )
-{
- return new test_case( ut_detail::normalize_test_case_name( tc_name ),
- ut_detail::user_tc_method_invoker<InstanceType,UserTestCase>( user_test_case, test_method ) );
-}
-
-//____________________________________________________________________________//
-
-// ************************************************************************** //
-// ************** auto_test_unit_registrar ************** //
-// ************************************************************************** //
-
-namespace ut_detail {
-
-struct BOOST_TEST_DECL auto_test_unit_registrar
-{
- // Constructors
- auto_test_unit_registrar( test_case* tc, counter_t exp_fail );
- explicit auto_test_unit_registrar( const_string ts_name );
- explicit auto_test_unit_registrar( test_unit_generator const& tc_gen );
- explicit auto_test_unit_registrar( int );
-
-private:
- static std::list<test_suite*>& curr_ts_store();
-};
-
-//____________________________________________________________________________//
-
-template<typename T>
-struct auto_tc_exp_fail {
- auto_tc_exp_fail() : m_value( 0 ) {}
-
- explicit auto_tc_exp_fail( unsigned v )
- : m_value( v )
- {
- instance() = this;
- }
-
- static auto_tc_exp_fail*& instance()
- {
- static auto_tc_exp_fail inst;
- static auto_tc_exp_fail* inst_ptr = &inst;
-
- return inst_ptr;
- }
-
- unsigned value() const { return m_value; }
-
-private:
- // Data members
- unsigned m_value;
-};
-
-//____________________________________________________________________________//
-
-} // namespace ut_detail
-
-// ************************************************************************** //
-// ************** global_fixture ************** //
-// ************************************************************************** //
-
-class BOOST_TEST_DECL global_fixture : public test_observer {
-public:
- // Constructor
- global_fixture();
-};
-
-//____________________________________________________________________________//
-
-namespace ut_detail {
-
-template<typename F>
-struct global_fixture_impl : public global_fixture {
- // Constructor
- global_fixture_impl(): m_fixure( 0 ) {}
-
- // test observer interface
- virtual void test_start( counter_t ) { m_fixure = new F; }
- virtual void test_finish() { delete m_fixure; m_fixure = 0; }
- virtual void test_aborted() { delete m_fixure; m_fixure = 0; }
-
-private:
- // Data members
- F* m_fixure;
-};
-
-// ************************************************************************** //
-// ************** test_case_template_invoker ************** //
-// ************************************************************************** //
-
-template<typename TestCaseTemplate,typename TestType>
-class test_case_template_invoker {
-public:
- void operator()() { TestCaseTemplate::run( (boost::type<TestType>*)0 ); }
-};
-
-// ************************************************************************** //
-// ************** generate_test_case_4_type ************** //
-// ************************************************************************** //
-
-template<typename Generator,typename TestCaseTemplate>
-struct generate_test_case_4_type {
- explicit generate_test_case_4_type( const_string tc_name, Generator& G )
- : m_test_case_name( tc_name )
- , m_holder( G )
- {}
-
- template<typename TestType>
- void operator()( mpl::identity<TestType> )
- {
- std::string full_name;
- assign_op( full_name, m_test_case_name, 0 );
- full_name += '<';
- full_name += typeid(TestType).name();
- if( boost::is_const<TestType>::value )
- full_name += " const";
- full_name += '>';
-
- m_holder.m_test_cases.push_back(
- new test_case( full_name, test_case_template_invoker<TestCaseTemplate,TestType>() ) );
- }
-
-private:
- // Data members
- const_string m_test_case_name;
- Generator& m_holder;
-};
-
-// ************************************************************************** //
-// ************** test_case_template ************** //
-// ************************************************************************** //
-
-template<typename TestCaseTemplate,typename TestTypesList>
-class template_test_case_gen : public test_unit_generator {
-public:
- // Constructor
- template_test_case_gen( const_string tc_name )
- {
- typedef generate_test_case_4_type<template_test_case_gen<TestCaseTemplate,TestTypesList>,
- TestCaseTemplate
- > single_test_gen;
- mpl::for_each<TestTypesList,mpl::make_identity<mpl::_> >( single_test_gen( tc_name, *this ) );
- }
-
- virtual test_unit* next() const
- {
- if( m_test_cases.empty() )
- return 0;
-
- test_unit* res = m_test_cases.front();
- m_test_cases.pop_front();
-
- return res;
- }
-
- // Data members
- mutable std::list<test_unit*> m_test_cases;
-};
-
-//____________________________________________________________________________//
-
-} // namespace ut_detail
-
-} // unit_test
-
-} // namespace boost
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER
-
diff --git a/boost/test/utils/algorithm.hpp b/boost/test/utils/algorithm.hpp
index 1ad389dbaf..7a70654718 100644
--- a/boost/test/utils/algorithm.hpp
+++ b/boost/test/utils/algorithm.hpp
@@ -1,20 +1,18 @@
-// (C) Copyright Gennadiy Rozental 2004-2008.
+// (C) Copyright Gennadiy Rozental 2004-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : addition to STL algorithms
+/// @file
+/// Addition to STL algorithms
// ***************************************************************************
-#ifndef BOOST_ALGORITHM_HPP_062304GER
-#define BOOST_ALGORITHM_HPP_062304GER
+#ifndef BOOST_TEST_UTILS_ALGORITHM_HPP
+#define BOOST_TEST_UTILS_ALGORITHM_HPP
+// STL
#include <utility>
#include <algorithm> // std::find
#include <functional> // std::bind1st
@@ -29,7 +27,7 @@ namespace unit_test {
/// @brief this algorithm search through two collections for first mismatch position that get returned as a pair
/// of iterators, first pointing to the mismatch position in first collection, second iterator in second one
-
+///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
@@ -52,7 +50,7 @@ mismatch( InputIter1 first1, InputIter1 last1,
/// @brief this algorithm search through two collections for first mismatch position that get returned as a pair
/// of iterators, first pointing to the mismatch position in first collection, second iterator in second one. This algorithms
/// uses supplied predicate for collection elements comparison
-
+///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
@@ -75,14 +73,14 @@ mismatch( InputIter1 first1, InputIter1 last1,
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for first element that does not belong a second one
-
+///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template<class ForwardIterator1, class ForwardIterator2>
inline ForwardIterator1
-find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
+find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2 )
{
while( first1 != last1 ) {
@@ -96,9 +94,9 @@ find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
//____________________________________________________________________________//
-/// @brief this algorithm search through first collection for first element that does not satisfy binary
+/// @brief this algorithm search through first collection for first element that does not satisfy binary
/// predicate in conjunction will any element in second collection
-
+///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
@@ -106,8 +104,8 @@ find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
/// @param pred - predicate to be used for search
template<class ForwardIterator1, class ForwardIterator2, class Predicate>
inline ForwardIterator1
-find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
- ForwardIterator2 first2, ForwardIterator2 last2,
+find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
+ ForwardIterator2 first2, ForwardIterator2 last2,
Predicate pred )
{
while( first1 != last1 ) {
@@ -122,14 +120,14 @@ find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for last element that belongs to a second one
-
+///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template<class BidirectionalIterator1, class ForwardIterator2>
inline BidirectionalIterator1
-find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
+find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2 )
{
if( first1 == last1 || first2 == last2 )
@@ -143,9 +141,9 @@ find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
//____________________________________________________________________________//
-/// @brief this algorithm search through first collection for last element that satisfy binary
+/// @brief this algorithm search through first collection for last element that satisfy binary
/// predicate in conjunction will at least one element in second collection
-
+///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
@@ -153,8 +151,8 @@ find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
/// @param pred - predicate to be used for search
template<class BidirectionalIterator1, class ForwardIterator2, class Predicate>
inline BidirectionalIterator1
-find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
- ForwardIterator2 first2, ForwardIterator2 last2,
+find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
+ ForwardIterator2 first2, ForwardIterator2 last2,
Predicate pred )
{
if( first1 == last1 || first2 == last2 )
@@ -169,14 +167,14 @@ find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for last element that does not belong to a second one
-
+///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template<class BidirectionalIterator1, class ForwardIterator2>
inline BidirectionalIterator1
-find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
+find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2 )
{
if( first1 == last1 || first2 == last2 )
@@ -190,9 +188,9 @@ find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
//____________________________________________________________________________//
-/// @brief this algorithm search through first collection for last element that does not satisfy binary
+/// @brief this algorithm search through first collection for last element that does not satisfy binary
/// predicate in conjunction will any element in second collection
-
+///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
@@ -200,8 +198,8 @@ find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
/// @param pred - predicate to be used for search
template<class BidirectionalIterator1, class ForwardIterator2, class Predicate>
inline BidirectionalIterator1
-find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
- ForwardIterator2 first2, ForwardIterator2 last2,
+find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
+ ForwardIterator2 first2, ForwardIterator2 last2,
Predicate pred )
{
if( first1 == last1 || first2 == last2 )
@@ -216,13 +214,10 @@ find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
//____________________________________________________________________________//
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_ALGORITHM_HPP_062304GER
+#endif // BOOST_TEST_UTILS_ALGORITHM_HPP
diff --git a/boost/test/utils/assign_op.hpp b/boost/test/utils/assign_op.hpp
index 434219fa9d..ea49b5148b 100644
--- a/boost/test/utils/assign_op.hpp
+++ b/boost/test/utils/assign_op.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,11 +12,10 @@
// Description : overloadable assignment
// ***************************************************************************
-#ifndef BOOST_TEST_ASSIGN_OP_033005GER
-#define BOOST_TEST_ASSIGN_OP_033005GER
+#ifndef BOOST_TEST_UTILS_ASSIGN_OP_HPP
+#define BOOST_TEST_UTILS_ASSIGN_OP_HPP
namespace boost {
-
namespace unit_test {
// ************************************************************************** //
@@ -34,8 +33,7 @@ assign_op( T& t, S const& s, long )
//____________________________________________________________________________//
} // namespace unit_test
-
} // namespace boost
-#endif // BOOST_TEST_ASSIGN_OP_033005GER
+#endif // BOOST_TEST_UTILS_ASSIGN_OP_HPP
diff --git a/boost/test/utils/basic_cstring/basic_cstring.hpp b/boost/test/utils/basic_cstring/basic_cstring.hpp
index 14742c49f9..7cbd36b328 100644
--- a/boost/test/utils/basic_cstring/basic_cstring.hpp
+++ b/boost/test/utils/basic_cstring/basic_cstring.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2004-2008.
+// (C) Copyright Gennadiy Rozental 2004-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -9,17 +9,20 @@
//
// Version : $Revision$
//
-// Description : class basic_cstring wraps C string and provide std_string like
+// Description : class basic_cstring wraps C string and provide std_string like
// interface
// ***************************************************************************
-#ifndef BOOST_TEST_BASIC_CSTRING_HPP_071894GER
-#define BOOST_TEST_BASIC_CSTRING_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_HPP
+#define BOOST_TEST_UTILS_BASIC_CSTRING_HPP
// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring_fwd.hpp>
#include <boost/test/utils/basic_cstring/bcs_char_traits.hpp>
+// Boost
+#include <boost/type_traits/remove_cv.hpp>
+
// STL
#include <string>
@@ -44,6 +47,7 @@ public:
typedef typename ut_detail::bcs_char_traits<CharT>::std_string std_string;
typedef CharT value_type;
+ typedef typename remove_cv<value_type>::type value_ret_type;
typedef value_type* pointer;
typedef value_type const* const_pointer;
typedef value_type& reference;
@@ -70,12 +74,13 @@ public:
basic_cstring();
basic_cstring( std_string const& s );
basic_cstring( pointer s );
- basic_cstring( pointer s, size_type arg_size );
+ template<typename LenType>
+ basic_cstring( pointer s, LenType len ) : m_begin( s ), m_end( m_begin + len ) {}
basic_cstring( pointer first, pointer last );
// data access methods
- value_type operator[]( size_type index ) const;
- value_type at( size_type index ) const;
+ value_ret_type operator[]( size_type index ) const;
+ value_ret_type at( size_type index ) const;
// size operators
size_type size() const;
@@ -84,25 +89,25 @@ public:
void resize( size_type new_len );
// !! only for STL container conformance use is_empty instead
- bool empty() const;
+ bool empty() const;
// Trimming
self_type& trim_right( size_type trim_size );
self_type& trim_left( size_type trim_size );
self_type& trim_right( iterator it );
self_type& trim_left( iterator it );
-#ifndef __IBMCPP__
+#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(800))
self_type& trim_left( self_type exclusions = self_type() ) ;
self_type& trim_right( self_type exclusions = self_type() ) ;
self_type& trim( self_type exclusions = self_type() ) ;
#else
- // VisualAge version 6 has in this case a problem with the default arguments.
- self_type& trim_left( self_type exclusions ) ;
- self_type& trim_right( self_type exclusions ) ;
- self_type& trim( self_type exclusions ) ;
- self_type& trim_left() { trim_left( self_type() ) ; }
- self_type& trim_right() { trim_right( self_type() ) ; }
- self_type& trim() { trim( self_type() ) ; }
+ // VA C++/XL C++ v6 and v8 has in this case a problem with the default arguments.
+ self_type& trim_left( self_type exclusions );
+ self_type& trim_right( self_type exclusions );
+ self_type& trim( self_type exclusions );
+ self_type& trim_left() { return trim_left( self_type() ); }
+ self_type& trim_right() { return trim_right( self_type() ); }
+ self_type& trim() { return trim( self_type() ); }
#endif
// Assignment operators
@@ -111,12 +116,28 @@ public:
basic_cstring& operator=( pointer s );
template<typename CharT2>
- basic_cstring& assign( basic_cstring<CharT2> const& s ) { *this = basic_cstring<CharT>( s.begin(), s.end() ); return *this; }
- basic_cstring& assign( self_type const& s, size_type pos, size_type len );
+ basic_cstring& assign( basic_cstring<CharT2> const& s )
+ {
+ return *this = basic_cstring<CharT>( s.begin(), s.end() );
+ }
+ template<typename PosType, typename LenType>
+ basic_cstring& assign( self_type const& s, PosType pos, LenType len )
+ {
+ return *this = self_type( s.m_begin + pos, len );
+ }
+
basic_cstring& assign( std_string const& s );
- basic_cstring& assign( std_string const& s, size_type pos, size_type len );
+ template<typename PosType, typename LenType>
+ basic_cstring& assign( std_string const& s, PosType pos, LenType len )
+ {
+ return *this = self_type( s.c_str() + pos, len );
+ }
basic_cstring& assign( pointer s );
- basic_cstring& assign( pointer s, size_type len );
+ template<typename LenType>
+ basic_cstring& assign( pointer s, LenType len )
+ {
+ return *this = self_type( s, len );
+ }
basic_cstring& assign( pointer f, pointer l );
// swapping
@@ -187,15 +208,6 @@ basic_cstring<CharT>::basic_cstring( pointer s )
template<typename CharT>
inline
-basic_cstring<CharT>::basic_cstring( pointer s, size_type arg_size )
-: m_begin( s ), m_end( m_begin + arg_size )
-{
-}
-
-//____________________________________________________________________________//
-
-template<typename CharT>
-inline
basic_cstring<CharT>::basic_cstring( pointer first, pointer last )
: m_begin( first )
, m_end( last )
@@ -205,7 +217,7 @@ basic_cstring<CharT>::basic_cstring( pointer first, pointer last )
//____________________________________________________________________________//
template<typename CharT>
-inline typename basic_cstring<CharT>::value_type
+inline typename basic_cstring<CharT>::value_ret_type
basic_cstring<CharT>::operator[]( size_type index ) const
{
return m_begin[index];
@@ -214,7 +226,7 @@ basic_cstring<CharT>::operator[]( size_type index ) const
//____________________________________________________________________________//
template<typename CharT>
-inline typename basic_cstring<CharT>::value_type
+inline typename basic_cstring<CharT>::value_ret_type
basic_cstring<CharT>::at( size_type index ) const
{
if( m_begin + index >= m_end )
@@ -229,7 +241,7 @@ template<typename CharT>
inline typename basic_cstring<CharT>::size_type
basic_cstring<CharT>::size() const
{
- return m_end - m_begin;
+ return static_cast<size_type>(m_end - m_begin);
}
//____________________________________________________________________________//
@@ -309,7 +321,7 @@ basic_cstring<CharT>::trim_left( basic_cstring exclusions )
if( traits_type::find( exclusions.begin(), exclusions.size(), *it ) == reinterpret_cast<pointer>(0) )
break;
}
-
+
return trim_left( it );
}
@@ -354,7 +366,7 @@ basic_cstring<CharT>::trim_right( basic_cstring exclusions )
if( self_type::traits_type::find( exclusions.begin(), exclusions.size(), *it ) == reinterpret_cast<pointer>(0) )
break;
}
-
+
return trim_right( it+1 );
}
@@ -404,15 +416,6 @@ basic_cstring<CharT>::operator=( pointer s )
template<typename CharT>
inline basic_cstring<CharT>&
-basic_cstring<CharT>::assign( basic_cstring<CharT> const& s, size_type pos, size_type len )
-{
- return *this = self_type( s.m_begin + pos, len );
-}
-
-//____________________________________________________________________________//
-
-template<typename CharT>
-inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( std_string const& s )
{
return *this = self_type( s );
@@ -422,15 +425,6 @@ basic_cstring<CharT>::assign( std_string const& s )
template<typename CharT>
inline basic_cstring<CharT>&
-basic_cstring<CharT>::assign( std_string const& s, size_type pos, size_type len )
-{
- return *this = self_type( s.c_str() + pos, len );
-}
-
-//____________________________________________________________________________//
-
-template<typename CharT>
-inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( pointer s )
{
return *this = self_type( s );
@@ -440,15 +434,6 @@ basic_cstring<CharT>::assign( pointer s )
template<typename CharT>
inline basic_cstring<CharT>&
-basic_cstring<CharT>::assign( pointer s, size_type len )
-{
- return *this = self_type( s, len );
-}
-
-//____________________________________________________________________________//
-
-template<typename CharT>
-inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( pointer f, pointer l )
{
return *this = self_type( f, l );
@@ -526,7 +511,7 @@ basic_cstring<CharT>::find( basic_cstring<CharT> str ) const
++it;
}
- return it == last ? static_cast<size_type>(npos) : it - begin();
+ return it == last ? npos : static_cast<size_type>(it - begin());
}
//____________________________________________________________________________//
@@ -586,7 +571,7 @@ inline bool
operator==( basic_cstring<CharT1> const& s1, basic_cstring<CharT2> const& s2 )
{
typedef typename basic_cstring<CharT1>::traits_type traits_type;
- return s1.size() == s2.size() &&
+ return s1.size() == s2.size() &&
traits_type::compare( s1.begin(), s2.begin(), s1.size() ) == 0;
}
@@ -682,12 +667,12 @@ operator!=( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<C
// ************************************************************************** //
template<typename CharT>
-inline typename basic_cstring<CharT>::value_type
+inline typename basic_cstring<CharT>::value_ret_type
first_char( basic_cstring<CharT> source )
{
- typedef typename basic_cstring<CharT>::value_type string_value_type;
+ typedef typename basic_cstring<CharT>::value_ret_type res_type;
- return source.is_empty() ? static_cast<string_value_type>(0) : *source.begin();
+ return source.is_empty() ? static_cast<res_type>(0) : *source.begin();
}
//____________________________________________________________________________//
@@ -697,12 +682,12 @@ first_char( basic_cstring<CharT> source )
// ************************************************************************** //
template<typename CharT>
-inline typename basic_cstring<CharT>::value_type
+inline typename basic_cstring<CharT>::value_ret_type
last_char( basic_cstring<CharT> source )
{
- typedef typename basic_cstring<CharT>::value_type string_value_type;
+ typedef typename basic_cstring<CharT>::value_ret_type res_type;
- return source.is_empty() ? static_cast<string_value_type>(0) : *(source.end()-1);
+ return source.is_empty() ? static_cast<res_type>(0) : *(source.end()-1);
}
//____________________________________________________________________________//
@@ -720,6 +705,28 @@ assign_op( std::basic_string<CharT1>& target, basic_cstring<CharT2> src, int )
//____________________________________________________________________________//
+template<typename CharT1, typename CharT2>
+inline std::basic_string<CharT1>&
+operator+=( std::basic_string<CharT1>& target, basic_cstring<CharT2> const& str )
+{
+ target.append( str.begin(), str.end() );
+ return target;
+}
+
+//____________________________________________________________________________//
+
+template<typename CharT1, typename CharT2>
+inline std::basic_string<CharT1>
+operator+( std::basic_string<CharT1> const& lhs, basic_cstring<CharT2> const& rhs )
+{
+ std::basic_string<CharT1> res( lhs );
+
+ res.append( rhs.begin(), rhs.end() );
+ return res;
+}
+
+//____________________________________________________________________________//
+
} // namespace unit_test
} // namespace boost
@@ -728,4 +735,4 @@ assign_op( std::basic_string<CharT1>& target, basic_cstring<CharT2> src, int )
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_TEST_BASIC_CSTRING_HPP_071894GER
+#endif // BOOST_TEST_UTILS_BASIC_CSTRING_HPP
diff --git a/boost/test/utils/basic_cstring/basic_cstring_fwd.hpp b/boost/test/utils/basic_cstring/basic_cstring_fwd.hpp
index f3d11a5cd2..a1865f4f94 100644
--- a/boost/test/utils/basic_cstring/basic_cstring_fwd.hpp
+++ b/boost/test/utils/basic_cstring/basic_cstring_fwd.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2004-2008.
+// (C) Copyright Gennadiy Rozental 2004-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -9,12 +9,12 @@
//
// Version : $Revision$
//
-// Description : basic_cstring class wrap C string and provide std_string like
+// Description : basic_cstring class wrap C string and provide std_string like
// interface
// ***************************************************************************
-#ifndef BOOST_TEST_BASIC_CSTRING_FWD_HPP_071894GER
-#define BOOST_TEST_BASIC_CSTRING_FWD_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP
+#define BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP
#include <boost/detail/workaround.hpp>
@@ -36,5 +36,5 @@ typedef char const* const c_literal_string;
} // namespace boost
-#endif // BOOST_TEST_BASIC_CSTRING_FWD_HPP_071894GER
+#endif // BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP
diff --git a/boost/test/utils/basic_cstring/bcs_char_traits.hpp b/boost/test/utils/basic_cstring/bcs_char_traits.hpp
index a97d4616a2..4700d14291 100644
--- a/boost/test/utils/basic_cstring/bcs_char_traits.hpp
+++ b/boost/test/utils/basic_cstring/bcs_char_traits.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2004-2008.
+// (C) Copyright Gennadiy Rozental 2004-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : generic char traits class; wraps std::char_traits
// ***************************************************************************
-#ifndef BOOST_TEST_BCS_CHAR_TRAITS_HPP_071894GER
-#define BOOST_TEST_BCS_CHAR_TRAITS_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_BCS_CHAR_TRAITS_HPP
+#define BOOST_TEST_UTILS_BCS_CHAR_TRAITS_HPP
// Boost
#include <boost/config.hpp>
@@ -119,11 +119,11 @@ struct char_traits_with_find : std::string_char_traits<CharT> {
}
};
-template<> struct bcs_char_traits_impl<char> : char_traits_with_find<char> {};
-template<> struct bcs_char_traits_impl<wchar_t> : char_traits_with_find<wchar_t> {};
+template<> struct bcs_char_traits_impl<char> : public char_traits_with_find<char> {};
+template<> struct bcs_char_traits_impl<wchar_t> : public char_traits_with_find<wchar_t> {};
#else
-template<> struct bcs_char_traits_impl<char> : std::char_traits<char> {};
-template<> struct bcs_char_traits_impl<wchar_t> : std::char_traits<wchar_t> {};
+template<> struct bcs_char_traits_impl<char> : public std::char_traits<char> {};
+template<> struct bcs_char_traits_impl<wchar_t> : public std::char_traits<wchar_t> {};
#endif
template<typename CharT>
@@ -147,4 +147,4 @@ public:
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_TEST_BCS_CHAR_TRAITS_HPP_071894GER
+#endif // BOOST_TEST_UTILS_BCS_CHAR_TRAITS_HPP
diff --git a/boost/test/utils/basic_cstring/compare.hpp b/boost/test/utils/basic_cstring/compare.hpp
index 5c1416f17a..f071a2540c 100644
--- a/boost/test/utils/basic_cstring/compare.hpp
+++ b/boost/test/utils/basic_cstring/compare.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2004-2008.
+// (C) Copyright Gennadiy Rozental 2004-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : class basic_cstring comparisons implementation
// ***************************************************************************
-#ifndef BOOST_TEST_BASIC_CSTRING_COMPARE_HPP_071894GER
-#define BOOST_TEST_BASIC_CSTRING_COMPARE_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_COMPARE_HPP
+#define BOOST_TEST_UTILS_BASIC_CSTRING_COMPARE_HPP
// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
@@ -81,8 +81,8 @@ class case_ins_less : public std::binary_function<basic_cstring<CharT>,basic_cst
public:
bool operator()( basic_cstring<CharT> x, basic_cstring<CharT> y ) const
{
- return x.size() != y.size()
- ? x.size() < y.size()
+ return x.size() != y.size()
+ ? x.size() < y.size()
: ut_detail::case_ins<CharT>::compare( x.begin(), y.begin(), x.size() ) < 0;
}
};
@@ -90,7 +90,7 @@ public:
//____________________________________________________________________________//
// ************************************************************************** //
-// ************** operator < ************** //
+// ************** operators <,> ************** //
// ************************************************************************** //
template<class CharT>
@@ -99,11 +99,43 @@ operator <( boost::unit_test::basic_cstring<CharT> const& x,
boost::unit_test::basic_cstring<CharT> const& y )
{
typedef typename boost::unit_test::basic_cstring<CharT>::traits_type traits_type;
- return x.size() != y.size()
- ? x.size() < y.size()
+ return x.size() != y.size()
+ ? x.size() < y.size()
: traits_type::compare( x.begin(), y.begin(), x.size() ) < 0;
}
+//____________________________________________________________________________//
+
+template<class CharT>
+inline bool
+operator <=( boost::unit_test::basic_cstring<CharT> const& x,
+ boost::unit_test::basic_cstring<CharT> const& y )
+{
+ return !(y < x);
+}
+
+//____________________________________________________________________________//
+
+template<class CharT>
+inline bool
+operator >( boost::unit_test::basic_cstring<CharT> const& x,
+ boost::unit_test::basic_cstring<CharT> const& y )
+{
+ return y < x;
+}
+
+//____________________________________________________________________________//
+
+template<class CharT>
+inline bool
+operator >=( boost::unit_test::basic_cstring<CharT> const& x,
+ boost::unit_test::basic_cstring<CharT> const& y )
+{
+ return !(x < y);
+}
+
+//____________________________________________________________________________//
+
} // namespace unit_test
} // namespace boost
diff --git a/boost/test/utils/basic_cstring/io.hpp b/boost/test/utils/basic_cstring/io.hpp
index 1c8a2a3826..218ae6a520 100644
--- a/boost/test/utils/basic_cstring/io.hpp
+++ b/boost/test/utils/basic_cstring/io.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2004-2008.
+// (C) Copyright Gennadiy Rozental 2004-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : basic_cstring i/o implementation
// ***************************************************************************
-#ifndef BOOST_TEST_BASIC_CSTRING_IO_HPP_071894GER
-#define BOOST_TEST_BASIC_CSTRING_IO_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_IO_HPP
+#define BOOST_TEST_UTILS_BASIC_CSTRING_IO_HPP
// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
diff --git a/boost/test/utils/callback.hpp b/boost/test/utils/callback.hpp
deleted file mode 100644
index 6aa0a15773..0000000000
--- a/boost/test/utils/callback.hpp
+++ /dev/null
@@ -1,310 +0,0 @@
-// (C) Copyright Gennadiy Rozental 2005-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)
-
-// See http://www.boost.org/libs/test for the library home page.
-//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description :
-// ***************************************************************************
-
-#ifndef BOOST_TEST_CALLBACK_020505GER
-#define BOOST_TEST_CALLBACK_020505GER
-
-// Boost
-#include <boost/config.hpp>
-#include <boost/detail/workaround.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) || BOOST_WORKAROUND(BOOST_INTEL, <= 700)
-# define BOOST_CALLBACK_EXPLICIT_COPY_CONSTRUCTOR
-#endif
-
-//____________________________________________________________________________//
-
-namespace boost {
-
-namespace unit_test {
-
-namespace ut_detail {
-
-struct unused {};
-
-template<typename R>
-struct invoker {
- template<typename Functor>
- R invoke( Functor& f ) { return f(); }
- template<typename Functor, typename T1>
- R invoke( Functor& f, T1 t1 ) { return f( t1 ); }
- template<typename Functor, typename T1, typename T2>
- R invoke( Functor& f, T1 t1, T2 t2 ) { return f( t1, t2 ); }
- template<typename Functor, typename T1, typename T2, typename T3>
- R invoke( Functor& f, T1 t1, T2 t2, T3 t3 ) { return f( t1, t2, t3 ); }
-};
-
-//____________________________________________________________________________//
-
-template<>
-struct invoker<unused> {
- template<typename Functor>
- unused invoke( Functor& f ) { f(); return unused(); }
- template<typename Functor, typename T1>
- unused invoke( Functor& f, T1 t1 ) { f( t1 ); return unused(); }
- template<typename Functor, typename T1, typename T2>
- unused invoke( Functor& f, T1 t1, T2 t2 ) { f( t1, t2 ); return unused(); }
- template<typename Functor, typename T1, typename T2, typename T3>
- unused invoke( Functor& f, T1 t1, T2 t2, T3 t3 ) { f( t1, t2, t3 ); return unused(); }
-};
-
-//____________________________________________________________________________//
-
-} // namespace ut_detail
-
-// ************************************************************************** //
-// ************** unit_test::callback0 ************** //
-// ************************************************************************** //
-
-namespace ut_detail {
-
-template<typename R>
-struct callback0_impl {
- virtual ~callback0_impl() {}
-
- virtual R invoke() = 0;
-};
-
-//____________________________________________________________________________//
-
-template<typename R, typename Functor>
-struct callback0_impl_t : callback0_impl<R> {
- // Constructor
- explicit callback0_impl_t( Functor f ) : m_f( f ) {}
-
- virtual R invoke() { return invoker<R>().invoke( m_f ); }
-
-private:
- // Data members
- Functor m_f;
-};
-
-//____________________________________________________________________________//
-
-} // namespace ut_detail
-
-template<typename R = ut_detail::unused>
-class callback0 {
-public:
- // Constructors
- callback0() {}
-#ifdef BOOST_CALLBACK_EXPLICIT_COPY_CONSTRUCTOR
- callback0( callback0 const& rhs ) : m_impl( rhs.m_impl ) {}
-#endif
-
- template<typename Functor>
- callback0( Functor f )
- : m_impl( new ut_detail::callback0_impl_t<R,Functor>( f ) ) {}
-
- void operator=( callback0 const& rhs ) { m_impl = rhs.m_impl; }
-
- template<typename Functor>
- void operator=( Functor f ) { m_impl.reset( new ut_detail::callback0_impl_t<R,Functor>( f ) ); }
-
- R operator()() const { return m_impl->invoke(); }
-
- bool operator!() const { return !m_impl; }
-
-private:
- // Data members
- boost::shared_ptr<ut_detail::callback0_impl<R> > m_impl;
-};
-
-// ************************************************************************** //
-// ************** unit_test::callback1 ************** //
-// ************************************************************************** //
-
-namespace ut_detail {
-
-template<typename R, typename T1>
-struct callback1_impl {
- virtual ~callback1_impl() {}
-
- virtual R invoke( T1 t1 ) = 0;
-};
-
-//____________________________________________________________________________//
-
-template<typename R, typename T1,typename Functor>
-struct callback1_impl_t : callback1_impl<R,T1> {
- // Constructor
- explicit callback1_impl_t( Functor f ) : m_f( f ) {}
-
- virtual R invoke( T1 t1 ) { return invoker<R>().invoke( m_f, t1 ); }
-
-private:
- // Data members
- Functor m_f;
-};
-
-//____________________________________________________________________________//
-
-} // namespace ut_detail
-
-template<typename T1,typename R = ut_detail::unused>
-class callback1 {
-public:
- // Constructors
- callback1() {}
-#ifdef BOOST_CALLBACK_EXPLICIT_COPY_CONSTRUCTOR
- callback1( callback1 const& rhs ) : m_impl( rhs.m_impl ) {}
-#endif
-
- template<typename Functor>
- callback1( Functor f )
- : m_impl( new ut_detail::callback1_impl_t<R,T1,Functor>( f ) ) {}
-
- void operator=( callback1 const& rhs ) { m_impl = rhs.m_impl; }
-
- template<typename Functor>
- void operator=( Functor f ) { m_impl.reset( new ut_detail::callback1_impl_t<R,T1,Functor>( f ) ); }
-
- R operator()( T1 t1 ) const { return m_impl->invoke( t1 ); }
-
- bool operator!() const { return !m_impl; }
-
-private:
- // Data members
- boost::shared_ptr<ut_detail::callback1_impl<R,T1> > m_impl;
-};
-
-// ************************************************************************** //
-// ************** unit_test::callback2 ************** //
-// ************************************************************************** //
-
-namespace ut_detail {
-
-template<typename R, typename T1,typename T2>
-struct callback2_impl {
- virtual ~callback2_impl() {}
-
- virtual R invoke( T1 t1, T2 t2 ) = 0;
-};
-
-//____________________________________________________________________________//
-
-template<typename R, typename T1, typename T2, typename Functor>
-struct callback2_impl_t : callback2_impl<R,T1,T2> {
- // Constructor
- explicit callback2_impl_t( Functor f ) : m_f( f ) {}
-
- virtual R invoke( T1 t1, T2 t2 ) { return invoker<R>().template invoke<Functor,T1,T2>( m_f, t1, t2 ); }
-
-private:
- // Data members
- Functor m_f;
-};
-
-//____________________________________________________________________________//
-
-} // namespace ut_detail
-
-template<typename T1,typename T2, typename R = ut_detail::unused>
-class callback2 {
-public:
- // Constructors
- callback2() {}
-#ifdef BOOST_CALLBACK_EXPLICIT_COPY_CONSTRUCTOR
- callback2( callback2 const& rhs ) : m_impl( rhs.m_impl ) {}
-#endif
-
- template<typename Functor>
- callback2( Functor f ) : m_impl( new ut_detail::callback2_impl_t<R,T1,T2,Functor>( f ) ) {}
-
- void operator=( callback2 const& rhs ) { m_impl = rhs.m_impl; }
-
- template<typename Functor>
- void operator=( Functor f ) { m_impl.reset( new ut_detail::callback2_impl_t<R,T1,T2,Functor>( f ) ); }
-
- R operator()( T1 t1, T2 t2 ) const { return m_impl->invoke( t1, t2 ); }
-
- bool operator!() const { return !m_impl; }
-
-private:
- // Data members
- boost::shared_ptr<ut_detail::callback2_impl<R,T1,T2> > m_impl;
-};
-
-// ************************************************************************** //
-// ************** unit_test::callback3 ************** //
-// ************************************************************************** //
-
-namespace ut_detail {
-
-template<typename R, typename T1, typename T2, typename T3>
-struct callback3_impl {
- virtual ~callback3_impl() {}
-
- virtual R invoke( T1 t1, T2 t2, T3 t3 ) = 0;
-};
-
-//____________________________________________________________________________//
-
-template<typename R, typename T1, typename T2, typename T3, typename Functor>
-struct callback3_impl_t : callback3_impl<R,T1,T2,T3> {
- // Constructor
- explicit callback3_impl_t( Functor f ) : m_f( f ) {}
-
- virtual R invoke( T1 t1, T2 t2, T3 t3 ) { return invoker<R>().invoke( m_f, t1, t2, t3 ); }
-
-private:
- // Data members
- Functor m_f;
-};
-
-//____________________________________________________________________________//
-
-} // namespace ut_detail
-
-template<typename T1,typename T2, typename T3, typename R = ut_detail::unused>
-class callback3 {
-public:
- // Constructors
- callback3() {}
-#ifdef BOOST_CALLBACK_EXPLICIT_COPY_CONSTRUCTOR
- callback3( callback3 const& rhs ) : m_impl( rhs.m_impl ) {}
-#endif
-
- template<typename Functor>
- callback3( Functor f )
- : m_impl( new ut_detail::callback3_impl_t<R,T1,T2,T3,Functor>( f ) ) {}
-
- void operator=( callback3 const& rhs ) { m_impl = rhs.m_impl; }
-
- template<typename Functor>
- void operator=( Functor f ) { m_impl.reset( new ut_detail::callback3_impl_t<R,T1,T2,T3,Functor>( f ) ); }
-
- R operator()( T1 t1, T2 t2, T3 t3 ) const { return m_impl->invoke( t1, t2, t3 ); }
-
- bool operator!() const { return !m_impl; }
-
-private:
- // Data members
- boost::shared_ptr<ut_detail::callback3_impl<R,T1,T2,T3> > m_impl;
-};
-
-} // namespace unit_test
-
-} // namespace boost
-
-#undef BOOST_CALLBACK_EXPLICIT_COPY_CONSTRUCTOR
-
-//____________________________________________________________________________//
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // BOOST_TEST_CALLBACK_020505GER
diff --git a/boost/test/utils/class_properties.hpp b/boost/test/utils/class_properties.hpp
index d2070dc97a..1781a17dd0 100644
--- a/boost/test/utils/class_properties.hpp
+++ b/boost/test/utils/class_properties.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -9,12 +9,12 @@
//
// Version : $Revision$
//
-// Description : simple facility that mimmic notion of read-only read-write
+// Description : simple facility that mimmic notion of read-only read-write
// properties in C++ classes. Original idea by Henrik Ravn.
// ***************************************************************************
-#ifndef BOOST_TEST_CLASS_PROPERTIES_HPP_071894GER
-#define BOOST_TEST_CLASS_PROPERTIES_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_CLASS_PROPERTIES_HPP
+#define BOOST_TEST_UTILS_CLASS_PROPERTIES_HPP
// Boost.Test
#include <boost/test/detail/config.hpp>
@@ -36,7 +36,6 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
// ************************************************************************** //
@@ -116,28 +115,6 @@ DEFINE_PROPERTY_FREE_BINARY_OPERATOR( != )
#undef DEFINE_PROPERTY_FREE_BINARY_OPERATOR
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-
-#define DEFINE_PROPERTY_LOGICAL_OPERATOR( op ) \
-template<class PropertyType> \
-inline bool \
-operator op( bool b, class_property<PropertyType> const& p ) \
-{ \
- return b op p.get(); \
-} \
-template<class PropertyType> \
-inline bool \
-operator op( class_property<PropertyType> const& p, bool b ) \
-{ \
- return b op p.get(); \
-} \
-/**/
-
-DEFINE_PROPERTY_LOGICAL_OPERATOR( && )
-DEFINE_PROPERTY_LOGICAL_OPERATOR( || )
-
-#endif
-
// ************************************************************************** //
// ************** readonly_property ************** //
// ************************************************************************** //
@@ -209,13 +186,10 @@ public:
//____________________________________________________________________________//
} // unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#undef BOOST_TEST_NO_PROTECTED_USING
-#endif // BOOST_TEST_CLASS_PROPERTIES_HPP_071894GER
+#endif // BOOST_TEST_UTILS_CLASS_PROPERTIES_HPP
diff --git a/boost/test/utils/custom_manip.hpp b/boost/test/utils/custom_manip.hpp
index 52705a9703..43b581df16 100644
--- a/boost/test/utils/custom_manip.hpp
+++ b/boost/test/utils/custom_manip.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : simple helpers for creating cusom output manipulators
// ***************************************************************************
-#ifndef BOOST_TEST_CUSTOM_MANIP_HPP_071894GER
-#define BOOST_TEST_CUSTOM_MANIP_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_CUSTOM_MANIP_HPP
+#define BOOST_TEST_UTILS_CUSTOM_MANIP_HPP
// STL
#include <iosfwd>
@@ -23,7 +23,6 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
// ************************************************************************** //
@@ -53,11 +52,8 @@ operator<<( std::ostream& ostr, custom_manip<Uniq> const& ) { return custom_prin
//____________________________________________________________________________//
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_TEST_CUSTOM_MANIP_HPP_071894GER
+#endif // BOOST_TEST_UTILS_CUSTOM_MANIP_HPP
diff --git a/boost/test/utils/fixed_mapping.hpp b/boost/test/utils/fixed_mapping.hpp
index e8139337bb..299a77b789 100644
--- a/boost/test/utils/fixed_mapping.hpp
+++ b/boost/test/utils/fixed_mapping.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : fixed sized mapping with specified invalid value
// ***************************************************************************
-#ifndef BOOST_TEST_FIXED_MAPPING_HPP_071894GER
-#define BOOST_TEST_FIXED_MAPPING_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_FIXED_MAPPING_HPP
+#define BOOST_TEST_UTILS_FIXED_MAPPING_HPP
// Boost
#include <boost/preprocessor/repetition/repeat.hpp>
@@ -32,7 +32,6 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
// configurable maximum fixed sized mapping size supported by this header.
@@ -107,11 +106,8 @@ private:
};
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
#undef MAX_MAP_SIZE
@@ -120,5 +116,5 @@ private:
#undef CONSTR_DECL
#undef CONTRUCTORS
-#endif // BOOST_TEST_FIXED_MAPPING_HPP_071894GER
+#endif // BOOST_TEST_UTILS_FIXED_MAPPING_HPP
diff --git a/boost/test/utils/foreach.hpp b/boost/test/utils/foreach.hpp
index da32ae300f..d57b628cd3 100644
--- a/boost/test/utils/foreach.hpp
+++ b/boost/test/utils/foreach.hpp
@@ -1,5 +1,5 @@
// (C) Copyright Eric Niebler 2004-2005
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 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)
@@ -11,14 +11,14 @@
// Version : $Revision$
//
// Description : this is an abridged version of an excelent BOOST_FOREACH facility
-// presented by Eric Niebler. I am so fond of it so I can't wait till it
-// going to be accepted into Boost. Also I need version with less number of dependencies
-// and more portable. This version doesn't support rvalues and will reeveluate it's
+// presented by Eric Niebler. I am so fond of it so I can't wait till it
+// going to be accepted into Boost. Also I need version with less number of dependencies
+// and more portable. This version doesn't support rvalues and will reeveluate it's
// parameters, but should be good enough for my purposes.
// ***************************************************************************
-#ifndef BOOST_TEST_FOREACH_HPP_021005GER
-#define BOOST_TEST_FOREACH_HPP_021005GER
+#ifndef BOOST_TEST_UTILS_FOREACH_HPP
+#define BOOST_TEST_UTILS_FOREACH_HPP
// Boost.Test
#include <boost/test/detail/config.hpp>
@@ -35,9 +35,7 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
-
namespace for_each {
// ************************************************************************** //
@@ -178,6 +176,28 @@ next( static_any_t cur, C const&, mpl::true_ )
//____________________________________________________________________________//
// ************************************************************************** //
+// ************** prev ************** //
+// ************************************************************************** //
+
+template<typename C>
+inline void
+prev( static_any_t cur, C&, mpl::false_ )
+{
+ --static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur );
+}
+
+//____________________________________________________________________________//
+
+template<typename C>
+inline void
+prev( static_any_t cur, C const&, mpl::true_ )
+{
+ --static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur );
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
// ************** deref ************** //
// ************************************************************************** //
@@ -233,6 +253,13 @@ deref( static_any_t cur, C const&, ::boost::type<RefType>, mpl::true_ )
BOOST_TEST_FE_IS_CONST( COL ) ) \
/**/
+#define BOOST_TEST_FE_PREV( COL ) \
+ ::boost::unit_test::for_each::prev( \
+ BOOST_TEST_FE_CUR_VAR, \
+ COL, \
+ BOOST_TEST_FE_IS_CONST( COL ) ) \
+/**/
+
#define BOOST_FOREACH_NOOP(COL) \
((void)&(COL))
@@ -266,16 +293,24 @@ for( bool BOOST_TEST_FE_CON_VAR = true;
!BOOST_TEST_FE_CON_VAR; BOOST_TEST_FE_CON_VAR = true ) \
/**/
+#define BOOST_TEST_REVERSE_FOREACH( RefType, var, COL ) \
+if( BOOST_TEST_FE_ANY BOOST_TEST_FE_CUR_VAR = BOOST_TEST_FE_END( COL ) ) {} else \
+if( BOOST_TEST_FE_ANY BOOST_TEST_FE_END_VAR = BOOST_TEST_FE_BEG( COL ) ) {} else \
+for( bool BOOST_TEST_FE_CON_VAR = true; \
+ BOOST_TEST_FE_CON_VAR && !BOOST_TEST_FE_DONE( COL ); ) \
+ \
+ if( (BOOST_TEST_FE_CON_VAR = false, false) ) {} else \
+ if( (BOOST_TEST_FE_PREV( COL ), false) ) {} else \
+ for( RefType var = BOOST_TEST_FE_DEREF( COL, RefType ); \
+ !BOOST_TEST_FE_CON_VAR; BOOST_TEST_FE_CON_VAR = true ) \
+/**/
+
//____________________________________________________________________________//
} // namespace for_each
-
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_TEST_FOREACH_HPP_021005GER
+#endif // BOOST_TEST_UTILS_FOREACH_HPP
diff --git a/boost/test/utils/is_cstring.hpp b/boost/test/utils/is_cstring.hpp
new file mode 100644
index 0000000000..5172246c67
--- /dev/null
+++ b/boost/test/utils/is_cstring.hpp
@@ -0,0 +1,58 @@
+// (C) Copyright Gennadiy Rozental 2012-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision$
+//
+// Description : defines the is_cstring type trait
+// ***************************************************************************
+
+#ifndef BOOST_TEST_UTILS_IS_CSTRING_HPP
+#define BOOST_TEST_UTILS_IS_CSTRING_HPP
+
+// Boost
+#include <boost/mpl/bool.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/decay.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+
+// ************************************************************************** //
+// ************** is_cstring ************** //
+// ************************************************************************** //
+
+namespace ut_detail {
+
+template<typename T>
+struct is_cstring_impl : public mpl::false_ {};
+
+template<typename T>
+struct is_cstring_impl<T const*> : public is_cstring_impl<T*> {};
+
+template<typename T>
+struct is_cstring_impl<T const* const> : public is_cstring_impl<T*> {};
+
+template<>
+struct is_cstring_impl<char*> : public mpl::true_ {};
+
+template<>
+struct is_cstring_impl<wchar_t*> : public mpl::true_ {};
+
+} // namespace ut_detail
+
+template<typename T>
+struct is_cstring : public ut_detail::is_cstring_impl<typename decay<T>::type> {};
+
+} // namespace unit_test
+} // namespace boost
+
+#endif // BOOST_TEST_UTILS_IS_CSTRING_HPP
diff --git a/boost/test/utils/is_forward_iterable.hpp b/boost/test/utils/is_forward_iterable.hpp
new file mode 100644
index 0000000000..8b46b1b268
--- /dev/null
+++ b/boost/test/utils/is_forward_iterable.hpp
@@ -0,0 +1,152 @@
+// (C) Copyright Gennadiy Rozental 2012-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/test for the library home page.
+//
+//! @file
+//! Defines the is_forward_iterable collection type trait
+// ***************************************************************************
+
+#ifndef BOOST_TEST_UTILS_IS_FORWARD_ITERABLE_HPP
+#define BOOST_TEST_UTILS_IS_FORWARD_ITERABLE_HPP
+
+#if defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_NULLPTR) || defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
+ #define BOOST_TEST_FWD_ITERABLE_CXX03
+#endif
+
+
+#if defined(BOOST_TEST_FWD_ITERABLE_CXX03)
+// Boost
+#include <boost/mpl/bool.hpp>
+
+// STL
+#include <list>
+#include <vector>
+#include <map>
+#include <set>
+
+#else
+
+// Boost
+#include <boost/utility/declval.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/test/utils/is_cstring.hpp>
+
+// STL
+#include <utility>
+#include <type_traits>
+
+#endif
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+
+// ************************************************************************** //
+// ************** is_forward_iterable ************** //
+// ************************************************************************** //
+
+#if defined(BOOST_TEST_FWD_ITERABLE_CXX03) && !defined(BOOST_TEST_DOXYGEN_DOC__)
+template<typename T>
+struct is_forward_iterable : public mpl::false_ {};
+
+template<typename T>
+struct is_forward_iterable<T const> : public is_forward_iterable<T> {};
+
+template<typename T>
+struct is_forward_iterable<T&> : public is_forward_iterable<T> {};
+
+template<typename T, typename A>
+struct is_forward_iterable< std::vector<T, A> > : public mpl::true_ {};
+
+template<typename T, typename A>
+struct is_forward_iterable< std::list<T, A> > : public mpl::true_ {};
+
+template<typename K, typename V, typename C, typename A>
+struct is_forward_iterable< std::map<K, V, C, A> > : public mpl::true_ {};
+
+template<typename K, typename C, typename A>
+struct is_forward_iterable< std::set<K, C, A> > : public mpl::true_ {};
+
+#else
+
+namespace ut_detail {
+
+ template<typename T>
+ struct is_present : public mpl::true_ {};
+
+ // some compiler do not implement properly decltype non expression involving members (eg. VS2013)
+ // a workaround is to use -> decltype syntax.
+ template <class T>
+ struct has_member_size {
+ private:
+ struct nil_t {};
+ template<typename U> static auto test(U*) -> decltype( boost::declval<U>().size() );
+ template<typename> static nil_t test(...);
+
+ public:
+ static bool const value = !std::is_same< decltype(test<T>(nullptr)), nil_t>::value;
+ };
+
+ template <class T>
+ struct has_member_begin {
+ private:
+ struct nil_t {};
+ template<typename U> static auto test(U*) -> decltype( boost::declval<U>().begin() );
+ template<typename> static nil_t test(...);
+ public:
+ static bool const value = !std::is_same< decltype(test<T>(nullptr)), nil_t>::value;
+ };
+
+ template <class T>
+ struct has_member_end {
+ private:
+ struct nil_t {};
+ template<typename U> static auto test(U*) -> decltype( boost::declval<U>().end() );
+ template<typename> static nil_t test(...);
+ public:
+ static bool const value = !std::is_same< decltype(test<T>(nullptr)), nil_t>::value;
+ };
+
+ template <class T, class enabled = void>
+ struct is_forward_iterable_impl : std::false_type
+ {};
+
+ template <class T>
+ struct is_forward_iterable_impl<
+ T,
+ typename std::enable_if<
+ is_present<typename T::const_iterator>::value &&
+ is_present<typename T::value_type>::value &&
+ has_member_size<T>::value &&
+ has_member_begin<T>::value &&
+ has_member_end<T>::value &&
+ !is_cstring<T>::value
+ >::type
+ > : std::true_type
+ {};
+
+
+} // namespace ut_detail
+
+
+/*! Indicates that a specific type implements the forward iterable concept.
+ */
+template<typename T>
+struct is_forward_iterable {
+ typedef typename std::remove_reference<T>::type T_ref;
+ typedef ut_detail::is_forward_iterable_impl<T_ref> is_fwd_it_t;
+ typedef mpl::bool_<is_fwd_it_t::value> type;
+ enum { value = is_fwd_it_t::value };
+};
+
+#endif /* defined(BOOST_TEST_FWD_ITERABLE_CXX03) */
+
+} // namespace unit_test
+} // namespace boost
+
+#endif // BOOST_TEST_UTILS_IS_FORWARD_ITERABLE_HPP
diff --git a/boost/test/utils/iterator/ifstream_line_iterator.hpp b/boost/test/utils/iterator/ifstream_line_iterator.hpp
index d41b09d8f8..9a2154828c 100644
--- a/boost/test/utils/iterator/ifstream_line_iterator.hpp
+++ b/boost/test/utils/iterator/ifstream_line_iterator.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2004-2008.
+// (C) Copyright Gennadiy Rozental 2004-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -9,11 +9,11 @@
//
// Version : $Revision$
//
-// Description :
+// Description :
// ***************************************************************************
-#ifndef BOOST_IFSTREAM_LINE_ITERATOR_HPP_071894GER
-#define BOOST_IFSTREAM_LINE_ITERATOR_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_IFSTREAM_LINE_ITERATOR_HPP
+#define BOOST_TEST_UTILS_IFSTREAM_LINE_ITERATOR_HPP
// Boost
#include <boost/test/utils/iterator/istream_line_iterator.hpp>
@@ -87,6 +87,7 @@ public:
#ifdef BOOST_MSVC
# pragma warning(default: 4355)
+# pragma warning(pop)
#endif
typedef basic_ifstream_line_iterator<char> ifstream_line_iterator;
@@ -100,5 +101,5 @@ typedef basic_ifstream_line_iterator<wchar_t> wifstream_line_iterator;
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_IFSTREAM_LINE_ITERATOR_HPP_071894GER
+#endif // BOOST_TEST_UTILS_IFSTREAM_LINE_ITERATOR_HPP
diff --git a/boost/test/utils/iterator/input_iterator_facade.hpp b/boost/test/utils/iterator/input_iterator_facade.hpp
index 6ce07b2af2..a160808971 100644
--- a/boost/test/utils/iterator/input_iterator_facade.hpp
+++ b/boost/test/utils/iterator/input_iterator_facade.hpp
@@ -1,19 +1,16 @@
-// (C) Copyright Gennadiy Rozental 2004-2008.
+// (C) Copyright Gennadiy Rozental 2004-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : Input iterator facade
+//!@file
+//! Input iterator facade
// ***************************************************************************
-#ifndef BOOST_INPUT_ITERATOR_FACADE_HPP_071894GER
-#define BOOST_INPUT_ITERATOR_FACADE_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_INPUT_ITERATOR_FACADE_HPP
+#define BOOST_TEST_UTILS_INPUT_ITERATOR_FACADE_HPP
// Boost
#include <boost/iterator/iterator_facade.hpp>
@@ -80,7 +77,7 @@ private:
// iterator facade interface implementation
void increment()
{
- // we make post-end incrementation indefinetly safe
+ // we make post-end incrementation indefinetly safe
if( m_valid )
m_valid = input_iterator_core_access::get( *static_cast<Derived*>(this) );
}
@@ -105,5 +102,5 @@ private:
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_INPUT_ITERATOR_FACADE_HPP_071894GER
+#endif // BOOST_TEST_UTILS_INPUT_ITERATOR_FACADE_HPP
diff --git a/boost/test/utils/iterator/istream_line_iterator.hpp b/boost/test/utils/iterator/istream_line_iterator.hpp
index 5aa517d7c8..f75be9ca77 100644
--- a/boost/test/utils/iterator/istream_line_iterator.hpp
+++ b/boost/test/utils/iterator/istream_line_iterator.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2004-2008.
+// (C) Copyright Gennadiy Rozental 2004-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -9,11 +9,11 @@
//
// Version : $Revision$
//
-// Description :
+// Description :
// ***************************************************************************
-#ifndef BOOST_ISTREAM_LINE_ITERATOR_HPP_071894GER
-#define BOOST_ISTREAM_LINE_ITERATOR_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_ISTREAM_LINE_ITERATOR_HPP
+#define BOOST_TEST_UTILS_ISTREAM_LINE_ITERATOR_HPP
// Boost
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
@@ -58,7 +58,7 @@ public:
this->init();
}
explicit basic_istream_line_iterator( istream_type& input )
- : m_input_stream( &input )
+ : m_input_stream( &input )
, m_delimeter( input.widen( '\n' ) )
{
this->init();
@@ -89,5 +89,5 @@ typedef basic_istream_line_iterator<wchar_t> wistream_line_iterator;
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_ISTREAM_LINE_ITERATOR_HPP_071894GER
+#endif // BOOST_TEST_UTILS_ISTREAM_LINE_ITERATOR_HPP
diff --git a/boost/test/utils/iterator/token_iterator.hpp b/boost/test/utils/iterator/token_iterator.hpp
index 001507847d..c41f071739 100644
--- a/boost/test/utils/iterator/token_iterator.hpp
+++ b/boost/test/utils/iterator/token_iterator.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2004-2008.
+// (C) Copyright Gennadiy Rozental 2004-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : token iterator for string and range tokenization
// ***************************************************************************
-#ifndef BOOST_TOKEN_ITERATOR_HPP_071894GER
-#define BOOST_TOKEN_ITERATOR_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_TOKEN_ITERATOR_HPP
+#define BOOST_TEST_UTILS_TOKEN_ITERATOR_HPP
// Boost
#include <boost/config.hpp>
@@ -47,7 +47,7 @@ namespace unit_test {
// ************** ti_delimeter_type ************** //
// ************************************************************************** //
-enum ti_delimeter_type {
+enum ti_delimeter_type {
dt_char, // character is delimeter if it among explicit list of some characters
dt_ispunct, // character is delimeter if it satisfies ispunct functor
dt_isspace, // character is delimeter if it satisfies isspace functor
@@ -93,7 +93,7 @@ public:
void set_delimeters( Src d )
{
nfp::optionally_assign( m_delimeters, d );
-
+
if( !m_delimeters.is_empty() )
m_type = dt_char;
}
@@ -135,7 +135,7 @@ struct token_assigner {
template<typename Iterator, typename C, typename T>
static void assign( Iterator b, Iterator e, std::basic_string<C,T>& t )
{ for( ; b != e; ++b ) t += *b; }
-
+
template<typename Iterator, typename C>
static void assign( Iterator b, Iterator e, basic_cstring<C>& t ) { t.assign( b, e ); }
#else
@@ -151,7 +151,7 @@ struct token_assigner {
template<>
struct token_assigner<single_pass_traversal_tag> {
template<typename Iterator, typename Token>
- static void assign( Iterator b, Iterator e, Token& t ) {}
+ static void assign( Iterator /*b*/, Iterator /*e*/, Token& /*t*/ ) {}
template<typename Iterator, typename Token>
static void append_move( Iterator& b, Token& t ) { t += *b; ++b; }
@@ -213,7 +213,7 @@ protected:
nfp::optionally_assign( m_tokens_left, m, max_tokens );
}
- template<typename Iter>
+ template<typename Iter>
bool get( Iter& begin, Iter end )
{
typedef ut_detail::token_assigner<BOOST_DEDUCED_TYPENAME iterator_traversal<Iter>::type> Assigner;
@@ -240,22 +240,22 @@ protected:
Assigner::append_move( begin, this->m_value );
--m_tokens_left;
- }
+ }
else { // m_keep_empty_tokens is true
check_point = begin;
if( begin == end ) {
- if( m_token_produced )
+ if( m_token_produced )
return false;
m_token_produced = true;
}
if( m_is_kept( *begin ) ) {
- if( m_token_produced )
+ if( m_token_produced )
Assigner::append_move( begin, this->m_value );
m_token_produced = !m_token_produced;
- }
+ }
else if( !m_token_produced && m_is_dropped( *begin ) )
m_token_produced = true;
else {
@@ -414,5 +414,5 @@ make_range_token_iterator( Iter begin, Iter end, Modifier const& m )
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_TOKEN_ITERATOR_HPP_071894GER
+#endif // BOOST_TEST_UTILS_TOKEN_ITERATOR_HPP
diff --git a/boost/test/utils/lazy_ostream.hpp b/boost/test/utils/lazy_ostream.hpp
index 87d96602f9..8aef34133b 100644
--- a/boost/test/utils/lazy_ostream.hpp
+++ b/boost/test/utils/lazy_ostream.hpp
@@ -1,19 +1,15 @@
-// (C) Copyright Gennadiy Rozental 2008.
+// (C) Copyright Gennadiy Rozental 2008-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
// Description : contains definition for all test tools in test toolbox
// ***************************************************************************
-#ifndef BOOST_TEST_LAZY_OSTREAM_HPP_070708GER
-#define BOOST_TEST_LAZY_OSTREAM_HPP_070708GER
+#ifndef BOOST_TEST_UTILS_LAZY_OSTREAM_HPP
+#define BOOST_TEST_UTILS_LAZY_OSTREAM_HPP
// Boost.Test
#include <boost/test/detail/config.hpp>
@@ -30,11 +26,12 @@
// ************************************************************************** //
namespace boost {
-
namespace unit_test {
class lazy_ostream {
public:
+ virtual ~lazy_ostream() {}
+
static lazy_ostream& instance() { static lazy_ostream inst; return inst; }
friend std::ostream& operator<<( std::ostream& ostr, lazy_ostream const& o ) { return o( ostr ); }
@@ -45,13 +42,7 @@ public:
// actual printing interface; to be accessed only by this class and children
virtual std::ostream& operator()( std::ostream& ostr ) const { return ostr; }
protected:
- explicit lazy_ostream( bool empty = true ) : m_empty( empty ) {}
-
- // protected destructor to make sure right one is called
-#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
-public:
-#endif
- BOOST_TEST_PROTECTED_VIRTUAL ~lazy_ostream() {}
+ explicit lazy_ostream( bool p_empty = true ) : m_empty( p_empty ) {}
private:
// Data members
@@ -60,32 +51,43 @@ private:
//____________________________________________________________________________//
-template<typename T>
+template<typename PrevType, typename T, typename StorageT=T const&>
class lazy_ostream_impl : public lazy_ostream {
public:
- lazy_ostream_impl( lazy_ostream const& prev, T value )
+ lazy_ostream_impl( PrevType const& prev, T const& value )
: lazy_ostream( false )
, m_prev( prev )
, m_value( value )
- {}
-private:
+ {
+ }
+
virtual std::ostream& operator()( std::ostream& ostr ) const
{
return m_prev(ostr) << m_value;
}
-
+private:
// Data members
- lazy_ostream const& m_prev;
- T m_value;
+ PrevType const& m_prev;
+ StorageT m_value;
};
//____________________________________________________________________________//
template<typename T>
-inline lazy_ostream_impl<T const&>
+inline lazy_ostream_impl<lazy_ostream,T>
operator<<( lazy_ostream const& prev, T const& v )
{
- return lazy_ostream_impl<T const&>( prev, v );
+ return lazy_ostream_impl<lazy_ostream,T>( prev, v );
+}
+
+//____________________________________________________________________________//
+
+template<typename PrevPrevType, typename TPrev, typename T>
+inline lazy_ostream_impl<lazy_ostream_impl<PrevPrevType,TPrev>,T>
+operator<<( lazy_ostream_impl<PrevPrevType,TPrev> const& prev, T const& v )
+{
+ typedef lazy_ostream_impl<PrevPrevType,TPrev> PrevType;
+ return lazy_ostream_impl<PrevType,T>( prev, v );
}
//____________________________________________________________________________//
@@ -93,22 +95,36 @@ operator<<( lazy_ostream const& prev, T const& v )
#if BOOST_TEST_USE_STD_LOCALE
template<typename R,typename S>
-inline lazy_ostream_impl<R& (BOOST_TEST_CALL_DECL *)(S&)>
+inline lazy_ostream_impl<lazy_ostream,R& (BOOST_TEST_CALL_DECL *)(S&),R& (BOOST_TEST_CALL_DECL *)(S&)>
operator<<( lazy_ostream const& prev, R& (BOOST_TEST_CALL_DECL *man)(S&) )
{
- return lazy_ostream_impl<R& (BOOST_TEST_CALL_DECL *)(S&)>( prev, man );
+ typedef R& (BOOST_TEST_CALL_DECL * ManipType)(S&);
+
+ return lazy_ostream_impl<lazy_ostream,ManipType,ManipType>( prev, man );
+}
+
+//____________________________________________________________________________//
+
+template<typename PrevPrevType, typename TPrev,typename R,typename S>
+inline lazy_ostream_impl<lazy_ostream_impl<PrevPrevType,TPrev>,R& (BOOST_TEST_CALL_DECL *)(S&),R& (BOOST_TEST_CALL_DECL *)(S&)>
+operator<<( lazy_ostream_impl<PrevPrevType,TPrev> const& prev, R& (BOOST_TEST_CALL_DECL *man)(S&) )
+{
+ typedef R& (BOOST_TEST_CALL_DECL * ManipType)(S&);
+
+ return lazy_ostream_impl<lazy_ostream_impl<PrevPrevType,TPrev>,ManipType,ManipType>( prev, man );
}
//____________________________________________________________________________//
#endif
-} // namespace unit_test
+#define BOOST_TEST_LAZY_MSG( M ) (::boost::unit_test::lazy_ostream::instance() << M)
+} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_TEST_LAZY_OSTREAM_HPP_070708GER
+#endif // BOOST_TEST_UTILS_LAZY_OSTREAM_HPP
diff --git a/boost/test/utils/named_params.hpp b/boost/test/utils/named_params.hpp
index 0a6277ce12..0e66dc39c5 100644
--- a/boost/test/utils/named_params.hpp
+++ b/boost/test/utils/named_params.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,29 +12,32 @@
// Description : facilities for named function parameters support
// ***************************************************************************
-#ifndef BOOST_TEST_NAMED_PARAM_022505GER
-#define BOOST_TEST_NAMED_PARAM_022505GER
+#ifndef BOOST_TEST_UTILS_NAMED_PARAM
+#define BOOST_TEST_UTILS_NAMED_PARAM
// Boost
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
+#include <boost/mpl/bool.hpp>
// Boost.Test
#include <boost/test/utils/rtti.hpp>
#include <boost/test/utils/assign_op.hpp>
#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+
+#include <boost/test/detail/throw_exception.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
-
namespace nfp { // named function parameters
// ************************************************************************** //
-// ************** forward declarations ************** //
+// ************** forward declarations ************** //
// ************************************************************************** //
template<typename T, typename unique_id,typename RefType> struct named_parameter;
@@ -52,16 +55,17 @@ struct access_to_invalid_parameter {};
//____________________________________________________________________________//
-inline void
-report_access_to_invalid_parameter()
+inline void
+report_access_to_invalid_parameter(bool v)
{
- throw access_to_invalid_parameter();
+ if(v)
+ BOOST_TEST_IMPL_THROW( access_to_invalid_parameter() );
}
//____________________________________________________________________________//
// ************************************************************************** //
-// ************** nil ************** //
+// ************** nil ************** //
// ************************************************************************** //
struct nil {
@@ -71,35 +75,35 @@ struct nil {
#else
operator T const&() const
#endif
- { report_access_to_invalid_parameter(); static T* v = 0; return *v; }
+ { report_access_to_invalid_parameter(true); static T* v = 0; return *v; }
template<typename T>
T any_cast() const
- { report_access_to_invalid_parameter(); static typename remove_reference<T>::type* v = 0; return *v; }
+ { report_access_to_invalid_parameter(true); static typename remove_reference<T>::type* v = 0; return *v; }
template<typename Arg1>
nil operator()( Arg1 const& )
- { report_access_to_invalid_parameter(); return nil(); }
+ { report_access_to_invalid_parameter(true); return nil(); }
template<typename Arg1,typename Arg2>
nil operator()( Arg1 const&, Arg2 const& )
- { report_access_to_invalid_parameter(); return nil(); }
+ { report_access_to_invalid_parameter(true); return nil(); }
template<typename Arg1,typename Arg2,typename Arg3>
nil operator()( Arg1 const&, Arg2 const&, Arg3 const& )
- { report_access_to_invalid_parameter(); return nil(); }
+ { report_access_to_invalid_parameter(true); return nil(); }
// Visitation support
template<typename Visitor>
- void apply_to( Visitor& V ) const {}
+ void apply_to( Visitor& /*v*/ ) const {}
static nil& inst() { static nil s_inst; return s_inst; }
private:
nil() {}
};
-
+
// ************************************************************************** //
-// ************** named_parameter_base ************** //
+// ************** named_parameter_base ************** //
// ************************************************************************** //
template<typename Derived>
@@ -112,11 +116,11 @@ struct named_parameter_base {
//____________________________________________________________________________//
// ************************************************************************** //
-// ************** named_parameter_combine ************** //
+// ************** named_parameter_combine ************** //
// ************************************************************************** //
template<typename NP, typename Rest = nil>
-struct named_parameter_combine
+struct named_parameter_combine
: Rest
, named_parameter_base<named_parameter_combine<NP,Rest> > {
typedef typename NP::ref_type res_type;
@@ -164,10 +168,10 @@ private:
} // namespace nfp_detail
// ************************************************************************** //
-// ************** named_parameter ************** //
+// ************** named_parameter ************** //
// ************************************************************************** //
-template<typename T, typename unique_id,typename ReferenceType=T&>
+template<typename T, typename unique_id, typename ReferenceType=T&>
struct named_parameter
: nfp_detail::named_parameter_base<named_parameter<T, unique_id,ReferenceType> >
{
@@ -177,7 +181,7 @@ struct named_parameter
typedef unique_id id;
// Constructor
- explicit named_parameter( ref_type v )
+ explicit named_parameter( ref_type v )
: m_value( v )
, m_erased( false )
{}
@@ -216,7 +220,7 @@ private:
//____________________________________________________________________________//
// ************************************************************************** //
-// ************** no_params ************** //
+// ************** no_params ************** //
// ************************************************************************** //
namespace nfp_detail {
@@ -230,7 +234,7 @@ nfp_detail::no_params_type no_params( '\0' );
//____________________________________________________________________________//
// ************************************************************************** //
-// ************** keyword ************** //
+// ************** keyword ************** //
// ************************************************************************** //
template<typename unique_id, bool required = false>
@@ -252,7 +256,7 @@ struct keyword {
//____________________________________________________________________________//
// ************************************************************************** //
-// ************** typed_keyword ************** //
+// ************** typed_keyword ************** //
// ************************************************************************** //
template<typename T, typename unique_id, bool required = false>
@@ -281,14 +285,14 @@ struct typed_keyword<bool,unique_id,false>
//____________________________________________________________________________//
// ************************************************************************** //
-// ************** optionally_assign ************** //
+// ************** optionally_assign ************** //
// ************************************************************************** //
template<typename T>
inline void
optionally_assign( T&, nfp_detail::nil )
{
- nfp_detail::report_access_to_invalid_parameter();
+ nfp_detail::report_access_to_invalid_parameter(true);
}
//____________________________________________________________________________//
@@ -319,11 +323,48 @@ optionally_assign( T& target, Params const& p, Keyword k )
//____________________________________________________________________________//
-} // namespace nfp
+// ************************************************************************** //
+// ************** is_named_params ************** //
+// ************************************************************************** //
+
+template<typename T>
+struct is_named_params : public boost::mpl::false_ {};
+template<typename T, typename unique_id, typename ReferenceType>
+struct is_named_params<named_parameter<T,unique_id,ReferenceType> > : public boost::mpl::true_ {};
+
+template<typename NP, typename Rest>
+struct is_named_params<nfp_detail::named_parameter_combine<NP,Rest> > : public boost::mpl::true_ {};
+
+// ************************************************************************** //
+// ************** param_type ************** //
+// ************************************************************************** //
+
+template<typename Params,typename KeywordType,typename DefaultType=void>
+struct param_type {
+ typedef DefaultType type;
+};
+
+template<typename NP,typename Rest,typename Keyword,typename DefaultType>
+struct param_type<nfp_detail::named_parameter_combine<NP,Rest>,Keyword,DefaultType> : param_type<Rest,Keyword,DefaultType> {
+};
+
+template<typename T, typename unique_id, typename ReferenceType,bool required,typename DefaultType>
+struct param_type<named_parameter<T,unique_id,ReferenceType>,keyword<unique_id,required>,DefaultType> {
+ typedef typename boost::remove_cv<T>::type type;
+};
+
+template<typename T, typename unique_id, typename ReferenceType,typename Rest,bool required,typename DefaultType>
+struct param_type<nfp_detail::named_parameter_combine<named_parameter<T,unique_id,ReferenceType>,Rest>,
+ keyword<unique_id,required>,
+ DefaultType> {
+ typedef typename boost::remove_cv<T>::type type;
+};
+
+} // namespace nfp
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_TEST_NAMED_PARAM_022505GER
+#endif // BOOST_TEST_UTILS_NAMED_PARAM
diff --git a/boost/test/utils/nullstream.hpp b/boost/test/utils/nullstream.hpp
index deca6ed15f..b4cedd0842 100644
--- a/boost/test/utils/nullstream.hpp
+++ b/boost/test/utils/nullstream.hpp
@@ -1,7 +1,7 @@
-// (C) Copyright Gennadiy Rozental 2002-2008.
-// (C) Copyright Daryle Walker 2000-2001.
+// (C) Copyright Gennadiy Rozental 2002-2014.
+// (C) Copyright Daryle Walker 2000-2001.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -13,13 +13,15 @@
// Description : simulate /dev/null stream
// ***************************************************************************
-#ifndef BOOST_NULLSTREAM_HPP_071894GER
-#define BOOST_NULLSTREAM_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_NULLSTREAM_HPP
+#define BOOST_TEST_UTILS_NULLSTREAM_HPP
+// STL
#include <ostream> // for std::basic_ostream
#include <streambuf> // for std::basic_streambuf
#include <string> // for std::char_traits
+// Boost
#include <boost/utility/base_from_member.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
@@ -86,6 +88,7 @@ public:
#ifdef BOOST_MSVC
# pragma warning(default: 4355)
+# pragma warning(pop)
#endif
typedef basic_onullstream<char> onullstream;
@@ -97,4 +100,4 @@ typedef basic_onullstream<wchar_t> wonullstream;
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_NULLSTREAM_HPP_071894GER
+#endif // BOOST_TEST_UTILS_NULLSTREAM_HPP
diff --git a/boost/test/utils/rtti.hpp b/boost/test/utils/rtti.hpp
index f795a2cbe4..42f2bc648b 100644
--- a/boost/test/utils/rtti.hpp
+++ b/boost/test/utils/rtti.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,13 +12,13 @@
// Description : simple facilities for accessing type information at runtime
// ***************************************************************************
-#ifndef BOOST_TEST_RTTI_HPP_062604GER
-#define BOOST_TEST_RTTI_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RTTI_HPP
+#define BOOST_TEST_UTILS_RTTI_HPP
+// C Runtime
#include <cstddef>
namespace boost {
-
namespace rtti {
// ************************************************************************** //
@@ -43,7 +43,7 @@ private:
//____________________________________________________________________________//
-template<typename T>
+template<typename T>
inline id_t
type_id()
{
@@ -58,7 +58,6 @@ type_id()
//____________________________________________________________________________//
} // namespace rtti
-
} // namespace boost
-#endif // BOOST_RT_RTTI_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RTTI_HPP
diff --git a/boost/test/utils/runtime/argument.hpp b/boost/test/utils/runtime/argument.hpp
index d0f420aab7..b5133e23c3 100644
--- a/boost/test/utils/runtime/argument.hpp
+++ b/boost/test/utils/runtime/argument.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : model of actual argument (both typed and abstract interface)
// ***************************************************************************
-#ifndef BOOST_RT_ARGUMENT_HPP_062604GER
-#define BOOST_RT_ARGUMENT_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP
+#define BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -29,7 +29,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
// ************************************************************************** //
// ************** runtime::argument ************** //
@@ -105,8 +105,8 @@ arg_value( argument& arg_ )
//____________________________________________________________________________//
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_ARGUMENT_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP
diff --git a/boost/test/utils/runtime/cla/argument_factory.hpp b/boost/test/utils/runtime/cla/argument_factory.hpp
index 19ccc08c0f..6683540612 100644
--- a/boost/test/utils/runtime/cla/argument_factory.hpp
+++ b/boost/test/utils/runtime/cla/argument_factory.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : generic typed_argument_factory implementation
// ***************************************************************************
-#ifndef BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER
-#define BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_ARGUMENT_FACTORY_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_ARGUMENT_FACTORY_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -33,15 +33,13 @@
#include <boost/test/utils/runtime/cla/iface/argument_factory.hpp>
-// Boost.Test
-#include <boost/test/utils/callback.hpp>
-
// Boost
#include <boost/optional.hpp>
+#include <boost/function/function2.hpp>
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -72,7 +70,7 @@ struct typed_argument_factory : public argument_factory {
typed_argument_factory()
: m_value_interpreter( rt_cla_detail::default_value_interpreter() )
{}
- BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~typed_argument_factory() {}
+ BOOST_TEST_UTILS_RUNTIME_PARAM_UNNEEDED_VIRTUAL ~typed_argument_factory() {}
// properties modification
template<typename Modifier>
@@ -82,24 +80,24 @@ struct typed_argument_factory : public argument_factory {
optionally_assign( m_value_interpreter, m, interpreter );
if( m.has( default_value ) ) {
- BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_generator,
- BOOST_RT_PARAM_LITERAL( "multiple value generators for parameter" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( !m_value_generator,
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "multiple value generators for parameter" ) );
T const& dv_ref = m[default_value];
m_value_generator = rt_cla_detail::const_generator<T>( dv_ref );
}
if( m.has( default_refer_to ) ) {
- BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_generator,
- BOOST_RT_PARAM_LITERAL( "multiple value generators for parameter" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( !m_value_generator,
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "multiple value generators for parameter" ) );
cstring ref_id = m[default_refer_to];
m_value_generator = rt_cla_detail::ref_generator<T>( ref_id );
}
if( m.has( assign_to ) ) {
- BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_handler,
- BOOST_RT_PARAM_LITERAL( "multiple value handlers for parameter" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( !m_value_handler,
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "multiple value handlers for parameter" ) );
m_value_handler = rt_cla_detail::assigner<T>( m[assign_to] );
}
@@ -112,9 +110,9 @@ struct typed_argument_factory : public argument_factory {
// !! private?
// Data members
- unit_test::callback2<parameter const&,T&> m_value_handler;
- unit_test::callback2<parser const&,boost::optional<T>&> m_value_generator;
- unit_test::callback2<argv_traverser&,boost::optional<T>&> m_value_interpreter;
+ boost::function<void (parameter const&,T&)> m_value_handler;
+ boost::function<void (parser const&,boost::optional<T>&)> m_value_generator;
+ boost::function<void (argv_traverser&,boost::optional<T>&)> m_value_interpreter;
};
//____________________________________________________________________________//
@@ -125,23 +123,23 @@ typed_argument_factory<T>::produce_using( parameter& p, argv_traverser& tr )
{
boost::optional<T> value;
- try {
+ BOOST_TEST_IMPL_TRY {
m_value_interpreter( tr, value );
}
- catch( ... ) { // !! should we do that?
- BOOST_RT_PARAM_TRACE( "Fail to parse argument value" );
+ BOOST_TEST_IMPL_CATCHALL() { // !! should we do that?
+ BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( "Fail to parse argument value" );
if( !p.p_optional_value )
- throw;
+ BOOST_TEST_IMPL_RETHROW;
}
argument_ptr actual_arg = p.actual_argument();
- BOOST_RT_CLA_VALIDATE_INPUT( !!value || p.p_optional_value, tr,
- BOOST_RT_PARAM_LITERAL( "Argument value missing for parameter " ) << p.id_2_report() );
+ BOOST_TEST_UTILS_RUNTIME_CLA_VALIDATE_INPUT( !!value || p.p_optional_value, tr,
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "Argument value missing for parameter " ) << p.id_2_report() );
- BOOST_RT_CLA_VALIDATE_INPUT( !actual_arg || p.p_multiplicable, tr,
- BOOST_RT_PARAM_LITERAL( "Unexpected repetition of the parameter " ) << p.id_2_report() );
+ BOOST_TEST_UTILS_RUNTIME_CLA_VALIDATE_INPUT( !actual_arg || p.p_multiplicable, tr,
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "Unexpected repetition of the parameter " ) << p.id_2_report() );
if( !!value && !!m_value_handler )
m_value_handler( p, *value );
@@ -154,7 +152,7 @@ typed_argument_factory<T>::produce_using( parameter& p, argv_traverser& tr )
typedef std::list<boost::optional<T> > optional_list;
if( !actual_arg )
- actual_arg.reset( p.p_optional_value
+ actual_arg.reset( p.p_optional_value
? static_cast<argument*>(new typed_argument<optional_list>( p ))
: static_cast<argument*>(new typed_argument<std::list<T> >( p )) );
@@ -165,7 +163,7 @@ typed_argument_factory<T>::produce_using( parameter& p, argv_traverser& tr )
}
else {
std::list<T>& values = arg_value<std::list<T> >( *actual_arg );
-
+
values.push_back( *value );
}
}
@@ -176,7 +174,7 @@ typed_argument_factory<T>::produce_using( parameter& p, argv_traverser& tr )
//____________________________________________________________________________//
template<typename T>
-inline argument_ptr
+inline argument_ptr
typed_argument_factory<T>::produce_using( parameter& p, parser const& pa )
{
argument_ptr actual_arg;
@@ -211,8 +209,8 @@ typed_argument_factory<T>::argument_usage_info( format_stream& fs )
} // namespace boost
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace cla
-#endif // BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_ARGUMENT_FACTORY_HPP
diff --git a/boost/test/utils/runtime/cla/argv_traverser.cpp b/boost/test/utils/runtime/cla/argv_traverser.cpp
index a7a44f7fd9..9716b8fb9c 100644
--- a/boost/test/utils/runtime/cla/argv_traverser.cpp
+++ b/boost/test/utils/runtime/cla/argv_traverser.cpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,5 +12,5 @@
// Description : offline implementation for argc/argv traverser
// ***************************************************************************
-#define BOOST_RT_PARAM_INLINE
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
#include <boost/test/utils/runtime/cla/argv_traverser.ipp>
diff --git a/boost/test/utils/runtime/cla/argv_traverser.hpp b/boost/test/utils/runtime/cla/argv_traverser.hpp
index 58cf2fe5f7..6f6e03dfc8 100644
--- a/boost/test/utils/runtime/cla/argv_traverser.hpp
+++ b/boost/test/utils/runtime/cla/argv_traverser.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : defines facility to hide input traversing details
// ***************************************************************************
-#ifndef BOOST_RT_CLA_ARGV_TRAVERSER_HPP_062604GER
-#define BOOST_RT_CLA_ARGV_TRAVERSER_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -27,7 +27,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -84,15 +84,17 @@ private:
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#ifndef BOOST_RT_PARAM_OFFLINE
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_OFFLINE
-# define BOOST_RT_PARAM_INLINE inline
-# include <boost/test/utils/runtime/cla/argv_traverser.ipp>
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
+# define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE inline
+#endif
+# include <boost/test/utils/runtime/cla/argv_traverser.ipp>
#endif
-#endif // BOOST_RT_CLA_ARGV_TRAVERSER_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_HPP
diff --git a/boost/test/utils/runtime/cla/argv_traverser.ipp b/boost/test/utils/runtime/cla/argv_traverser.ipp
index 2b5e3818b3..d1ae93be82 100644
--- a/boost/test/utils/runtime/cla/argv_traverser.ipp
+++ b/boost/test/utils/runtime/cla/argv_traverser.ipp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : implements facility to hide input traversing details
// ***************************************************************************
-#ifndef BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER
-#define BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_IPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_IPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/trace.hpp>
@@ -30,7 +30,7 @@ namespace std { using ::memcpy; }
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -38,21 +38,23 @@ namespace cla {
// ************** runtime::cla::argv_traverser ************** //
// ************************************************************************** //
-BOOST_RT_PARAM_INLINE
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
argv_traverser::argv_traverser()
-: p_ignore_mismatch( false ), p_separator( BOOST_RT_PARAM_LITERAL( ' ' ) )
+: p_ignore_mismatch( false ), p_separator( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( ' ' ) )
{
}
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
argv_traverser::init( int argc, char_type** argv )
{
+ m_buffer.clear();
+
for( int index = 1; index < argc; ++index ) {
m_buffer += argv[index];
if( index != argc-1 )
- m_buffer += BOOST_RT_PARAM_LITERAL( ' ' );
+ m_buffer += BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( ' ' );
}
m_remainder.reset( new char_type[m_buffer.size()+1] );
@@ -60,14 +62,14 @@ argv_traverser::init( int argc, char_type** argv )
m_work_buffer = m_buffer;
m_commited_end = m_work_buffer.begin();
- BOOST_RT_PARAM_TRACE( "Input buffer: " << m_buffer );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( "Input buffer: " << m_buffer );
next_token();
}
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
argv_traverser::remainder( int& argc, char_type** argv )
{
argc = 1;
@@ -75,15 +77,16 @@ argv_traverser::remainder( int& argc, char_type** argv )
while(pos < m_remainder_size ) {
argv[argc++] = m_remainder.get() + pos;
- pos = std::find( m_remainder.get() + pos, m_remainder.get() + m_remainder_size,
- BOOST_RT_PARAM_LITERAL( ' ' ) ) - m_remainder.get();
- m_remainder[pos++] = BOOST_RT_PARAM_LITERAL( '\0' );
+ pos = static_cast<size_t>(std::find( m_remainder.get() + pos, m_remainder.get() + m_remainder_size,
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( ' ' ) ) -
+ m_remainder.get());
+ m_remainder[pos++] = BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( '\0' );
}
}
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE cstring
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE cstring
argv_traverser::token() const
{
return m_token;
@@ -91,7 +94,7 @@ argv_traverser::token() const
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
argv_traverser::next_token()
{
if( m_work_buffer.is_empty() )
@@ -108,7 +111,7 @@ argv_traverser::next_token()
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE cstring
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE cstring
argv_traverser::input() const
{
return m_work_buffer;
@@ -116,7 +119,7 @@ argv_traverser::input() const
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
argv_traverser::trim( std::size_t size )
{
m_work_buffer.trim_left( size );
@@ -131,7 +134,7 @@ argv_traverser::trim( std::size_t size )
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE bool
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE bool
argv_traverser::match_front( cstring str )
{
return m_work_buffer.size() < str.size() ? false : m_work_buffer.substr( 0, str.size() ) == str;
@@ -139,7 +142,7 @@ argv_traverser::match_front( cstring str )
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE bool
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE bool
argv_traverser::match_front( char_type c )
{
return first_char( m_work_buffer ) == c;
@@ -147,7 +150,7 @@ argv_traverser::match_front( char_type c )
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE bool
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE bool
argv_traverser::eoi() const
{
return m_work_buffer.is_empty();
@@ -155,7 +158,7 @@ argv_traverser::eoi() const
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
argv_traverser::commit()
{
m_commited_end = m_work_buffer.begin();
@@ -163,7 +166,7 @@ argv_traverser::commit()
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
argv_traverser::rollback()
{
m_work_buffer.assign( m_commited_end, m_work_buffer.end() );
@@ -174,15 +177,15 @@ argv_traverser::rollback()
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE std::size_t
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE std::size_t
argv_traverser::input_pos() const
{
- return m_work_buffer.begin() - m_commited_end;
+ return static_cast<std::size_t>(m_work_buffer.begin() - m_commited_end);
}
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE bool
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE bool
argv_traverser::handle_mismatch()
{
if( !p_ignore_mismatch )
@@ -202,8 +205,8 @@ argv_traverser::handle_mismatch()
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_IPP
diff --git a/boost/test/utils/runtime/cla/basic_parameter.hpp b/boost/test/utils/runtime/cla/basic_parameter.hpp
index 8b826bba0a..817b12a301 100644
--- a/boost/test/utils/runtime/cla/basic_parameter.hpp
+++ b/boost/test/utils/runtime/cla/basic_parameter.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : generic custom parameter generator
// ***************************************************************************
-#ifndef BOOST_RT_CLA_BASIC_PARAMETER_HPP_062604GER
-#define BOOST_RT_CLA_BASIC_PARAMETER_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_BASIC_PARAMETER_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_BASIC_PARAMETER_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -28,7 +28,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -40,7 +40,7 @@ template<typename T, typename IdPolicy>
class basic_parameter : private base_from_member<IdPolicy>, public typed_parameter<T> {
public:
// Constructors
- explicit basic_parameter( cstring n )
+ explicit basic_parameter( cstring n )
: base_from_member<IdPolicy>()
, typed_parameter<T>( base_from_member<IdPolicy>::member )
{
@@ -59,7 +59,7 @@ public:
//____________________________________________________________________________//
-#define BOOST_RT_CLA_NAMED_PARAM_GENERATORS( param_type ) \
+#define BOOST_TEST_UTILS_RUNTIME_CLA_NAMED_PARAM_GENERATORS( param_type ) \
template<typename T> \
inline shared_ptr<param_type ## _t<T> > \
param_type( cstring name = cstring() ) \
@@ -78,8 +78,8 @@ param_type( cstring name = cstring() )
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_BASIC_PARAMETER_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_BASIC_PARAMETER_HPP
diff --git a/boost/test/utils/runtime/cla/char_parameter.cpp b/boost/test/utils/runtime/cla/char_parameter.cpp
index 017402e8e7..6e85fe4136 100644
--- a/boost/test/utils/runtime/cla/char_parameter.cpp
+++ b/boost/test/utils/runtime/cla/char_parameter.cpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,5 +12,5 @@
// Description : offline implementation of char parameter
// ***************************************************************************
-#define BOOST_RT_PARAM_INLINE
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
#include <boost/test/utils/runtime/cla/char_parameter.ipp>
diff --git a/boost/test/utils/runtime/cla/char_parameter.hpp b/boost/test/utils/runtime/cla/char_parameter.hpp
index 425c24f3f9..0e2928b1af 100644
--- a/boost/test/utils/runtime/cla/char_parameter.hpp
+++ b/boost/test/utils/runtime/cla/char_parameter.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : defines model of parameter with single char name
// ***************************************************************************
-#ifndef BOOST_RT_CLA_CHAR_PARAMETER_HPP_062604GER
-#define BOOST_RT_CLA_CHAR_PARAMETER_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_CHAR_PARAMETER_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_CHAR_PARAMETER_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -24,7 +24,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -36,7 +36,7 @@ class char_name_policy : public basic_naming_policy {
public:
// Constructor
char_name_policy();
- BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~char_name_policy() {}
+ BOOST_TEST_UTILS_RUNTIME_PARAM_UNNEEDED_VIRTUAL ~char_name_policy() {}
// policy interface
virtual bool conflict_with( identification_policy const& ) const;
@@ -47,7 +47,7 @@ public:
{
basic_naming_policy::accept_modifier( m );
- BOOST_RT_PARAM_VALIDATE_LOGIC( p_name->size() <= 1, "Invalid parameter name " << p_name );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( p_name->size() <= 1, "Invalid parameter name " << p_name );
}
};
@@ -84,15 +84,17 @@ char_parameter( char_type name )
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#ifndef BOOST_RT_PARAM_OFFLINE
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_OFFLINE
-# define BOOST_RT_PARAM_INLINE inline
-# include <boost/test/utils/runtime/cla/char_parameter.ipp>
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
+# define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE inline
+#endif
+# include <boost/test/utils/runtime/cla/char_parameter.ipp>
#endif
-#endif // BOOST_RT_CLA_CHAR_PARAMETER_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_CHAR_PARAMETER_HPP
diff --git a/boost/test/utils/runtime/cla/char_parameter.ipp b/boost/test/utils/runtime/cla/char_parameter.ipp
index db4d0c1ed1..398ce79ac4 100644
--- a/boost/test/utils/runtime/cla/char_parameter.ipp
+++ b/boost/test/utils/runtime/cla/char_parameter.ipp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : implements model of parameter with single char name
// ***************************************************************************
-#ifndef BOOST_RT_CLA_CHAR_PARAMETER_IPP_062904GER
-#define BOOST_RT_CLA_CHAR_PARAMETER_IPP_062904GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_CHAR_PARAMETER_IPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_CHAR_PARAMETER_IPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -22,7 +22,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -30,19 +30,19 @@ namespace cla {
// ************** char_name_policy ************** //
// ************************************************************************** //
-BOOST_RT_PARAM_INLINE
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
char_name_policy::char_name_policy()
: basic_naming_policy( rtti::type_id<char_name_policy>() )
{
- assign_op( p_prefix.value, BOOST_RT_PARAM_CSTRING_LITERAL( "-" ), 0 );
+ assign_op( p_prefix.value, BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "-" ), 0 );
}
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE bool
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE bool
char_name_policy::conflict_with( identification_policy const& id ) const
{
- return id.p_type_id == p_type_id &&
+ return id.p_type_id == p_type_id &&
p_name == static_cast<char_name_policy const&>( id ).p_name;
}
@@ -50,8 +50,8 @@ char_name_policy::conflict_with( identification_policy const& id ) const
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_CHAR_PARAMETER_IPP_062904GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_CHAR_PARAMETER_IPP
diff --git a/boost/test/utils/runtime/cla/detail/argument_value_usage.hpp b/boost/test/utils/runtime/cla/detail/argument_value_usage.hpp
index 0d59595612..a70b6d1fb7 100644
--- a/boost/test/utils/runtime/cla/detail/argument_value_usage.hpp
+++ b/boost/test/utils/runtime/cla/detail/argument_value_usage.hpp
@@ -1,10 +1,9 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied warranty,
-// and with no claim as to its suitability for any purpose.
-
-// See http://www.boost.org for updates, documentation, and revision history.
+// (C) Copyright Gennadiy Rozental 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/test for the library home page.
//
// File : $RCSfile$
//
@@ -13,8 +12,8 @@
// Description : argument usage printing helpers
// ***************************************************************************
-#ifndef BOOST_RT_CLA_ARGUMENT_VALUE_USAGE_HPP_062604GER
-#define BOOST_RT_CLA_ARGUMENT_VALUE_USAGE_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_ARGUMENT_VALUE_USAGE_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_ARGUMENT_VALUE_USAGE_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -32,7 +31,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -47,7 +46,7 @@ template<typename T>
inline void
argument_value_usage( format_stream& fs, long, T* = 0 )
{
- fs << BOOST_RT_PARAM_CSTRING_LITERAL( "<value>" );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "<value>" );
}
//____________________________________________________________________________//
@@ -57,7 +56,7 @@ template<typename T>
inline void
argument_value_usage( format_stream& fs, int, std::list<T>* = 0 )
{
- fs << BOOST_RT_PARAM_CSTRING_LITERAL( "(<value1>, ..., <valueN>)" );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "(<value1>, ..., <valueN>)" );
}
//____________________________________________________________________________//
@@ -66,7 +65,7 @@ argument_value_usage( format_stream& fs, int, std::list<T>* = 0 )
inline void
argument_value_usage( format_stream& fs, int, bool* = 0 )
{
- fs << BOOST_RT_PARAM_CSTRING_LITERAL( "yes|y|no|n" );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "yes|y|no|n" );
}
//____________________________________________________________________________//
@@ -75,8 +74,8 @@ argument_value_usage( format_stream& fs, int, bool* = 0 )
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_ARGUMENT_VALUE_USAGE_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_ARGUMENT_VALUE_USAGE_HPP
diff --git a/boost/test/utils/runtime/cla/dual_name_parameter.cpp b/boost/test/utils/runtime/cla/dual_name_parameter.cpp
index c715de349e..ab034ff04c 100644
--- a/boost/test/utils/runtime/cla/dual_name_parameter.cpp
+++ b/boost/test/utils/runtime/cla/dual_name_parameter.cpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,5 +12,5 @@
// Description : offline implementation of generic parameter with dual naming
// ***************************************************************************
-#define BOOST_RT_PARAM_INLINE
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
#include <boost/test/utils/runtime/cla/dual_name_parameter.ipp>
diff --git a/boost/test/utils/runtime/cla/dual_name_parameter.hpp b/boost/test/utils/runtime/cla/dual_name_parameter.hpp
index 26ac657c86..789b67ad1d 100644
--- a/boost/test/utils/runtime/cla/dual_name_parameter.hpp
+++ b/boost/test/utils/runtime/cla/dual_name_parameter.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : defines model of generic parameter with dual naming
// ***************************************************************************
-#ifndef BOOST_RT_CLA_DUAL_NAME_PARAMETER_HPP_062604GER
-#define BOOST_RT_CLA_DUAL_NAME_PARAMETER_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_DUAL_NAME_PARAMETER_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_DUAL_NAME_PARAMETER_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -23,7 +23,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -76,21 +76,23 @@ public:
//____________________________________________________________________________//
-BOOST_RT_CLA_NAMED_PARAM_GENERATORS( dual_name_parameter )
+BOOST_TEST_UTILS_RUNTIME_CLA_NAMED_PARAM_GENERATORS( dual_name_parameter )
//____________________________________________________________________________//
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#ifndef BOOST_RT_PARAM_OFFLINE
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_OFFLINE
-# define BOOST_RT_PARAM_INLINE inline
-# include <boost/test/utils/runtime/cla/dual_name_parameter.ipp>
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
+# define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE inline
+#endif
+# include <boost/test/utils/runtime/cla/dual_name_parameter.ipp>
#endif
-#endif // BOOST_RT_CLA_DUAL_NAME_PARAMETER_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_DUAL_NAME_PARAMETER_HPP
diff --git a/boost/test/utils/runtime/cla/dual_name_parameter.ipp b/boost/test/utils/runtime/cla/dual_name_parameter.ipp
index 6e3a37f58d..e39d132d62 100644
--- a/boost/test/utils/runtime/cla/dual_name_parameter.ipp
+++ b/boost/test/utils/runtime/cla/dual_name_parameter.ipp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : implements model of generic parameter with dual naming
// ***************************************************************************
-#ifndef BOOST_RT_CLA_DUAL_NAME_PARAMETER_IPP_062904GER
-#define BOOST_RT_CLA_DUAL_NAME_PARAMETER_IPP_062904GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_DUAL_NAME_PARAMETER_IPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_DUAL_NAME_PARAMETER_IPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -23,7 +23,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -31,11 +31,11 @@ namespace cla {
// ************** dual_name_policy ************** //
// ************************************************************************** //
-BOOST_RT_PARAM_INLINE
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
dual_name_policy::dual_name_policy()
{
- m_primary.accept_modifier( prefix = BOOST_RT_PARAM_CSTRING_LITERAL( "--" ) );
- m_secondary.accept_modifier( prefix = BOOST_RT_PARAM_CSTRING_LITERAL( "-" ) );
+ m_primary.accept_modifier( prefix = BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "--" ) );
+ m_secondary.accept_modifier( prefix = BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "-" ) );
}
//____________________________________________________________________________//
@@ -46,8 +46,8 @@ template<typename K>
inline void
split( string_name_policy& snp, char_name_policy& cnp, cstring src, K const& k )
{
- cstring::iterator sep = std::find( src.begin(), src.end(), BOOST_RT_PARAM_LITERAL( '|' ) );
-
+ cstring::iterator sep = std::find( src.begin(), src.end(), BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( '|' ) );
+
if( sep != src.begin() )
snp.accept_modifier( k = cstring( src.begin(), sep ) );
@@ -57,7 +57,7 @@ split( string_name_policy& snp, char_name_policy& cnp, cstring src, K const& k )
} // local namespace
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
dual_name_policy::set_prefix( cstring src )
{
split( m_primary, m_secondary, src, prefix );
@@ -65,7 +65,7 @@ dual_name_policy::set_prefix( cstring src )
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
dual_name_policy::set_name( cstring src )
{
split( m_primary, m_secondary, src, name );
@@ -73,7 +73,7 @@ dual_name_policy::set_name( cstring src )
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
dual_name_policy::set_separator( cstring src )
{
split( m_primary, m_secondary, src, separator );
@@ -83,8 +83,8 @@ dual_name_policy::set_separator( cstring src )
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_DUAL_NAME_PARAMETER_IPP_062904GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_DUAL_NAME_PARAMETER_IPP
diff --git a/boost/test/utils/runtime/cla/fwd.hpp b/boost/test/utils/runtime/cla/fwd.hpp
index b5039339d8..df02974345 100644
--- a/boost/test/utils/runtime/cla/fwd.hpp
+++ b/boost/test/utils/runtime/cla/fwd.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : cla subsystem forward declarations
// ***************************************************************************
-#ifndef BOOST_RT_CLA_FWD_HPP_062604GER
-#define BOOST_RT_CLA_FWD_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_FWD_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_FWD_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -23,7 +23,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -48,8 +48,8 @@ class positional_parameter_base;
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_FWD_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_FWD_HPP
diff --git a/boost/test/utils/runtime/cla/id_policy.cpp b/boost/test/utils/runtime/cla/id_policy.cpp
index c3a5ab8273..b000e26f94 100644
--- a/boost/test/utils/runtime/cla/id_policy.cpp
+++ b/boost/test/utils/runtime/cla/id_policy.cpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,5 +12,5 @@
// Description : some generic identification policies offline implementation
// ***************************************************************************
-#define BOOST_RT_PARAM_INLINE
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
#include <boost/test/utils/runtime/cla/id_policy.ipp>
diff --git a/boost/test/utils/runtime/cla/id_policy.hpp b/boost/test/utils/runtime/cla/id_policy.hpp
index 596805ea21..3308b07c61 100644
--- a/boost/test/utils/runtime/cla/id_policy.hpp
+++ b/boost/test/utils/runtime/cla/id_policy.hpp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-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)
@@ -12,8 +12,8 @@
// Description : some generic identification policies definition
// ***************************************************************************
-#ifndef BOOST_RT_CLA_ID_POLICY_HPP_062604GER
-#define BOOST_RT_CLA_ID_POLICY_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_ID_POLICY_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_ID_POLICY_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -30,7 +30,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -65,7 +65,7 @@ protected:
explicit basic_naming_policy( rtti::id_t dyn_type )
: identification_policy( dyn_type )
{}
- BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~basic_naming_policy() {}
+ BOOST_TEST_UTILS_RUNTIME_PARAM_UNNEEDED_VIRTUAL ~basic_naming_policy() {}
// Naming policy interface
virtual bool match_prefix( argv_traverser& tr ) const;
@@ -102,11 +102,11 @@ public:
}
virtual void usage_info( format_stream& fs ) const
{
- fs << BOOST_RT_PARAM_LITERAL( '{' );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( '{' );
m_primary.usage_info( fs );
- fs << BOOST_RT_PARAM_LITERAL( '|' );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( '|' );
m_secondary.usage_info( fs );
- fs << BOOST_RT_PARAM_LITERAL( '}' );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( '}' );
}
virtual bool matching( parameter const& p, argv_traverser& tr, bool primary ) const
{
@@ -122,7 +122,7 @@ public:
}
protected:
- BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~dual_id_policy() {}
+ BOOST_TEST_UTILS_RUNTIME_PARAM_UNNEEDED_VIRTUAL ~dual_id_policy() {}
// Data members
PrimaryId m_primary;
@@ -131,15 +131,17 @@ protected:
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#ifndef BOOST_RT_PARAM_OFFLINE
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_OFFLINE
-# define BOOST_RT_PARAM_INLINE inline
-# include <boost/test/utils/runtime/cla/id_policy.ipp>
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
+# define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE inline
+#endif
+# include <boost/test/utils/runtime/cla/id_policy.ipp>
#endif
-#endif // BOOST_RT_CLA_ID_POLICY_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_ID_POLICY_HPP
diff --git a/boost/test/utils/runtime/cla/id_policy.ipp b/boost/test/utils/runtime/cla/id_policy.ipp
index 5498b9a8d0..879ccfd1e1 100644
--- a/boost/test/utils/runtime/cla/id_policy.ipp
+++ b/boost/test/utils/runtime/cla/id_policy.ipp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : some generic identification policies implementation
// ***************************************************************************
-#ifndef BOOST_RT_CLA_ID_POLICY_IPP_062904GER
-#define BOOST_RT_CLA_ID_POLICY_IPP_062904GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_ID_POLICY_IPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_ID_POLICY_IPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -23,7 +23,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -31,18 +31,18 @@ namespace cla {
// ************** basic_naming_policy ************** //
// ************************************************************************** //
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
basic_naming_policy::usage_info( format_stream& fs ) const
{
fs << p_prefix << p_name << p_separator;
if( p_separator->empty() )
- fs << BOOST_RT_PARAM_LITERAL( ' ' );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( ' ' );
}
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE bool
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE bool
basic_naming_policy::match_prefix( argv_traverser& tr ) const
{
if( !tr.match_front( p_prefix.get() ) )
@@ -53,8 +53,8 @@ basic_naming_policy::match_prefix( argv_traverser& tr ) const
}
//____________________________________________________________________________//
-
-BOOST_RT_PARAM_INLINE bool
+
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE bool
basic_naming_policy::match_name( argv_traverser& tr ) const
{
if( !tr.match_front( p_name.get() ) )
@@ -65,8 +65,8 @@ basic_naming_policy::match_name( argv_traverser& tr ) const
}
//____________________________________________________________________________//
-
-BOOST_RT_PARAM_INLINE bool
+
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE bool
basic_naming_policy::match_separator( argv_traverser& tr, bool optional_value ) const
{
if( p_separator->empty() ) {
@@ -92,12 +92,12 @@ basic_naming_policy::match_separator( argv_traverser& tr, bool optional_value )
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE bool
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE bool
basic_naming_policy::matching( parameter const& p, argv_traverser& tr, bool ) const
{
if( !match_prefix( tr ) )
return false;
-
+
if( !match_name( tr ) )
return false;
@@ -111,8 +111,8 @@ basic_naming_policy::matching( parameter const& p, argv_traverser& tr, bool ) co
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_ID_POLICY_IPP_062904GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_ID_POLICY_IPP
diff --git a/boost/test/utils/runtime/cla/iface/argument_factory.hpp b/boost/test/utils/runtime/cla/iface/argument_factory.hpp
index 03669e0cc0..cbca713bd3 100644
--- a/boost/test/utils/runtime/cla/iface/argument_factory.hpp
+++ b/boost/test/utils/runtime/cla/iface/argument_factory.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : defines interface for argument_factory
// ***************************************************************************
-#ifndef BOOST_RT_CLA_IFACE_ARGUMENT_FACTORY_HPP_062604GER
-#define BOOST_RT_CLA_IFACE_ARGUMENT_FACTORY_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_IFACE_ARGUMENT_FACTORY_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_IFACE_ARGUMENT_FACTORY_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -23,7 +23,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -44,8 +44,8 @@ protected:
} // namespace boost
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace cla
-#endif // BOOST_RT_CLA_IFACE_ARGUMENT_FACTORY_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_IFACE_ARGUMENT_FACTORY_HPP
diff --git a/boost/test/utils/runtime/cla/iface/id_policy.hpp b/boost/test/utils/runtime/cla/iface/id_policy.hpp
index 1e2d684c25..5fa13e6bc7 100644
--- a/boost/test/utils/runtime/cla/iface/id_policy.hpp
+++ b/boost/test/utils/runtime/cla/iface/id_policy.hpp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-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)
@@ -12,8 +12,8 @@
// Description : defines interface for identification_policy
// ***************************************************************************
-#ifndef BOOST_RT_CLA_IFACE_ID_POLICY_HPP_062604GER
-#define BOOST_RT_CLA_IFACE_ID_POLICY_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_IFACE_ID_POLICY_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_IFACE_ID_POLICY_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -26,7 +26,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -66,8 +66,8 @@ protected:
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_IFACE_ID_POLICY_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_IFACE_ID_POLICY_HPP
diff --git a/boost/test/utils/runtime/cla/modifier.hpp b/boost/test/utils/runtime/cla/modifier.hpp
index 08924e2f94..4b55536b73 100644
--- a/boost/test/utils/runtime/cla/modifier.hpp
+++ b/boost/test/utils/runtime/cla/modifier.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : parameter modifiers
// ***************************************************************************
-#ifndef BOOST_RT_CLA_MODIFIER_HPP_062604GER
-#define BOOST_RT_CLA_MODIFIER_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_MODIFIER_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_MODIFIER_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -23,7 +23,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -62,8 +62,8 @@ nfp::keyword<struct assign_to_t> assign_to;
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_MODIFIER_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_MODIFIER_HPP
diff --git a/boost/test/utils/runtime/cla/named_parameter.cpp b/boost/test/utils/runtime/cla/named_parameter.cpp
index 1b91059fd0..7e94722dc9 100644
--- a/boost/test/utils/runtime/cla/named_parameter.cpp
+++ b/boost/test/utils/runtime/cla/named_parameter.cpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,5 +12,5 @@
// Description : offline implementation of named parameter
// ***************************************************************************
-#define BOOST_RT_PARAM_INLINE
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
#include <boost/test/utils/runtime/cla/named_parameter.ipp>
diff --git a/boost/test/utils/runtime/cla/named_parameter.hpp b/boost/test/utils/runtime/cla/named_parameter.hpp
index 9f0ac1dae0..be3f9c570b 100644
--- a/boost/test/utils/runtime/cla/named_parameter.hpp
+++ b/boost/test/utils/runtime/cla/named_parameter.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : defines model of named parameter
// ***************************************************************************
-#ifndef BOOST_RT_CLA_NAMED_PARAMETER_HPP_062604GER
-#define BOOST_RT_CLA_NAMED_PARAMETER_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_NAMED_PARAMETER_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_NAMED_PARAMETER_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -23,7 +23,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -35,7 +35,7 @@ class string_name_policy : public basic_naming_policy {
public:
// Constructor
string_name_policy();
- BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~string_name_policy() {}
+ BOOST_TEST_UTILS_RUNTIME_PARAM_UNNEEDED_VIRTUAL ~string_name_policy() {}
// policy interface
virtual bool responds_to( cstring name ) const;
@@ -73,21 +73,23 @@ public:
//____________________________________________________________________________//
-BOOST_RT_CLA_NAMED_PARAM_GENERATORS( named_parameter )
+BOOST_TEST_UTILS_RUNTIME_CLA_NAMED_PARAM_GENERATORS( named_parameter )
//____________________________________________________________________________//
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#ifndef BOOST_RT_PARAM_OFFLINE
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_OFFLINE
-# define BOOST_RT_PARAM_INLINE inline
-# include <boost/test/utils/runtime/cla/named_parameter.ipp>
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
+# define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE inline
+#endif
+# include <boost/test/utils/runtime/cla/named_parameter.ipp>
#endif
-#endif // BOOST_RT_CLA_NAMED_PARAMETER_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_NAMED_PARAMETER_HPP
diff --git a/boost/test/utils/runtime/cla/named_parameter.ipp b/boost/test/utils/runtime/cla/named_parameter.ipp
index e04348f53b..e59ebdf89c 100644
--- a/boost/test/utils/runtime/cla/named_parameter.ipp
+++ b/boost/test/utils/runtime/cla/named_parameter.ipp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : implements model of named parameter
// ***************************************************************************
-#ifndef BOOST_RT_CLA_NAMED_PARAMETER_IPP_062904GER
-#define BOOST_RT_CLA_NAMED_PARAMETER_IPP_062904GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_NAMED_PARAMETER_IPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_NAMED_PARAMETER_IPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -26,7 +26,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -34,17 +34,17 @@ namespace cla {
// ************** string_name_policy ************** //
// ************************************************************************** //
-BOOST_RT_PARAM_INLINE
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
string_name_policy::string_name_policy()
: basic_naming_policy( rtti::type_id<string_name_policy>() )
, m_guess_name( false )
{
- assign_op( p_prefix.value, BOOST_RT_PARAM_CSTRING_LITERAL( "-" ), 0 );
+ assign_op( p_prefix.value, BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "-" ), 0 );
}
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE bool
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE bool
string_name_policy::responds_to( cstring name ) const
{
std::pair<cstring::iterator,dstring::const_iterator> mm_pos;
@@ -61,7 +61,7 @@ string_name_policy::responds_to( cstring name ) const
# pragma warning(disable:4244)
#endif
-BOOST_RT_PARAM_INLINE bool
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE bool
string_name_policy::conflict_with( identification_policy const& id ) const
{
if( id.p_type_id == p_type_id ) {
@@ -80,16 +80,16 @@ string_name_policy::conflict_with( identification_policy const& id ) const
((m_guess_name && (mm_pos.second == snp.p_name->end()) ) || // that match other guy and I am guessing
(snp.m_guess_name && (mm_pos.first == p_name->end()) )); // or me and the other guy is
}
-
+
if( id.p_type_id == rtti::type_id<char_name_policy>() ) {
char_name_policy const& cnp = static_cast<char_name_policy const&>( id );
- return m_guess_name &&
- (p_prefix == cnp.p_prefix) &&
+ return m_guess_name &&
+ (p_prefix == cnp.p_prefix) &&
unit_test::first_char( cstring( p_name ) ) == unit_test::first_char( cstring( cnp.p_name ) );
}
-
- return false;
+
+ return false;
}
#ifdef BOOST_MSVC
@@ -98,7 +98,7 @@ string_name_policy::conflict_with( identification_policy const& id ) const
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE bool
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE bool
string_name_policy::match_name( argv_traverser& tr ) const
{
if( !m_guess_name )
@@ -107,13 +107,13 @@ string_name_policy::match_name( argv_traverser& tr ) const
cstring in = tr.input();
std::pair<cstring::iterator,dstring::const_iterator> mm_pos;
-
+
mm_pos = unit_test::mismatch( in.begin(), in.end(), p_name->begin(), p_name->end() );
if( mm_pos.first == in.begin() )
return false;
- tr.trim( mm_pos.first - in.begin() );
+ tr.trim( static_cast<std::size_t>(mm_pos.first - in.begin()) );
return true;
}
@@ -122,8 +122,8 @@ string_name_policy::match_name( argv_traverser& tr ) const
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_NAMED_PARAMETER_IPP_062904GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_NAMED_PARAMETER_IPP
diff --git a/boost/test/utils/runtime/cla/parameter.hpp b/boost/test/utils/runtime/cla/parameter.hpp
index 25680db087..9e26d25007 100644
--- a/boost/test/utils/runtime/cla/parameter.hpp
+++ b/boost/test/utils/runtime/cla/parameter.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : defines model of formal parameter
// ***************************************************************************
-#ifndef BOOST_RT_CLA_PARAMETER_HPP_062604GER
-#define BOOST_RT_CLA_PARAMETER_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_PARAMETER_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_PARAMETER_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -32,7 +32,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -40,7 +40,7 @@ namespace cla {
// ************** runtime::cla::parameter ************** //
// ************************************************************************** //
-class parameter : public BOOST_RT_PARAM_NAMESPACE::parameter {
+class parameter : public BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE::parameter {
public:
parameter( identification_policy& ID, argument_factory& F, bool optional_value = false )
: p_optional( false )
@@ -78,9 +78,10 @@ public:
}
// access methods
- bool has_argument() const { return m_actual_argument!=0; }
+ bool has_argument() const { return !!m_actual_argument; }
argument const& actual_argument() const { return *m_actual_argument; }
argument_ptr actual_argument() { return m_actual_argument; }
+ void reset() { m_actual_argument.reset(); }
// identification interface
@@ -88,20 +89,20 @@ public:
bool conflict_with( parameter const& p ) const
{
return (id_2_report() == p.id_2_report() && !id_2_report().is_empty()) ||
- m_id_policy.conflict_with( p.m_id_policy ) ||
+ m_id_policy.conflict_with( p.m_id_policy ) ||
((m_id_policy.p_type_id != p.m_id_policy.p_type_id) && p.m_id_policy.conflict_with( m_id_policy ));
}
cstring id_2_report() const { return m_id_policy.id_2_report(); }
void usage_info( format_stream& fs ) const
- {
+ {
m_id_policy.usage_info( fs );
if( p_optional_value )
- fs << BOOST_RT_PARAM_LITERAL( '[' );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( '[' );
m_arg_factory.argument_usage_info( fs );
if( p_optional_value )
- fs << BOOST_RT_PARAM_LITERAL( ']' );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( ']' );
}
// argument match/produce based on input
@@ -143,8 +144,8 @@ operator-( shared_ptr<Parameter> p, Modifier const& m )
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_PARAMETER_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_PARAMETER_HPP
diff --git a/boost/test/utils/runtime/cla/parser.cpp b/boost/test/utils/runtime/cla/parser.cpp
index 4d1d7afe97..8efc17d3b2 100644
--- a/boost/test/utils/runtime/cla/parser.cpp
+++ b/boost/test/utils/runtime/cla/parser.cpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -9,10 +9,10 @@
//
// Version : $Revision$
//
-// Description : offline implementation for parser
+// Description : offline implementation for parser
// ***************************************************************************
#include <boost/test/utils/runtime/config.hpp>
-#define BOOST_RT_PARAM_INLINE
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
#include <boost/test/utils/runtime/cla/parser.ipp>
diff --git a/boost/test/utils/runtime/cla/parser.hpp b/boost/test/utils/runtime/cla/parser.hpp
index f95d26a095..ffe09e4adc 100644
--- a/boost/test/utils/runtime/cla/parser.hpp
+++ b/boost/test/utils/runtime/cla/parser.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : defines parser - public interface for CLA parsing and accessing
// ***************************************************************************
-#ifndef BOOST_RT_CLA_PARSER_HPP_062604GER
-#define BOOST_RT_CLA_PARSER_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -32,7 +32,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -76,6 +76,7 @@ private:
class parser {
public:
typedef std::list<parameter_ptr>::const_iterator param_iterator;
+ typedef std::list<parameter_ptr>::size_type param_size_type;
// Constructor
explicit parser( cstring program_name = cstring() );
@@ -100,10 +101,12 @@ public:
// parameters access
param_iterator first_param() const;
param_iterator last_param() const;
+ param_size_type num_params() const { return m_parameters.size(); }
+ void reset();
// arguments access
const_argument_ptr operator[]( cstring string_id ) const;
- cstring get( cstring string_id ) const;
+ cstring get( cstring string_id ) const;
template<typename T>
T const& get( cstring string_id ) const
@@ -139,15 +142,17 @@ private:
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#ifndef BOOST_RT_PARAM_OFFLINE
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_OFFLINE
-# define BOOST_RT_PARAM_INLINE inline
-# include <boost/test/utils/runtime/cla/parser.ipp>
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
+# define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE inline
+#endif
+# include <boost/test/utils/runtime/cla/parser.ipp>
#endif
-#endif // BOOST_RT_CLA_PARSER_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP
diff --git a/boost/test/utils/runtime/cla/parser.ipp b/boost/test/utils/runtime/cla/parser.ipp
index 188d303156..b8a4ca4636 100644
--- a/boost/test/utils/runtime/cla/parser.ipp
+++ b/boost/test/utils/runtime/cla/parser.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-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)
@@ -12,8 +12,8 @@
// Description : implements parser - public interface for CLA parsing and accessing
// ***************************************************************************
-#ifndef BOOST_RT_CLA_PARSER_IPP_062904GER
-#define BOOST_RT_CLA_PARSER_IPP_062904GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_IPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_IPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -35,7 +35,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -43,7 +43,7 @@ namespace cla {
// ************** runtime::cla::parser ************** //
// ************************************************************************** //
-BOOST_RT_PARAM_INLINE
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
parser::parser( cstring program_name )
{
assign_op( m_program_name, program_name, 0 );
@@ -51,7 +51,7 @@ parser::parser( cstring program_name )
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE parser::param_iterator
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE parser::param_iterator
parser::first_param() const
{
return m_parameters.begin();
@@ -59,7 +59,7 @@ parser::first_param() const
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE parser::param_iterator
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE parser::param_iterator
parser::last_param() const
{
return m_parameters.end();
@@ -67,25 +67,25 @@ parser::last_param() const
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE argument const&
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE argument const&
parser::valid_argument( cstring string_id ) const
{
const_argument_ptr arg = (*this)[string_id];
- BOOST_RT_PARAM_VALIDATE_LOGIC( !!arg, "Actual argument for parameter " << string_id << " is not present" );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( !!arg, "Actual argument for parameter " << string_id << " is not present" );
return *arg;
}
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE parser&
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE parser&
parser::operator<<( parameter_ptr new_param )
{
BOOST_TEST_FOREACH( parameter_ptr, old_param, m_parameters ) {
- BOOST_RT_PARAM_VALIDATE_LOGIC( !old_param->conflict_with( *new_param ),
- BOOST_RT_PARAM_LITERAL( "Definition of parameter " ) << new_param->id_2_report() <<
- BOOST_RT_PARAM_LITERAL( " conflicts with defintion of parameter " ) << old_param->id_2_report() );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( !old_param->conflict_with( *new_param ),
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "Definition of parameter " ) << new_param->id_2_report() <<
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( " conflicts with defintion of parameter " ) << old_param->id_2_report() );
}
m_parameters.push_back( new_param );
@@ -95,12 +95,12 @@ parser::operator<<( parameter_ptr new_param )
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
parser::parse( int& argc, char_type** argv )
{
if( m_program_name.empty() ) {
m_program_name.assign( argv[0] );
- dstring::size_type pos = m_program_name.find_last_of( BOOST_RT_PARAM_LITERAL( "/\\" ) );
+ dstring::size_type pos = m_program_name.find_last_of( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "/\\" ) );
if( pos != static_cast<dstring::size_type>(cstring::npos) )
m_program_name.erase( 0, pos+1 );
@@ -108,18 +108,18 @@ parser::parse( int& argc, char_type** argv )
m_traverser.init( argc, argv );
- try {
+ BOOST_TEST_IMPL_TRY {
while( !m_traverser.eoi() ) {
parameter_ptr found_param;
- BOOST_RT_PARAM_TRACE( "Total " << m_parameters.size() << " parameters registered" );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( "Total " << m_parameters.size() << " parameters registered" );
BOOST_TEST_FOREACH( parameter_ptr const&, curr_param, m_parameters ) {
- BOOST_RT_PARAM_TRACE( "Try parameter " << curr_param->id_2_report() );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( "Try parameter " << curr_param->id_2_report() );
if( curr_param->matching( m_traverser, !found_param ) ) {
- BOOST_RT_PARAM_TRACE( "Match found" );
- BOOST_RT_CLA_VALIDATE_INPUT( !found_param, (m_traverser.rollback(),m_traverser), "Ambiguous input" );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( "Match found" );
+ BOOST_TEST_UTILS_RUNTIME_CLA_VALIDATE_INPUT( !found_param, (m_traverser.rollback(),m_traverser), "Ambiguous input" );
found_param = curr_param;
}
@@ -128,14 +128,14 @@ parser::parse( int& argc, char_type** argv )
}
if( !found_param ) {
- BOOST_RT_PARAM_TRACE( "No match found" );
- BOOST_RT_CLA_VALIDATE_INPUT( m_traverser.handle_mismatch(), m_traverser,
- BOOST_RT_PARAM_LITERAL( "Unexpected input" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( "No match found" );
+ BOOST_TEST_UTILS_RUNTIME_CLA_VALIDATE_INPUT( m_traverser.handle_mismatch(), m_traverser,
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "Unexpected input" ) );
continue;
}
- BOOST_RT_PARAM_TRACE( "Parse argument value" );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( "Parse argument value" );
found_param->produce_argument( m_traverser );
m_traverser.commit();
@@ -145,31 +145,31 @@ parser::parse( int& argc, char_type** argv )
if( !curr_param->p_optional && !curr_param->actual_argument() ) {
curr_param->produce_argument( *this );
- BOOST_RT_PARAM_VALIDATE_LOGIC( curr_param->actual_argument(),
- BOOST_RT_PARAM_LITERAL( "Required argument for parameter " ) << curr_param->id_2_report()
- << BOOST_RT_PARAM_LITERAL( " is missing" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( curr_param->actual_argument(),
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "Required argument for parameter " ) << curr_param->id_2_report()
+ << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( " is missing" ) );
}
}
}
- catch( bad_lexical_cast const& ) {
- BOOST_RT_PARAM_REPORT_LOGIC_ERROR(
- BOOST_RT_PARAM_LITERAL( "String to value convertion error during input parsing" ) );
- }
+ BOOST_TEST_IMPL_CATCH0( bad_lexical_cast ) {
+ BOOST_TEST_UTILS_RUNTIME_PARAM_REPORT_LOGIC_ERROR(
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "String to value convertion error during input parsing" ) );
+ };
m_traverser.remainder( argc, argv );
}
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE const_argument_ptr
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE const_argument_ptr
parser::operator[]( cstring string_id ) const
{
parameter_ptr found_param;
BOOST_TEST_FOREACH( parameter_ptr const&, curr_param, m_parameters ) {
if( curr_param->responds_to( string_id ) ) {
- BOOST_RT_PARAM_VALIDATE_LOGIC( !found_param,
- BOOST_RT_PARAM_LITERAL( "Ambiguous parameter string id: " ) << string_id );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( !found_param,
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "Ambiguous parameter string id: " ) << string_id );
found_param = curr_param;
}
@@ -180,7 +180,7 @@ parser::operator[]( cstring string_id ) const
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE cstring
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE cstring
parser::get( cstring string_id ) const
{
return get<cstring>( string_id );
@@ -188,46 +188,46 @@ parser::get( cstring string_id ) const
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
parser::usage( out_stream& ostr )
{
if( m_program_name.empty() )
- assign_op( m_program_name, BOOST_RT_PARAM_CSTRING_LITERAL( "<program>" ), 0 );
+ assign_op( m_program_name, BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "<program>" ), 0 );
format_stream fs;
fs << m_program_name;
BOOST_TEST_FOREACH( parameter_ptr const&, curr_param, m_parameters ) {
- fs << BOOST_RT_PARAM_LITERAL( ' ' );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( ' ' );
if( curr_param->p_optional )
- fs << BOOST_RT_PARAM_LITERAL( '[' );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( '[' );
curr_param->usage_info( fs );
if( curr_param->p_optional )
- fs << BOOST_RT_PARAM_LITERAL( ']' );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( ']' );
if( curr_param->p_multiplicable ) {
- fs << BOOST_RT_PARAM_CSTRING_LITERAL( " ... " );
-
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( " ... " );
+
if( curr_param->p_optional )
- fs << BOOST_RT_PARAM_LITERAL( '[' );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( '[' );
curr_param->usage_info( fs );
if( curr_param->p_optional )
- fs << BOOST_RT_PARAM_LITERAL( ']' );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( ']' );
}
}
- ostr << BOOST_RT_PARAM_CSTRING_LITERAL( "Usage:\n" ) << fs.str() << std::endl;
+ ostr << BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "Usage:\n" ) << fs.str() << std::endl;
}
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
parser::help( out_stream& ostr )
{
usage( ostr );
@@ -239,20 +239,29 @@ parser::help( out_stream& ostr )
continue;
if( need_where ) {
- ostr << BOOST_RT_PARAM_CSTRING_LITERAL( "where:\n" );
+ ostr << BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "where:\n" );
need_where = false;
}
- ostr << curr_param->id_2_report() << BOOST_RT_PARAM_CSTRING_LITERAL( " - " ) << curr_param->p_description << std::endl;
+ ostr << curr_param->id_2_report() << BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( " - " ) << curr_param->p_description << std::endl;
}
}
//____________________________________________________________________________//
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
+parser::reset()
+{
+ BOOST_TEST_FOREACH( parameter_ptr const&, param, m_parameters )
+ param->reset();
+}
+
+//____________________________________________________________________________//
+
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_PARSER_IPP_062904GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_IPP
diff --git a/boost/test/utils/runtime/cla/positional_parameter.hpp b/boost/test/utils/runtime/cla/positional_parameter.hpp
index 60da845627..f378743dd5 100644
--- a/boost/test/utils/runtime/cla/positional_parameter.hpp
+++ b/boost/test/utils/runtime/cla/positional_parameter.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : positional parameter model
// ***************************************************************************
-#ifndef BOOST_RT_CLA_POSITIONAL_PARAMETER_HPP_062604GER
-#define BOOST_RT_CLA_POSITIONAL_PARAMETER_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_POSITIONAL_PARAMETER_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_POSITIONAL_PARAMETER_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -22,7 +22,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -35,17 +35,17 @@ public:
trivial_id_policy()
: identification_policy( rtti::type_id<trivial_id_policy>() )
{}
- BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~trivial_id_policy() {}
+ BOOST_TEST_UTILS_RUNTIME_PARAM_UNNEEDED_VIRTUAL ~trivial_id_policy() {}
virtual bool responds_to( cstring name ) const { return m_name == name; }
virtual bool conflict_with( identification_policy const& ) const { return false; }
virtual cstring id_2_report() const { return m_name; }
virtual void usage_info( format_stream& fs ) const
- {
+ {
if( !m_name.empty() )
- fs << BOOST_RT_PARAM_LITERAL( '<' ) << m_name << BOOST_RT_PARAM_LITERAL( '>' );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( '<' ) << m_name << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( '>' );
else
- fs << BOOST_RT_PARAM_CSTRING_LITERAL( "<value>" );
+ fs << BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "<value>" );
}
virtual bool matching( parameter const& p, argv_traverser&, bool primary ) const
@@ -80,12 +80,12 @@ public:
//____________________________________________________________________________//
-BOOST_RT_CLA_NAMED_PARAM_GENERATORS( positional_parameter )
+BOOST_TEST_UTILS_RUNTIME_CLA_NAMED_PARAM_GENERATORS( positional_parameter )
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_POSITIONAL_PARAMETER_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_POSITIONAL_PARAMETER_HPP
diff --git a/boost/test/utils/runtime/cla/typed_parameter.hpp b/boost/test/utils/runtime/cla/typed_parameter.hpp
index 3d4c57b23a..70c5bbc009 100644
--- a/boost/test/utils/runtime/cla/typed_parameter.hpp
+++ b/boost/test/utils/runtime/cla/typed_parameter.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : generic typed parameter model
// ***************************************************************************
-#ifndef BOOST_RT_CLA_TYPED_PARAMETER_HPP_062604GER
-#define BOOST_RT_CLA_TYPED_PARAMETER_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_TYPED_PARAMETER_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_TYPED_PARAMETER_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -29,7 +29,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -40,8 +40,8 @@ namespace cla {
template<typename T>
class typed_parameter : public cla::parameter {
public:
- explicit typed_parameter( identification_policy& ID )
- : cla::parameter( ID, m_arg_factory, rtti::type_id<T>() == rtti::type_id<bool>() )
+ explicit typed_parameter( identification_policy& ID )
+ : cla::parameter( ID, m_arg_factory, rtti::type_id<T>() == rtti::type_id<bool>() )
{}
// parameter properties modification
@@ -52,8 +52,8 @@ public:
m_arg_factory.accept_modifier( m );
- BOOST_RT_PARAM_VALIDATE_LOGIC( !p_optional || !m_arg_factory.m_value_generator,
- BOOST_RT_PARAM_LITERAL( "can't define a value generator for optional parameter " ) << id_2_report() );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( !p_optional || !m_arg_factory.m_value_generator,
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "can't define a value generator for optional parameter " ) << id_2_report() );
}
private:
@@ -63,8 +63,8 @@ private:
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_TYPED_PARAMETER_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_TYPED_PARAMETER_HPP
diff --git a/boost/test/utils/runtime/cla/validation.cpp b/boost/test/utils/runtime/cla/validation.cpp
index f5c1e6669a..7f19a5ca45 100644
--- a/boost/test/utils/runtime/cla/validation.cpp
+++ b/boost/test/utils/runtime/cla/validation.cpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,5 +12,5 @@
// Description : input validation helpers offline implementation
// ***************************************************************************
-#define BOOST_RT_PARAM_INLINE
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
#include <boost/test/utils/runtime/cla/validation.ipp>
diff --git a/boost/test/utils/runtime/cla/validation.hpp b/boost/test/utils/runtime/cla/validation.hpp
index 57a7f2459f..8a3da14c5b 100644
--- a/boost/test/utils/runtime/cla/validation.hpp
+++ b/boost/test/utils/runtime/cla/validation.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : input validation helpers definition
// ***************************************************************************
-#ifndef BOOST_RT_CLA_VALIDATION_HPP_062604GER
-#define BOOST_RT_CLA_VALIDATION_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_VALIDATION_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_VALIDATION_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -22,7 +22,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -34,22 +34,24 @@ void report_input_error( argv_traverser const& tr, format_stream& msg );
//____________________________________________________________________________//
-#define BOOST_RT_CLA_VALIDATE_INPUT( b, tr, msg ) \
- if( b ) ; else ::boost::BOOST_RT_PARAM_NAMESPACE::cla::report_input_error( tr, format_stream().ref() << msg )
+#define BOOST_TEST_UTILS_RUNTIME_CLA_VALIDATE_INPUT( b, tr, msg ) \
+ if( b ) ; else ::boost::BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE::cla::report_input_error( tr, format_stream().ref() << msg )
//____________________________________________________________________________//
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#ifndef BOOST_RT_PARAM_OFFLINE
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_OFFLINE
-# define BOOST_RT_PARAM_INLINE inline
-# include <boost/test/utils/runtime/cla/validation.ipp>
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
+# define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE inline
+#endif
+# include <boost/test/utils/runtime/cla/validation.ipp>
#endif
-#endif // BOOST_RT_CLA_VALIDATION_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_VALIDATION_HPP
diff --git a/boost/test/utils/runtime/cla/validation.ipp b/boost/test/utils/runtime/cla/validation.ipp
index 9728bd6702..9d8cd27b4a 100644
--- a/boost/test/utils/runtime/cla/validation.ipp
+++ b/boost/test/utils/runtime/cla/validation.ipp
@@ -1,35 +1,31 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
//
-// File : $RCSfile$
-//
-// Version : $Revision$
-//
-// Description : input validation helpers implementation
+//! @file
+//! @brief Input validation helpers implementation
// ***************************************************************************
-#ifndef BOOST_RT_CLA_VALIDATION_IPP_070604GER
-#define BOOST_RT_CLA_VALIDATION_IPP_070604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_VALIDATION_IPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_VALIDATION_IPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
#include <boost/test/utils/runtime/cla/argv_traverser.hpp>
#include <boost/test/utils/runtime/cla/validation.hpp>
-#include <boost/test/utils/runtime/validation.hpp> // BOOST_RT_PARAM_NAMESPACE::logic_error
+#include <boost/test/utils/runtime/validation.hpp> // BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE::logic_error
-// Boost
+// Boost.Test
#include <boost/test/utils/basic_cstring/io.hpp>
-
-// STL
+#include <boost/test/detail/throw_exception.hpp>
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -37,29 +33,29 @@ namespace cla {
// ************** runtime::cla::validation ************** //
// ************************************************************************** //
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
report_input_error( argv_traverser const& tr, format_stream& msg )
{
if( tr.eoi() )
- msg << BOOST_RT_PARAM_LITERAL( " at the end of input" );
+ msg << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( " at the end of input" );
else {
- msg << BOOST_RT_PARAM_LITERAL( " in the following position: " );
+ msg << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( " in the following position: " );
if( tr.input().size() > 5 )
- msg << tr.input().substr( 0, 5 ) << BOOST_RT_PARAM_LITERAL( "..." );
+ msg << tr.input().substr( 0, 5 ) << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "..." );
else
msg << tr.input();
}
- throw BOOST_RT_PARAM_NAMESPACE::logic_error( msg.str() );
+ BOOST_TEST_IMPL_THROW( BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE::logic_error( msg.str() ) );
}
//____________________________________________________________________________//
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_VALIDATION_IPP_070604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_VALIDATION_IPP
diff --git a/boost/test/utils/runtime/cla/value_generator.hpp b/boost/test/utils/runtime/cla/value_generator.hpp
index ab15c9b551..0efc25def1 100644
--- a/boost/test/utils/runtime/cla/value_generator.hpp
+++ b/boost/test/utils/runtime/cla/value_generator.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : specific value generators
// ***************************************************************************
-#ifndef BOOST_RT_CLA_VALUE_GENERATOR_HPP_062604GER
-#define BOOST_RT_CLA_VALUE_GENERATOR_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_VALUE_GENERATOR_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_VALUE_GENERATOR_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -23,7 +23,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -74,8 +74,8 @@ private:
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_VALUE_GENERATOR_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_VALUE_GENERATOR_HPP
diff --git a/boost/test/utils/runtime/cla/value_handler.hpp b/boost/test/utils/runtime/cla/value_handler.hpp
index fbf99667aa..38792602ac 100644
--- a/boost/test/utils/runtime/cla/value_handler.hpp
+++ b/boost/test/utils/runtime/cla/value_handler.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : specific value handlers
// ***************************************************************************
-#ifndef BOOST_RT_CLA_VALUE_HANDLER_HPP_062604GER
-#define BOOST_RT_CLA_VALUE_HANDLER_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_VALUE_HANDLER_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CLA_VALUE_HANDLER_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -22,7 +22,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace cla {
@@ -50,8 +50,8 @@ private:
} // namespace cla
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CLA_VALUE_HANDLER_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CLA_VALUE_HANDLER_HPP
diff --git a/boost/test/utils/runtime/config.hpp b/boost/test/utils/runtime/config.hpp
index 771a8ee7af..dfa9ae30de 100644
--- a/boost/test/utils/runtime/config.hpp
+++ b/boost/test/utils/runtime/config.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : Runtime.Param library configuration
// ***************************************************************************
-#ifndef BOOST_RT_CONFIG_HPP_062604GER
-#define BOOST_RT_CONFIG_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CONFIG_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CONFIG_HPP
// Boost
#include <boost/config.hpp>
@@ -34,26 +34,28 @@
#include <string>
#include <cstdlib>
+#ifdef __SUNPRO_CC
+ #include <stdlib.h>
+#endif
+
//____________________________________________________________________________//
-#ifndef BOOST_RT_PARAM_CUSTOM_STRING
-# ifndef BOOST_RT_PARAM_WIDE_STRING
-# define BOOST_RT_PARAM_NAMESPACE runtime
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_CUSTOM_STRING
+# ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_WIDE_STRING
+# define BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE runtime
# else
-# define BOOST_RT_PARAM_NAMESPACE wide_runtime
+# define BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE wide_runtime
# endif
#endif
-#ifdef __SUNPRO_CC
-extern int putenv(char*);
-#endif
+
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
-#ifndef BOOST_RT_PARAM_CUSTOM_STRING
-# ifndef BOOST_RT_PARAM_WIDE_STRING
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_CUSTOM_STRING
+# ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_WIDE_STRING
typedef char char_type;
typedef std::string dstring;
@@ -72,6 +74,10 @@ typedef std::basic_ostream<char_type> out_stream;
#pragma warning(disable:4996) // putenv
#endif
+#if defined(__MINGW32__)
+extern "C" int putenv( const char * );
+#endif
+
#ifndef UNDER_CE
#if defined(__COMO__) && 0
inline void
@@ -97,15 +103,15 @@ putenv_impl( cstring name, cstring value )
#endif
#endif
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
-#define BOOST_RT_PARAM_LITERAL( l ) l
-#define BOOST_RT_PARAM_CSTRING_LITERAL( l ) cstring( l, sizeof( l ) - 1 )
-#define BOOST_RT_PARAM_GETENV getenv
-#define BOOST_RT_PARAM_PUTENV ::boost::BOOST_RT_PARAM_NAMESPACE::putenv_impl
-#define BOOST_RT_PARAM_EXCEPTION_INHERIT_STD
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( l ) l
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( l ) cstring( l, sizeof( l ) - 1 )
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_GETENV getenv
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_PUTENV ::boost::BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE::putenv_impl
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_EXCEPTION_INHERIT_STD
//____________________________________________________________________________//
@@ -133,24 +139,24 @@ putenv_impl( cstring name, cstring value )
}
#endif
-#define BOOST_RT_PARAM_LITERAL( l ) L ## l
-#define BOOST_RT_PARAM_CSTRING_LITERAL( l ) cstring( L ## l, sizeof( L ## l )/sizeof(wchar_t) - 1 )
-#define BOOST_RT_PARAM_GETENV wgetenv
-#define BOOST_RT_PARAM_PUTENV putenv_impl
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( l ) L ## l
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( l ) cstring( L ## l, sizeof( L ## l )/sizeof(wchar_t) - 1 )
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_GETENV wgetenv
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_PUTENV putenv_impl
# endif
#endif
#ifdef __GNUC__
-#define BOOST_RT_PARAM_UNNEEDED_VIRTUAL virtual
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_UNNEEDED_VIRTUAL virtual
#else
-#define BOOST_RT_PARAM_UNNEEDED_VIRTUAL
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_UNNEEDED_VIRTUAL
#endif
//____________________________________________________________________________//
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CONFIG_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CONFIG_HPP
diff --git a/boost/test/utils/runtime/configuration.hpp b/boost/test/utils/runtime/configuration.hpp
index 4c133bdea2..bf731736ee 100644
--- a/boost/test/utils/runtime/configuration.hpp
+++ b/boost/test/utils/runtime/configuration.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : abstract interface for the formal parameter
// ***************************************************************************
-#ifndef BOOST_RT_CONFIGURATION_HPP_062604GER
-#define BOOST_RT_CONFIGURATION_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_CONFIGURATION_HPP
+#define BOOST_TEST_UTILS_RUNTIME_CONFIGURATION_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -22,7 +22,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
// ************************************************************************** //
// ************** runtime::configuration ************** //
@@ -54,8 +54,8 @@ public:
private:
};
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_CONFIGURATION_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_CONFIGURATION_HPP
diff --git a/boost/test/utils/runtime/env/environment.cpp b/boost/test/utils/runtime/env/environment.cpp
index a7a0fdf0c2..ddf47b342c 100644
--- a/boost/test/utils/runtime/env/environment.cpp
+++ b/boost/test/utils/runtime/env/environment.cpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2004-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2004-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/libs/test for the library home page.
@@ -9,7 +9,7 @@
//
// Version : $Revision$
//
-// Description : implements offline model of program environment
+// Description : implements offline model of program environment
// ***************************************************************************
#include <boost/test/utils/runtime/config.hpp>
@@ -19,5 +19,5 @@
# pragma warning(disable: 4701) // local environment 'result' may be used without having been initialized
#endif
-#define BOOST_RT_PARAM_INLINE
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
#include <boost/test/utils/runtime/env/environment.ipp>
diff --git a/boost/test/utils/runtime/env/environment.hpp b/boost/test/utils/runtime/env/environment.hpp
index f3170ff53a..62b2ae6dc1 100644
--- a/boost/test/utils/runtime/env/environment.hpp
+++ b/boost/test/utils/runtime/env/environment.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -9,11 +9,11 @@
//
// Version : $Revision$
//
-// Description : defines and implements inline model of program environment
+// Description : defines and implements inline model of program environment
// ***************************************************************************
-#ifndef BOOST_RT_ENV_ENVIRONMENT_HPP_062604GER
-#define BOOST_RT_ENV_ENVIRONMENT_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_ENV_ENVIRONMENT_HPP
+#define BOOST_TEST_UTILS_RUNTIME_ENV_ENVIRONMENT_HPP
#ifdef UNDER_CE
#error Windows CE does not support environment variables.
@@ -29,15 +29,12 @@
#include <boost/test/utils/runtime/env/modifier.hpp>
#include <boost/test/utils/runtime/env/variable.hpp>
-// Boost.Test
-#include <boost/test/utils/callback.hpp>
-
// Boost
#include <boost/optional.hpp>
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
// ************************************************************************** //
// ************** runtime::environment implementation ************** //
@@ -56,7 +53,7 @@ init_new_var( cstring var_name, Modifiers m = nfp::no_params )
cstring str_value = sys_read_var( new_vd.m_var_name );
if( !str_value.is_empty() ) {
- try {
+ BOOST_TEST_IMPL_TRY {
boost::optional<T> value;
if( m.has( interpreter ) )
@@ -70,7 +67,7 @@ init_new_var( cstring var_name, Modifiers m = nfp::no_params )
arg_value<T>( *new_vd.m_value ) = *value;
}
}
- catch( ... ) { // !! could we do that
+ BOOST_TEST_IMPL_CATCHALL() { // !! could we do that
// !! should we report an error?
}
}
@@ -158,15 +155,17 @@ namespace environment {
namespace env = environment;
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#ifndef BOOST_RT_PARAM_OFFLINE
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_OFFLINE
-#define BOOST_RT_PARAM_INLINE inline
-#include <boost/test/utils/runtime/env/environment.ipp>
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE
+# define BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE inline
+#endif
+# include <boost/test/utils/runtime/env/environment.ipp>
#endif
-#endif // BOOST_RT_ENV_ENVIRONMENT_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_ENV_ENVIRONMENT_HPP
diff --git a/boost/test/utils/runtime/env/environment.ipp b/boost/test/utils/runtime/env/environment.ipp
index 5a320003f7..6baf72f430 100644
--- a/boost/test/utils/runtime/env/environment.ipp
+++ b/boost/test/utils/runtime/env/environment.ipp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -9,11 +9,11 @@
//
// Version : $Revision$
//
-// Description : implements model of program environment
+// Description : implements model of program environment
// ***************************************************************************
-#ifndef BOOST_RT_ENV_ENVIRONMENT_IPP_062904GER
-#define BOOST_RT_ENV_ENVIRONMENT_IPP_062904GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_ENV_ENVIRONMENT_IPP
+#define BOOST_TEST_UTILS_RUNTIME_ENV_ENVIRONMENT_IPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -31,7 +31,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace environment {
@@ -44,10 +44,10 @@ namespace rt_env_detail {
typedef std::map<cstring,rt_env_detail::variable_data> registry;
typedef std::list<dstring> keys;
-BOOST_RT_PARAM_INLINE registry& s_registry() { static registry instance; return instance; }
-BOOST_RT_PARAM_INLINE keys& s_keys() { static keys instance; return instance; }
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE registry& s_registry() { static registry instance; return instance; }
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE keys& s_keys() { static keys instance; return instance; }
-BOOST_RT_PARAM_INLINE variable_data&
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE variable_data&
new_var_record( cstring var_name )
{
// save the name in list of keys
@@ -57,15 +57,15 @@ new_var_record( cstring var_name )
// create and return new record
variable_data& new_var_data = s_registry()[key];
-
+
new_var_data.m_var_name = key;
-
+
return new_var_data;
}
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE variable_data*
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE variable_data*
find_var_record( cstring var_name )
{
registry::iterator it = s_registry().find( var_name );
@@ -75,41 +75,41 @@ find_var_record( cstring var_name )
//____________________________________________________________________________//
-#ifdef BOOST_MSVC
-#pragma warning(push)
+#ifdef BOOST_MSVC
+#pragma warning(push)
#pragma warning(disable:4996) // getenv
#endif
-BOOST_RT_PARAM_INLINE cstring
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE cstring
sys_read_var( cstring var_name )
{
using namespace std;
- return BOOST_RT_PARAM_GETENV( var_name.begin() );
+ return BOOST_TEST_UTILS_RUNTIME_PARAM_GETENV( var_name.begin() );
}
-#ifdef BOOST_MSVC
-#pragma warning(pop)
+#ifdef BOOST_MSVC
+#pragma warning(pop)
#endif
//____________________________________________________________________________//
-BOOST_RT_PARAM_INLINE void
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE void
sys_write_var( cstring var_name, format_stream& var_value )
{
- BOOST_RT_PARAM_PUTENV( var_name, cstring( var_value.str() ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_PUTENV( var_name, cstring( var_value.str() ) );
}
//____________________________________________________________________________//
} // namespace rt_env_detail
-BOOST_RT_PARAM_INLINE variable_base
+BOOST_TEST_UTILS_RUNTIME_PARAM_INLINE variable_base
var( cstring var_name )
{
rt_env_detail::variable_data* vd = rt_env_detail::find_var_record( var_name );
- BOOST_RT_PARAM_VALIDATE_LOGIC( !!vd,
- BOOST_RT_PARAM_LITERAL( "First access to the environment variable " )
- << var_name << BOOST_RT_PARAM_LITERAL( " should be typed" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( !!vd,
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "First access to the environment variable " )
+ << var_name << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( " should be typed" ) );
return variable_base( *vd );
}
@@ -118,8 +118,8 @@ var( cstring var_name )
} // namespace environment
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_ENV_ENVIRONMENT_IPP_062904GER
+#endif // BOOST_TEST_UTILS_RUNTIME_ENV_ENVIRONMENT_IPP_062904GER
diff --git a/boost/test/utils/runtime/env/fwd.hpp b/boost/test/utils/runtime/env/fwd.hpp
index dff5dfd299..438795ea8f 100644
--- a/boost/test/utils/runtime/env/fwd.hpp
+++ b/boost/test/utils/runtime/env/fwd.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : environment subsystem forward declarations
// ***************************************************************************
-#ifndef BOOST_RT_ENV_FWD_HPP_062604GER
-#define BOOST_RT_ENV_FWD_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_ENV_FWD_HPP
+#define BOOST_TEST_UTILS_RUNTIME_ENV_FWD_HPP
#ifdef UNDER_CE
#error Windows CE does not support environment variables.
@@ -24,13 +24,20 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace environment {
+template<typename T>
+class variable;
+
class variable_base;
variable_base var( cstring var_name );
+template<typename T>
+inline variable<T>
+ var( cstring var_name );
+
namespace rt_env_detail {
struct variable_data;
@@ -47,8 +54,8 @@ template <typename T> class variable;
} // namespace environment
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_ENV_FWD_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_ENV_FWD_HPP
diff --git a/boost/test/utils/runtime/env/modifier.hpp b/boost/test/utils/runtime/env/modifier.hpp
index cdd6be908f..536461a549 100644
--- a/boost/test/utils/runtime/env/modifier.hpp
+++ b/boost/test/utils/runtime/env/modifier.hpp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-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)
@@ -12,8 +12,8 @@
// Description : defines variable modifiers
// ***************************************************************************
-#ifndef BOOST_RT_ENV_MODIFIER_HPP_062604GER
-#define BOOST_RT_ENV_MODIFIER_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_ENV_MODIFIER_HPP
+#define BOOST_TEST_UTILS_RUNTIME_ENV_MODIFIER_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -23,7 +23,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace environment {
@@ -40,8 +40,8 @@ nfp::keyword<struct interpreter_t> interpreter;
} // local namespace
} // namespace environment
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_ENV_MODIFIER_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_ENV_MODIFIER_HPP
diff --git a/boost/test/utils/runtime/env/variable.hpp b/boost/test/utils/runtime/env/variable.hpp
index 8e8b0a0737..df776a619a 100644
--- a/boost/test/utils/runtime/env/variable.hpp
+++ b/boost/test/utils/runtime/env/variable.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : defines model of program environment variable
// ***************************************************************************
-#ifndef BOOST_RT_ENV_VARIABLE_HPP_062604GER
-#define BOOST_RT_ENV_VARIABLE_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_ENV_VARIABLE_HPP
+#define BOOST_TEST_UTILS_RUNTIME_ENV_VARIABLE_HPP
#ifdef UNDER_CE
#error Windows CE does not support environment variables.
@@ -32,7 +32,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace environment {
@@ -74,7 +74,7 @@ public:
res.reset();
}
- bool has_value() const { return m_data->m_value!=0; }
+ bool has_value() const { return !!m_data->m_value; }
cstring name() const { return m_data->m_var_name; }
protected:
@@ -95,7 +95,7 @@ public:
template<typename Modifiers>
explicit variable( cstring var_name, Modifiers const& m );
- explicit variable( rt_env_detail::variable_data& data )
+ explicit variable( rt_env_detail::variable_data& data )
: variable_base( data ) {}
// other variable assignment
@@ -179,7 +179,7 @@ operator!=( V const& v, variable<T> ev )
} // namespace environment
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
@@ -195,7 +195,7 @@ operator!=( V const& v, variable<T> ev )
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace environment {
@@ -216,8 +216,8 @@ variable<T>::variable( cstring var_name, Modifiers const& m )
} // namespace environment
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_ENV_VARIABLE_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_ENV_VARIABLE_HPP
diff --git a/boost/test/utils/runtime/file/config_file.cpp b/boost/test/utils/runtime/file/config_file.cpp
index d369d79504..1e13d66eee 100644
--- a/boost/test/utils/runtime/file/config_file.cpp
+++ b/boost/test/utils/runtime/file/config_file.cpp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-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)
@@ -26,7 +26,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace file {
@@ -60,7 +60,7 @@ operator<<( std::ostream& os, parameter const& p )
param_namespace::param_namespace( cstring name, param_namespace const* parent )
: p_parent( parent )
{
- assign_op( p_name.value, name );
+ assign_op( p_name.value, name, 0 );
}
//____________________________________________________________________________//
@@ -69,8 +69,8 @@ void
param_namespace::insert_param( cstring param_name, cstring param_value )
{
BOOST_TEST_FOREACH( parameter const&, p, m_parameters )
- BOOST_RT_PARAM_VALIDATE_LOGIC( p.p_name != param_name,
- BOOST_RT_PARAM_LITERAL( "Duplicate parameter " ) << param_name );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( p.p_name != param_name,
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "Duplicate parameter " ) << param_name );
m_parameters.push_back( parameter( param_name, param_value, *this ) );
}
@@ -133,7 +133,7 @@ get_param_value( param_namespace const& where_from,
return res;
}
-
+
param_namespace const* sns = get_param_subns( where_from, name_part1 );
return sns ? get_param_value( *sns, name_part2, name_part3, name_part4, name_part5 )
@@ -153,13 +153,13 @@ get_requ_param_value( param_namespace const& where_from,
boost::optional<cstring> v = get_param_value( where_from, name_part1, name_part2, name_part3, name_part4, name_part5 );
#define APPEND_PART( part ) (part.is_empty() ? "" : "::") << (part.is_empty() ? cstring() : part)
- BOOST_RT_PARAM_VALIDATE_LOGIC( !!v, BOOST_RT_PARAM_LITERAL( "Required parameter " )
- << name_part1
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( !!v, BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "Required parameter " )
+ << name_part1
<< APPEND_PART( name_part2 )
<< APPEND_PART( name_part3 )
<< APPEND_PART( name_part4 )
<< APPEND_PART( name_part5 )
- << BOOST_RT_PARAM_LITERAL( " value is missing" ) );
+ << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( " value is missing" ) );
#undef APPEND_PART
return *v;
@@ -186,7 +186,7 @@ get_param_subns( param_namespace const& where_from, cstring namespace_name )
//____________________________________________________________________________//
void
-param_namespace::load_impl( config_file_iterator cf_it,
+param_namespace::load_impl( config_file_iterator cf_it,
cstring value_marker, cstring value_delimeter, cstring namespace_delimeter )
{
using namespace unit_test;
@@ -242,7 +242,7 @@ config_file::config_file( cstring file_name )
} // namespace file
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
diff --git a/boost/test/utils/runtime/file/config_file.hpp b/boost/test/utils/runtime/file/config_file.hpp
index f9c71b8138..e7baf08bf2 100644
--- a/boost/test/utils/runtime/file/config_file.hpp
+++ b/boost/test/utils/runtime/file/config_file.hpp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-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)
@@ -12,8 +12,8 @@
// Description : defines models configuration file, it's parameter and parameter namespaces
// ***************************************************************************
-#ifndef BOOST_RT_FILE_CONFIG_FILE_HPP_010105GER
-#define BOOST_RT_FILE_CONFIG_FILE_HPP_010105GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_FILE_CONFIG_FILE_HPP
+#define BOOST_TEST_UTILS_RUNTIME_FILE_CONFIG_FILE_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -32,7 +32,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace file {
@@ -65,7 +65,7 @@ namespace {
nfp::typed_keyword<cstring, struct value_marker_t> value_marker;
nfp::typed_keyword<cstring, struct value_delimeter_t> value_delimeter;
nfp::typed_keyword<cstring, struct namespace_delimeter_t> namespace_delimeter;
-} // local namespace
+} // local namespace
// ************************************************************************** //
// ************** runtime::file::param_namespace ************** //
@@ -86,9 +86,9 @@ public:
template<typename Modifier>
void load( config_file_iterator cf_it, Modifier const& m )
{
- cstring vm = m.has( value_marker ) ? m[value_marker] : BOOST_RT_PARAM_CSTRING_LITERAL( "\"" );
- cstring vd = m.has( value_delimeter ) ? m[value_delimeter] : BOOST_RT_PARAM_CSTRING_LITERAL( "= \t\n\r" );
- cstring nd = m.has( namespace_delimeter ) ? m[namespace_delimeter] : BOOST_RT_PARAM_CSTRING_LITERAL( "::" );
+ cstring vm = m.has( value_marker ) ? m[value_marker] : BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "\"" );
+ cstring vd = m.has( value_delimeter ) ? m[value_delimeter] : BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "= \t\n\r" );
+ cstring nd = m.has( namespace_delimeter ) ? m[namespace_delimeter] : BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "::" );
load_impl( cf_it, vm, vd, nd );
}
@@ -126,7 +126,7 @@ protected:
explicit param_namespace( cstring name, param_namespace const* parent = 0 );
private:
- void load_impl( config_file_iterator cf_it,
+ void load_impl( config_file_iterator cf_it,
cstring value_marker_, cstring value_delimeter_, cstring namespace_delimeter_ );
// Data members
@@ -175,8 +175,8 @@ public:
} // namespace file
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_FILE_CONFIG_FILE_HPP_010105GER
+#endif // BOOST_TEST_UTILS_RUNTIME_FILE_CONFIG_FILE_HPP_010105GER
diff --git a/boost/test/utils/runtime/file/config_file_iterator.cpp b/boost/test/utils/runtime/file/config_file_iterator.cpp
index a81a0c83e5..5d6cbdf7dc 100644
--- a/boost/test/utils/runtime/file/config_file_iterator.cpp
+++ b/boost/test/utils/runtime/file/config_file_iterator.cpp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-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)
@@ -24,9 +24,9 @@
// Boost
-#include <boost/utility.hpp>
#include <boost/scoped_array.hpp>
#include <boost/bind.hpp>
+#include <boost/noncopyable.hpp>
// Boost.Test
#include <boost/test/utils/basic_cstring/compare.hpp>
@@ -45,7 +45,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace file {
@@ -71,7 +71,7 @@ struct symbol_to_value_map : std::map<cstring, ValueType> {
m_name_store.erase( it );
- erase( name );
+ this->erase( name );
}
private:
@@ -106,7 +106,7 @@ is_valid_identifier( cstring const& source )
return false;
while( ++it < source.end() ) {
- if( !std::isalnum( *it ) && *it != BOOST_RT_PARAM_LITERAL( '_' ) && *it != BOOST_RT_PARAM_LITERAL( '-' ) )
+ if( !std::isalnum( *it ) && *it != BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( '_' ) && *it != BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( '-' ) )
return false;
}
@@ -158,7 +158,7 @@ include_level::include_level( cstring file_name, cstring path_separators, includ
}
}
- BOOST_RT_PARAM_VALIDATE_LOGIC( m_stream.is_open(), BOOST_RT_PARAM_LITERAL( "can't open file " ) << file_name );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( m_stream.is_open(), BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "can't open file " ) << file_name );
}
//____________________________________________________________________________//
@@ -234,21 +234,21 @@ struct config_file_iterator::Impl : noncopyable {
//____________________________________________________________________________//
config_file_iterator::Impl::Impl()
-: m_path_separators( BOOST_RT_PARAM_LITERAL( "/\\" ) )
-, m_line_delimeter( BOOST_RT_PARAM_LITERAL( '\n' ) )
-, m_sl_comment_delimeter( BOOST_RT_PARAM_LITERAL( "#" ) )
-, m_command_delimeter( BOOST_RT_PARAM_LITERAL( "$" ) )
-, m_line_beak( BOOST_RT_PARAM_LITERAL( "\\" ) )
-, m_macro_ref_begin( BOOST_RT_PARAM_LITERAL( "$" ) )
-, m_macro_ref_end( BOOST_RT_PARAM_LITERAL( "$" ) )
-
-, m_include_kw( BOOST_RT_PARAM_LITERAL( "include" ) )
-, m_define_kw( BOOST_RT_PARAM_LITERAL( "define" ) )
-, m_undef_kw( BOOST_RT_PARAM_LITERAL( "undef" ) )
-, m_ifdef_kw( BOOST_RT_PARAM_LITERAL( "ifdef" ) )
-, m_ifndef_kw( BOOST_RT_PARAM_LITERAL( "ifndef" ) )
-, m_else_kw( BOOST_RT_PARAM_LITERAL( "else" ) )
-, m_endif_kw( BOOST_RT_PARAM_LITERAL( "endif" ) )
+: m_path_separators( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "/\\" ) )
+, m_line_delimeter( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( '\n' ) )
+, m_sl_comment_delimeter( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "#" ) )
+, m_command_delimeter( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "$" ) )
+, m_line_beak( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "\\" ) )
+, m_macro_ref_begin( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "$" ) )
+, m_macro_ref_end( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "$" ) )
+
+, m_include_kw( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "include" ) )
+, m_define_kw( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "define" ) )
+, m_undef_kw( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "undef" ) )
+, m_ifdef_kw( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "ifdef" ) )
+, m_ifndef_kw( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "ifndef" ) )
+, m_else_kw( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "else" ) )
+, m_endif_kw( BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "endif" ) )
, m_buffer_size( 8192 )
@@ -338,9 +338,9 @@ config_file_iterator::Impl::get_next_line( cstring& line )
return true; // 110 //
}
- BOOST_RT_PARAM_VALIDATE_LOGIC( !broken_line, BOOST_RT_PARAM_LITERAL( "broken line is not completed" ) );
- BOOST_RT_PARAM_VALIDATE_LOGIC( m_conditional_states.size() == 0,
- BOOST_RT_PARAM_LITERAL( "matching endif command is missing" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( !broken_line, BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "broken line is not completed" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( m_conditional_states.size() == 0,
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "matching endif command is missing" ) );
return false;
}
@@ -359,14 +359,14 @@ config_file_iterator::Impl::get_macro_value( cstring macro_name, bool ignore_mis
env::get( macro_name, macro_value );
#endif
- BOOST_RT_PARAM_VALIDATE_LOGIC( macro_value || ignore_missing || !m_detect_missing_macro,
- BOOST_RT_PARAM_LITERAL( "Unknown macro \"" ) << macro_name << BOOST_RT_PARAM_LITERAL( "\"" ) );
-
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( macro_value || ignore_missing || !m_detect_missing_macro,
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "Unknown macro \"" ) << macro_name << BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "\"" ) );
+
if( !macro_value ) {
if( !ignore_missing )
macro_value = cstring();
}
- else
+ else
m_symbols_table.add( macro_name, *macro_value );
return macro_value;
@@ -386,7 +386,7 @@ config_file_iterator::Impl::process_command_line( cstring line )
command_handler_map::const_iterator it = m_command_handler_map.find( *tit );
- BOOST_RT_PARAM_VALIDATE_LOGIC( it != m_command_handler_map.end(), BOOST_RT_PARAM_LITERAL( "Invalid command " ) << *tit );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( it != m_command_handler_map.end(), BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "Invalid command " ) << *tit );
++tit;
@@ -405,13 +405,13 @@ config_file_iterator::Impl::process_include( cstring line )
string_token_iterator tit( line, kept_delimeters = dt_none );
- BOOST_RT_PARAM_VALIDATE_LOGIC( tit != string_token_iterator(),
- BOOST_RT_PARAM_LITERAL( "include file name missing" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( tit != string_token_iterator(),
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "include file name missing" ) );
cstring include_file_name = *tit;
- BOOST_RT_PARAM_VALIDATE_LOGIC( ++tit == string_token_iterator(),
- BOOST_RT_PARAM_LITERAL( "unexpected tokens at the end of include command" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( ++tit == string_token_iterator(),
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "unexpected tokens at the end of include command" ) );
substitute_macros( include_file_name );
@@ -431,8 +431,8 @@ config_file_iterator::Impl::process_define( cstring line )
string_token_iterator tit( line, (kept_delimeters = dt_none, max_tokens = 2 ));
cstring macro_name = *tit;
- BOOST_RT_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ),
- BOOST_RT_PARAM_LITERAL( "invalid macro name" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ),
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "invalid macro name" ) );
cstring macro_value = *(++tit);
substitute_macros( macro_value );
@@ -449,8 +449,8 @@ config_file_iterator::Impl::process_undef( cstring line )
return;
cstring macro_name = line;
- BOOST_RT_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ),
- BOOST_RT_PARAM_LITERAL( "invalid macro name" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ),
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "invalid macro name" ) );
m_symbols_table.remove( macro_name );
}
@@ -465,8 +465,8 @@ config_file_iterator::Impl::process_ifdef( cstring line )
return;
cstring macro_name = line;
- BOOST_RT_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ),
- BOOST_RT_PARAM_LITERAL( "invalid macro name" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ),
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "invalid macro name" ) );
if( !get_macro_value( macro_name ) )
m_inactive_ifdef_level = m_conditional_states.size();
@@ -482,8 +482,8 @@ config_file_iterator::Impl::process_ifndef( cstring line )
return;
cstring macro_name = line;
- BOOST_RT_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ),
- BOOST_RT_PARAM_LITERAL( "invalid macro name" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ),
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "invalid macro name" ) );
if( get_macro_value( macro_name ) )
m_inactive_ifdef_level = m_conditional_states.size();
@@ -494,12 +494,12 @@ config_file_iterator::Impl::process_ifndef( cstring line )
void
config_file_iterator::Impl::process_else( cstring line )
{
- BOOST_RT_PARAM_VALIDATE_LOGIC( m_conditional_states.size() > 0 && m_conditional_states.back(),
- BOOST_RT_PARAM_LITERAL( "else without matching if" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( m_conditional_states.size() > 0 && m_conditional_states.back(),
+ BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "else without matching if" ) );
m_inactive_ifdef_level = m_conditional_states.size() == m_inactive_ifdef_level ? 0 : m_conditional_states.size();
- BOOST_RT_PARAM_VALIDATE_LOGIC( line.is_empty(), BOOST_RT_PARAM_LITERAL( "unexpected tokens at the end of else command" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( line.is_empty(), BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "unexpected tokens at the end of else command" ) );
}
//____________________________________________________________________________//
@@ -507,13 +507,13 @@ config_file_iterator::Impl::process_else( cstring line )
void
config_file_iterator::Impl::process_endif( cstring line )
{
- BOOST_RT_PARAM_VALIDATE_LOGIC( m_conditional_states.size() > 0, BOOST_RT_PARAM_LITERAL( "endif without matching if" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( m_conditional_states.size() > 0, BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "endif without matching if" ) );
if( m_conditional_states.size() == m_inactive_ifdef_level )
m_inactive_ifdef_level = 0;
m_conditional_states.pop_back();
- BOOST_RT_PARAM_VALIDATE_LOGIC( line.is_empty(), BOOST_RT_PARAM_LITERAL( "unexpected tokens at the end of endif command" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( line.is_empty(), BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "unexpected tokens at the end of endif command" ) );
}
//____________________________________________________________________________//
@@ -531,7 +531,7 @@ config_file_iterator::Impl::substitute_macros( cstring& where )
pos = where.find( m_macro_ref_end );
- BOOST_RT_PARAM_VALIDATE_LOGIC( pos != cstring::npos, BOOST_RT_PARAM_LITERAL( "incomplete macro reference" ) );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( pos != cstring::npos, BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( "incomplete macro reference" ) );
cstring value = *get_macro_value( where.substr( 0, pos ), false );
m_post_subst_line.append( value.begin(), value.size() );
@@ -562,18 +562,18 @@ config_file_iterator::construct()
void
config_file_iterator::load( cstring file_name )
{
- m_pimpl->m_curr_level.reset( new include_level( file_name, m_pimpl->m_path_separators ) );
- m_pimpl->m_buffer.reset( new char[m_pimpl->m_buffer_size] );
-
- register_command_handler( m_pimpl->m_include_kw, bind( &Impl::process_include, m_pimpl.get(), _1 ) );
- register_command_handler( m_pimpl->m_define_kw, bind( &Impl::process_define, m_pimpl.get(), _1 ) );
- register_command_handler( m_pimpl->m_undef_kw, bind( &Impl::process_undef, m_pimpl.get(), _1 ) );
- register_command_handler( m_pimpl->m_ifdef_kw, bind( &Impl::process_ifdef, m_pimpl.get(), _1 ) );
- register_command_handler( m_pimpl->m_ifndef_kw, bind( &Impl::process_ifndef, m_pimpl.get(), _1 ) );
- register_command_handler( m_pimpl->m_else_kw, bind( &Impl::process_else, m_pimpl.get(), _1 ) );
- register_command_handler( m_pimpl->m_endif_kw, bind( &Impl::process_endif, m_pimpl.get(), _1 ) );
-
- init();
+ m_pimpl->m_curr_level.reset( new include_level( file_name, m_pimpl->m_path_separators ) );
+ m_pimpl->m_buffer.reset( new char[m_pimpl->m_buffer_size] );
+
+ register_command_handler( m_pimpl->m_include_kw, boost::bind( &Impl::process_include, m_pimpl.get(), _1 ) );
+ register_command_handler( m_pimpl->m_define_kw, boost::bind( &Impl::process_define, m_pimpl.get(), _1 ) );
+ register_command_handler( m_pimpl->m_undef_kw, boost::bind( &Impl::process_undef, m_pimpl.get(), _1 ) );
+ register_command_handler( m_pimpl->m_ifdef_kw, boost::bind( &Impl::process_ifdef, m_pimpl.get(), _1 ) );
+ register_command_handler( m_pimpl->m_ifndef_kw, boost::bind( &Impl::process_ifndef, m_pimpl.get(), _1 ) );
+ register_command_handler( m_pimpl->m_else_kw, boost::bind( &Impl::process_else, m_pimpl.get(), _1 ) );
+ register_command_handler( m_pimpl->m_endif_kw, boost::bind( &Impl::process_endif, m_pimpl.get(), _1 ) );
+
+ init();
}
//____________________________________________________________________________//
@@ -606,31 +606,31 @@ void
config_file_iterator::set_parameter( rtti::id_t id, cstring value )
{
BOOST_RTTI_SWITCH( id ) {
- BOOST_RTTI_CASE( cfg_detail::path_separators_t )
+ BOOST_RTTI_CASE( cfg_detail::path_separators_t )
assign_op( m_pimpl->m_path_separators , value, 0 );
- BOOST_RTTI_CASE( cfg_detail::sl_comment_delimeter_t )
+ BOOST_RTTI_CASE( cfg_detail::sl_comment_delimeter_t )
assign_op( m_pimpl->m_sl_comment_delimeter , value, 0 );
- BOOST_RTTI_CASE( cfg_detail::command_delimeter_t )
+ BOOST_RTTI_CASE( cfg_detail::command_delimeter_t )
assign_op( m_pimpl->m_command_delimeter , value, 0 );
- BOOST_RTTI_CASE( cfg_detail::line_beak_t )
+ BOOST_RTTI_CASE( cfg_detail::line_beak_t )
assign_op( m_pimpl->m_line_beak , value, 0 );
- BOOST_RTTI_CASE( cfg_detail::macro_ref_begin_t )
+ BOOST_RTTI_CASE( cfg_detail::macro_ref_begin_t )
assign_op( m_pimpl->m_macro_ref_begin , value, 0 );
- BOOST_RTTI_CASE( cfg_detail::macro_ref_end_t )
+ BOOST_RTTI_CASE( cfg_detail::macro_ref_end_t )
assign_op( m_pimpl->m_macro_ref_end , value, 0 );
- BOOST_RTTI_CASE( cfg_detail::include_kw_t )
+ BOOST_RTTI_CASE( cfg_detail::include_kw_t )
assign_op( m_pimpl->m_include_kw , value, 0 );
- BOOST_RTTI_CASE( cfg_detail::define_kw_t )
+ BOOST_RTTI_CASE( cfg_detail::define_kw_t )
assign_op( m_pimpl->m_define_kw , value, 0 );
- BOOST_RTTI_CASE( cfg_detail::undef_kw_t )
+ BOOST_RTTI_CASE( cfg_detail::undef_kw_t )
assign_op( m_pimpl->m_undef_kw , value, 0 );
- BOOST_RTTI_CASE( cfg_detail::ifdef_kw_t )
+ BOOST_RTTI_CASE( cfg_detail::ifdef_kw_t )
assign_op( m_pimpl->m_ifdef_kw , value, 0 );
- BOOST_RTTI_CASE( cfg_detail::ifndef_kw_t )
+ BOOST_RTTI_CASE( cfg_detail::ifndef_kw_t )
assign_op( m_pimpl->m_ifndef_kw , value, 0 );
- BOOST_RTTI_CASE( cfg_detail::else_kw_t )
+ BOOST_RTTI_CASE( cfg_detail::else_kw_t )
assign_op( m_pimpl->m_else_kw , value, 0 );
- BOOST_RTTI_CASE( cfg_detail::endif_kw_t )
+ BOOST_RTTI_CASE( cfg_detail::endif_kw_t )
assign_op( m_pimpl->m_endif_kw , value, 0 );
}
}
@@ -641,7 +641,7 @@ void
config_file_iterator::set_parameter( rtti::id_t id, bool value )
{
BOOST_RTTI_SWITCH( id ) {
- BOOST_RTTI_CASE( cfg_detail::trim_leading_spaces_t )
+ BOOST_RTTI_CASE( cfg_detail::trim_leading_spaces_t )
m_pimpl->m_trim_leading_spaces = value;
BOOST_RTTI_CASE( cfg_detail::trim_trailing_spaces_t )
m_pimpl->m_trim_trailing_spaces = value;
@@ -658,7 +658,7 @@ void
config_file_iterator::set_parameter( rtti::id_t id, char_type value )
{
BOOST_RTTI_SWITCH( id ) {
- BOOST_RTTI_CASE( cfg_detail::line_delimeter_t )
+ BOOST_RTTI_CASE( cfg_detail::line_delimeter_t )
m_pimpl->m_line_delimeter = value;
}
}
@@ -669,7 +669,7 @@ void
config_file_iterator::set_parameter( rtti::id_t id, std::size_t value )
{
BOOST_RTTI_SWITCH( id ) {
- BOOST_RTTI_CASE( cfg_detail::buffer_size_t )
+ BOOST_RTTI_CASE( cfg_detail::buffer_size_t )
m_pimpl->m_buffer_size = value;
}
}
@@ -678,7 +678,7 @@ config_file_iterator::set_parameter( rtti::id_t id, std::size_t value )
} // namespace file
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
diff --git a/boost/test/utils/runtime/file/config_file_iterator.hpp b/boost/test/utils/runtime/file/config_file_iterator.hpp
index 23d4a94f22..6c6273fca1 100644
--- a/boost/test/utils/runtime/file/config_file_iterator.hpp
+++ b/boost/test/utils/runtime/file/config_file_iterator.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
-// Use, modification, and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
+// (C) Copyright Gennadiy Rozental 2005-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/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : flexible configuration file iterator definition
// ***************************************************************************
-#ifndef BOOST_RT_FILE_CONFIG_FILE_ITERATOR_HPP_062604GER
-#define BOOST_RT_FILE_CONFIG_FILE_ITERATOR_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_FILE_CONFIG_FILE_ITERATOR_HPP
+#define BOOST_TEST_UTILS_RUNTIME_FILE_CONFIG_FILE_ITERATOR_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -22,19 +22,19 @@
// Boost.Test
#include <boost/test/utils/iterator/input_iterator_facade.hpp>
-#include <boost/test/utils/callback.hpp>
#include <boost/test/utils/named_params.hpp>
// Boost
#include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
namespace file {
-// Public typedef
+// Public typedef
typedef std::pair<dstring,long> location;
// ************************************************************************** //
@@ -99,7 +99,7 @@ class config_file_iterator : public unit_test::input_iterator_facade<config_file
typedef unit_test::input_iterator_facade<config_file_iterator,cstring,cstring> base;
public:
// Public typedefs
- typedef unit_test::callback1<cstring> command_handler;
+ typedef boost::function<void (cstring)> command_handler;
// Constructors
config_file_iterator() {}
@@ -159,8 +159,8 @@ private:
} // namespace file
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_FILE_CONFIG_FILE_ITERATOR_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_FILE_CONFIG_FILE_ITERATOR_HPP
diff --git a/boost/test/utils/runtime/fwd.hpp b/boost/test/utils/runtime/fwd.hpp
index aafdf69d17..2647184c5d 100644
--- a/boost/test/utils/runtime/fwd.hpp
+++ b/boost/test/utils/runtime/fwd.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : global framework level forward declaration
// ***************************************************************************
-#ifndef BOOST_RT_FWD_HPP_062604GER
-#define BOOST_RT_FWD_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_FWD_HPP
+#define BOOST_TEST_UTILS_RUNTIME_FWD_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -23,7 +23,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
class parameter;
@@ -34,8 +34,8 @@ typedef shared_ptr<argument const> const_argument_ptr;
template<typename T> class value_interpreter;
template<typename T> class typed_argument;
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_FWD_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_FWD_HPP
diff --git a/boost/test/utils/runtime/interpret_argument_value.hpp b/boost/test/utils/runtime/interpret_argument_value.hpp
index f767e7a29b..016caa017f 100644
--- a/boost/test/utils/runtime/interpret_argument_value.hpp
+++ b/boost/test/utils/runtime/interpret_argument_value.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,8 +12,8 @@
// Description : default algorithms for string to specific type convertions
// ***************************************************************************
-#ifndef BOOST_RT_INTERPRET_ARGUMENT_VALUE_HPP_062604GER
-#define BOOST_RT_INTERPRET_ARGUMENT_VALUE_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_INTERPRET_ARGUMENT_VALUE_HPP
+#define BOOST_TEST_UTILS_RUNTIME_INTERPRET_ARGUMENT_VALUE_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
@@ -33,7 +33,7 @@
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
// ************************************************************************** //
// ************** runtime::interpret_argument_value ************** //
@@ -45,11 +45,11 @@ template<typename T>
struct interpret_argument_value_impl {
static bool _( cstring source, boost::optional<T>& res )
{
- BOOST_RT_PARAM_TRACE( "In interpret_argument_value_impl<" << typeid(T).name() << ">" );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( "In interpret_argument_value_impl<" << typeid(T).name() << ">" );
res = lexical_cast<T>( source );
- BOOST_RT_PARAM_TRACE( "String " << source << " is interpreted as " << *res );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( "String " << source << " is interpreted as " << *res );
return true;
}
};
@@ -62,7 +62,7 @@ template<>
struct interpret_argument_value_impl<dstring> {
static bool _( cstring source, boost::optional<dstring>& res )
{
- BOOST_RT_PARAM_TRACE( "In interpret_argument_value_impl<dstring>" );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( "In interpret_argument_value_impl<dstring>" );
res = dstring();
assign_op( *res, source, 0 );
@@ -78,7 +78,7 @@ template<>
struct interpret_argument_value_impl<cstring> {
static bool _( cstring source, boost::optional<cstring>& res )
{
- BOOST_RT_PARAM_TRACE( "In interpret_argument_value_impl<cstring>" );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( "In interpret_argument_value_impl<cstring>" );
res = source;
@@ -93,14 +93,14 @@ template<>
struct interpret_argument_value_impl<bool> {
static bool _( cstring source, boost::optional<bool>& res )
{
- BOOST_RT_PARAM_TRACE( "In interpret_argument_value_impl<bool>" );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( "In interpret_argument_value_impl<bool>" );
- static literal_cstring YES( BOOST_RT_PARAM_CSTRING_LITERAL( "YES" ) );
- static literal_cstring Y( BOOST_RT_PARAM_CSTRING_LITERAL( "Y" ) );
- static literal_cstring NO( BOOST_RT_PARAM_CSTRING_LITERAL( "NO" ) );
- static literal_cstring N( BOOST_RT_PARAM_CSTRING_LITERAL( "N" ) );
- static literal_cstring one( BOOST_RT_PARAM_CSTRING_LITERAL( "1" ) );
- static literal_cstring zero( BOOST_RT_PARAM_CSTRING_LITERAL( "0" ) );
+ static literal_cstring YES( BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "YES" ) );
+ static literal_cstring Y( BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "Y" ) );
+ static literal_cstring NO( BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "NO" ) );
+ static literal_cstring N( BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "N" ) );
+ static literal_cstring one( BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "1" ) );
+ static literal_cstring zero( BOOST_TEST_UTILS_RUNTIME_PARAM_CSTRING_LITERAL( "0" ) );
source.trim();
@@ -114,7 +114,7 @@ struct interpret_argument_value_impl<bool> {
}
else {
res = true;
- return false;
+ return source.is_empty();
}
}
};
@@ -135,13 +135,13 @@ template<typename T>
inline bool
interpret_argument_value( cstring source, boost::optional<std::list<T> >& res, int )
{
- BOOST_RT_PARAM_TRACE( "In interpret_argument_value<std::list<T>>" );
+ BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( "In interpret_argument_value<std::list<T>>" );
res = std::list<T>();
while( !source.is_empty() ) {
// !! should we use token_iterator
- cstring::iterator single_value_end = std::find( source.begin(), source.end(), BOOST_RT_PARAM_LITERAL( ',' ) );
+ cstring::iterator single_value_end = std::find( source.begin(), source.end(), BOOST_TEST_UTILS_RUNTIME_PARAM_LITERAL( ',' ) );
boost::optional<T> value;
interpret_argument_value( cstring( source.begin(), single_value_end ), value, 0 );
@@ -156,8 +156,8 @@ interpret_argument_value( cstring source, boost::optional<std::list<T> >& res, i
//____________________________________________________________________________//
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_INTERPRET_ARGUMENT_VALUE_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_INTERPRET_ARGUMENT_VALUE_HPP
diff --git a/boost/test/utils/runtime/parameter.hpp b/boost/test/utils/runtime/parameter.hpp
index b914a9b4e5..2dd4ba725c 100644
--- a/boost/test/utils/runtime/parameter.hpp
+++ b/boost/test/utils/runtime/parameter.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,15 +12,15 @@
// Description : abstract interface for the formal parameter
// ***************************************************************************
-#ifndef BOOST_RT_PARAMETER_HPP_062604GER
-#define BOOST_RT_PARAMETER_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_PARAMETER_HPP
+#define BOOST_TEST_UTILS_RUNTIME_PARAMETER_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
// ************************************************************************** //
// ************** runtime::parameter ************** //
@@ -31,8 +31,8 @@ public:
virtual ~parameter() {}
};
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_PARAMETER_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_PARAMETER_HPP
diff --git a/boost/test/utils/runtime/trace.hpp b/boost/test/utils/runtime/trace.hpp
index 5c4e2a7c05..17a169b283 100644
--- a/boost/test/utils/runtime/trace.hpp
+++ b/boost/test/utils/runtime/trace.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,19 +12,19 @@
// Description : optional internal tracing
// ***************************************************************************
-#ifndef BOOST_RT_TRACE_HPP_062604GER
-#define BOOST_RT_TRACE_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_TRACE_HPP
+#define BOOST_TEST_UTILS_RUNTIME_TRACE_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
-#ifdef BOOST_RT_PARAM_DEBUG
+#ifdef BOOST_TEST_UTILS_RUNTIME_PARAM_DEBUG
#include <iostream>
-# define BOOST_RT_PARAM_TRACE( str ) std::cerr << str << std::endl
+# define BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( str ) std::cerr << str << std::endl
#else
-# define BOOST_RT_PARAM_TRACE( str )
+# define BOOST_TEST_UTILS_RUNTIME_PARAM_TRACE( str )
#endif
-#endif // BOOST_RT_TRACE_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_TRACE_HPP
diff --git a/boost/test/utils/runtime/validation.hpp b/boost/test/utils/runtime/validation.hpp
index bcfbc9f062..54163dc6a6 100644
--- a/boost/test/utils/runtime/validation.hpp
+++ b/boost/test/utils/runtime/validation.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,33 +12,34 @@
// Description : defines exceptions and validation tools
// ***************************************************************************
-#ifndef BOOST_RT_VALIDATION_HPP_062604GER
-#define BOOST_RT_VALIDATION_HPP_062604GER
+#ifndef BOOST_TEST_UTILS_RUNTIME_VALIDATION_HPP
+#define BOOST_TEST_UTILS_RUNTIME_VALIDATION_HPP
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
// Boost.Test
#include <boost/test/utils/class_properties.hpp>
+#include <boost/test/detail/throw_exception.hpp>
// Boost
#include <boost/shared_ptr.hpp>
// STL
-#ifdef BOOST_RT_PARAM_EXCEPTION_INHERIT_STD
+#ifdef BOOST_TEST_UTILS_RUNTIME_PARAM_EXCEPTION_INHERIT_STD
#include <stdexcept>
#endif
namespace boost {
-namespace BOOST_RT_PARAM_NAMESPACE {
+namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE {
// ************************************************************************** //
// ************** runtime::logic_error ************** //
// ************************************************************************** //
-class logic_error
-#ifdef BOOST_RT_PARAM_EXCEPTION_INHERIT_STD
+class logic_error
+#ifdef BOOST_TEST_UTILS_RUNTIME_PARAM_EXCEPTION_INHERIT_STD
: public std::exception
#endif
{
@@ -46,10 +47,12 @@ class logic_error
public:
// Constructor // !! could we eliminate shared_ptr
explicit logic_error( cstring msg ) : m_msg( new dstring( msg.begin(), msg.size() ) ) {}
- ~logic_error() throw() {}
+ ~logic_error() BOOST_NOEXCEPT_OR_NOTHROW
+ {}
dstring const& msg() const { return *m_msg; }
- virtual char_type const* what() const throw() { return m_msg->c_str(); }
+ virtual char_type const* what() const BOOST_NOEXCEPT_OR_NOTHROW
+ { return m_msg->c_str(); }
private:
dstring_ptr m_msg;
@@ -62,21 +65,21 @@ private:
inline void
report_logic_error( format_stream& msg )
{
- throw BOOST_RT_PARAM_NAMESPACE::logic_error( msg.str() );
+ BOOST_TEST_IMPL_THROW( BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE::logic_error( msg.str() ) );
}
//____________________________________________________________________________//
-#define BOOST_RT_PARAM_REPORT_LOGIC_ERROR( msg ) \
- boost::BOOST_RT_PARAM_NAMESPACE::report_logic_error( format_stream().ref() << msg )
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_REPORT_LOGIC_ERROR( msg ) \
+ boost::BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE::report_logic_error( format_stream().ref() << msg )
-#define BOOST_RT_PARAM_VALIDATE_LOGIC( b, msg ) \
- if( b ) {} else BOOST_RT_PARAM_REPORT_LOGIC_ERROR( msg )
+#define BOOST_TEST_UTILS_RUNTIME_PARAM_VALIDATE_LOGIC( b, msg ) \
+ if( b ) {} else BOOST_TEST_UTILS_RUNTIME_PARAM_REPORT_LOGIC_ERROR( msg )
//____________________________________________________________________________//
-} // namespace BOOST_RT_PARAM_NAMESPACE
+} // namespace BOOST_TEST_UTILS_RUNTIME_PARAM_NAMESPACE
} // namespace boost
-#endif // BOOST_RT_VALIDATION_HPP_062604GER
+#endif // BOOST_TEST_UTILS_RUNTIME_VALIDATION_HPP
diff --git a/boost/test/utils/setcolor.hpp b/boost/test/utils/setcolor.hpp
new file mode 100644
index 0000000000..f47ec84d8d
--- /dev/null
+++ b/boost/test/utils/setcolor.hpp
@@ -0,0 +1,117 @@
+// (C) Copyright Gennadiy Rozental 2009-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/test for the library home page.
+//
+// File : $RCSfile$
+//
+// Version : $Revision$
+//
+// Description : contains definition for setcolor iostream manipulator
+// ***************************************************************************
+
+#ifndef BOOST_TEST_UTILS_SETCOLOR_HPP
+#define BOOST_TEST_UTILS_SETCOLOR_HPP
+
+// Boost.Test
+#include <boost/test/detail/config.hpp>
+
+// STL
+#include <iostream>
+#include <cstdio>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+
+// ************************************************************************** //
+// ************** term_attr ************** //
+// ************************************************************************** //
+
+struct term_attr { enum _ {
+ NORMAL = 0,
+ BRIGHT = 1,
+ DIM = 2,
+ UNDERLINE = 4,
+ BLINK = 5,
+ REVERSE = 7,
+ CROSSOUT = 9
+}; };
+
+// ************************************************************************** //
+// ************** term_color ************** //
+// ************************************************************************** //
+
+struct term_color { enum _ {
+ BLACK = 0,
+ RED = 1,
+ GREEN = 2,
+ YELLOW = 3,
+ BLUE = 4,
+ MAGENTA = 5,
+ CYAN = 6,
+ WHITE = 7,
+ ORIGINAL = 9
+}; };
+
+// ************************************************************************** //
+// ************** setcolor ************** //
+// ************************************************************************** //
+
+class setcolor {
+public:
+ // Constructor
+ explicit setcolor( term_attr::_ attr = term_attr::NORMAL,
+ term_color::_ fg = term_color::ORIGINAL,
+ term_color::_ bg = term_color::ORIGINAL )
+ {
+ m_command_size = std::sprintf( m_control_command, "%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40 );
+ }
+
+ friend std::ostream&
+ operator<<( std::ostream& os, setcolor const& sc )
+ {
+ return os.write( sc.m_control_command, sc.m_command_size );
+ }
+
+private:
+ // Data members
+ char m_control_command[13];
+ int m_command_size;
+};
+
+// ************************************************************************** //
+// ************** scope_setcolor ************** //
+// ************************************************************************** //
+
+struct scope_setcolor {
+ scope_setcolor() : m_os( 0 ) {}
+ explicit scope_setcolor( std::ostream& os,
+ term_attr::_ attr = term_attr::NORMAL,
+ term_color::_ fg = term_color::ORIGINAL,
+ term_color::_ bg = term_color::ORIGINAL )
+ : m_os( &os )
+ {
+ os << setcolor( attr, fg, bg );
+ }
+ ~scope_setcolor()
+ {
+ if( m_os )
+ *m_os << setcolor();
+ }
+private:
+ // Data members
+ std::ostream* m_os;
+};
+
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_UTILS_SETCOLOR_HPP
diff --git a/boost/test/utils/trivial_singleton.hpp b/boost/test/utils/trivial_singleton.hpp
index 61cca97e00..818bad73ea 100644
--- a/boost/test/utils/trivial_singleton.hpp
+++ b/boost/test/utils/trivial_singleton.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2005-2008.
+// (C) Copyright Gennadiy Rozental 2005-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -12,20 +12,19 @@
// Description : simple helpers for creating cusom output manipulators
// ***************************************************************************
-#ifndef BOOST_TEST_TRIVIAL_SIGNLETON_HPP_020505GER
-#define BOOST_TEST_TRIVIAL_SIGNLETON_HPP_020505GER
+#ifndef BOOST_TEST_UTILS_TRIVIAL_SIGNLETON_HPP
+#define BOOST_TEST_UTILS_TRIVIAL_SIGNLETON_HPP
+// Boost.Test
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
-#include <boost/noncopyable.hpp>
-
+// Boost
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
// ************************************************************************** //
@@ -33,15 +32,19 @@ namespace unit_test {
// ************************************************************************** //
template<typename Derived>
-class singleton : private boost::noncopyable {
+class singleton {
public:
- static Derived& instance() { static Derived the_inst; return the_inst; }
+ static Derived& instance() { static Derived the_inst; return the_inst; }
+
+ BOOST_DELETED_FUNCTION(singleton(singleton const&))
+ BOOST_DELETED_FUNCTION(singleton& operator=(singleton const&))
+
protected:
- singleton() {}
- ~singleton() {}
+ BOOST_DEFAULTED_FUNCTION(singleton(), {})
+ BOOST_DEFAULTED_FUNCTION(~singleton(), {})
};
-} // namespace unit_test
+//____________________________________________________________________________//
#define BOOST_TEST_SINGLETON_CONS( type ) \
friend class boost::unit_test::singleton<type>; \
@@ -65,10 +68,12 @@ namespace { BOOST_JOIN( inst, _t)& inst = BOOST_JOIN( inst, _t)::instance(); }
#endif
+//____________________________________________________________________________//
+
+} // namespace unit_test
} // namespace boost
-//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_TEST_TRIVIAL_SIGNLETON_HPP_020505GER
+#endif // BOOST_TEST_UTILS_TRIVIAL_SIGNLETON_HPP
diff --git a/boost/test/utils/wrap_stringstream.hpp b/boost/test/utils/wrap_stringstream.hpp
index d1122c8ca8..e42adbd3ad 100644
--- a/boost/test/utils/wrap_stringstream.hpp
+++ b/boost/test/utils/wrap_stringstream.hpp
@@ -1,6 +1,6 @@
-// (C) Copyright Gennadiy Rozental 2002-2008.
+// (C) Copyright Gennadiy Rozental 2002-2014.
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
@@ -13,8 +13,8 @@
// to provide the unified interface
// ***************************************************************************
-#ifndef BOOST_WRAP_STRINGSTREAM_HPP_071894GER
-#define BOOST_WRAP_STRINGSTREAM_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_WRAP_STRINGSTREAM_HPP
+#define BOOST_TEST_UTILS_WRAP_STRINGSTREAM_HPP
// Boost.Test
#include <boost/test/detail/config.hpp>
@@ -81,7 +81,7 @@ basic_wrap_stringstream<CharT>::stream()
template <typename CharT>
inline basic_wrap_stringstream<CharT>&
basic_wrap_stringstream<CharT>::ref()
-{
+{
return *this;
}
@@ -114,7 +114,7 @@ operator<<( basic_wrap_stringstream<CharT>& targ, basic_wrap_stringstream<CharT>
//____________________________________________________________________________//
-#if BOOST_TEST_USE_STD_LOCALE
+#if BOOST_TEST_USE_STD_LOCALE
template <typename CharT>
inline basic_wrap_stringstream<CharT>&
@@ -157,8 +157,6 @@ typedef basic_wrap_stringstream<wchar_t> wrap_wstringstream;
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_WRAP_STRINGSTREAM_HPP_071894GER
+#endif // BOOST_TEST_UTILS_WRAP_STRINGSTREAM_HPP
diff --git a/boost/test/utils/xml_printer.hpp b/boost/test/utils/xml_printer.hpp
index ae73cce105..8552a173f9 100644
--- a/boost/test/utils/xml_printer.hpp
+++ b/boost/test/utils/xml_printer.hpp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2004-2008.
+// (C) Copyright Gennadiy Rozental 2004-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)
@@ -9,11 +9,11 @@
//
// Version : $Revision$
//
-// Description : common code used by any agent serving as XML printer
+// Description : common code used by any agent serving as OF_XML printer
// ***************************************************************************
-#ifndef BOOST_TEST_XML_PRINTER_HPP_071894GER
-#define BOOST_TEST_XML_PRINTER_HPP_071894GER
+#ifndef BOOST_TEST_UTILS_XML_PRINTER_HPP
+#define BOOST_TEST_UTILS_XML_PRINTER_HPP
// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
@@ -33,7 +33,6 @@
//____________________________________________________________________________//
namespace boost {
-
namespace unit_test {
// ************************************************************************** //
@@ -82,6 +81,22 @@ print_escaped( std::ostream& where_to, T const& value )
//____________________________________________________________________________//
+inline void
+print_escaped_cdata( std::ostream& where_to, const_string value )
+{
+ static const_string cdata_end( "]]>" );
+
+ const_string::size_type pos = value.find( cdata_end );
+ if( pos == const_string::npos )
+ where_to << value;
+ else {
+ where_to << value.substr( 0, pos+2 ) << cdata_end
+ << BOOST_TEST_L( "<![CDATA[" ) << value.substr( pos+2 );
+ }
+}
+
+//____________________________________________________________________________//
+
typedef custom_manip<struct attr_value_t> attr_value;
template<typename T>
@@ -102,17 +117,16 @@ typedef custom_manip<struct cdata_t> cdata;
inline std::ostream&
operator<<( custom_printer<cdata> const& p, const_string value )
{
- return *p << BOOST_TEST_L( "<![CDATA[" ) << value << BOOST_TEST_L( "]]>" );
+ *p << BOOST_TEST_L( "<![CDATA[" );
+ print_escaped_cdata( *p, value );
+ return *p << BOOST_TEST_L( "]]>" );
}
//____________________________________________________________________________//
} // namespace unit_test
-
} // namespace boost
-//____________________________________________________________________________//
-
#include <boost/test/detail/enable_warnings.hpp>
-#endif // BOOST_TEST_XML_PRINTER_HPP_071894GER
+#endif // BOOST_TEST_UTILS_XML_PRINTER_HPP
diff --git a/boost/thread/future.hpp b/boost/thread/future.hpp
index e6e22363aa..28239c4aa3 100644
--- a/boost/thread/future.hpp
+++ b/boost/thread/future.hpp
@@ -1363,6 +1363,28 @@ namespace boost
template <class F, class Rp, class Fp>
BOOST_THREAD_FUTURE<Rp>
make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename F, typename Rp, typename Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename F, typename Rp, typename Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ template<typename Ex, typename F, typename Rp, typename Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename Ex, typename F, typename Rp, typename Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template <class Rp, class Fp, class Executor>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
+ #endif
#endif
#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
template<typename F, typename Rp>
@@ -1372,6 +1394,36 @@ namespace boost
make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
#endif
}
+#if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
+ template< typename InputIterator>
+ typename boost::disable_if<is_future_type<InputIterator>,
+ BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
+ >::type
+ when_all(InputIterator first, InputIterator last);
+
+ inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
+
+ #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
+ when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
+ #endif
+
+ template< typename InputIterator>
+ typename boost::disable_if<is_future_type<InputIterator>,
+ BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
+ >::type
+ when_any(InputIterator first, InputIterator last);
+
+ inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
+
+ #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
+ when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
+ #endif
+#endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+
template <typename R>
class BOOST_THREAD_FUTURE : public detail::basic_future<R>
@@ -1395,6 +1447,28 @@ namespace boost
template <class F, class Rp, class Fp>
friend BOOST_THREAD_FUTURE<Rp>
detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ template<typename Ex, typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename Ex, typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template <class Rp, class Fp, class Executor>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
+ #endif
#endif
#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
template<typename F, typename Rp>
@@ -1403,6 +1477,35 @@ namespace boost
friend BOOST_THREAD_FUTURE<Rp>
detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
#endif
+#if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
+ template< typename InputIterator>
+ friend typename boost::disable_if<is_future_type<InputIterator>,
+ BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
+ >::type
+ when_all(InputIterator first, InputIterator last);
+
+ //friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
+
+ #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
+ when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
+ #endif
+
+ template< typename InputIterator>
+ friend typename boost::disable_if<is_future_type<InputIterator>,
+ BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
+ >::type
+ when_any(InputIterator first, InputIterator last);
+
+ //friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
+
+ #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
+ when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
+ #endif
+#endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
template <class> friend class packaged_task; // todo check if this works in windows
#else
@@ -1418,9 +1521,7 @@ namespace boost
friend BOOST_THREAD_FUTURE<Rp>
detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
-
typedef typename base_type::move_dest_type move_dest_type;
- public: // when_all
BOOST_THREAD_FUTURE(future_ptr a_future):
base_type(a_future)
@@ -1588,7 +1689,7 @@ namespace boost
friend class shared_future<R>;
friend class promise<R>;
- #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
template <typename, typename, typename>
friend struct detail::future_async_continuation_shared_state;
template <typename, typename, typename>
@@ -1601,7 +1702,30 @@ namespace boost
template <class F, class Rp, class Fp>
friend BOOST_THREAD_FUTURE<Rp>
detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
- #endif
+
+ template<typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ template<typename Ex, typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename Ex, typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template <class Rp, class Fp, class Executor>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
+ #endif
+
+#endif
#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
template<typename F, typename Rp>
friend struct detail::future_unwrap_shared_state;
@@ -1609,6 +1733,36 @@ namespace boost
friend BOOST_THREAD_FUTURE<Rp>
detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
#endif
+#if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
+ template< typename InputIterator>
+ friend typename boost::disable_if<is_future_type<InputIterator>,
+ BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
+ >::type
+ when_all(InputIterator first, InputIterator last);
+
+ friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
+
+ #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
+ when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
+ #endif
+
+ template< typename InputIterator>
+ friend typename boost::disable_if<is_future_type<InputIterator>,
+ BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
+ >::type
+ when_any(InputIterator first, InputIterator last);
+
+ friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
+
+ #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
+ when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
+ #endif
+#endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
template <class> friend class packaged_task; // todo check if this works in windows
#else
@@ -1630,8 +1784,8 @@ namespace boost
base_type(a_future)
{
}
-
public:
+
BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
typedef future_state::state state;
typedef R value_type; // EXTENSION
diff --git a/boost/thread/win32/thread_primitives.hpp b/boost/thread/win32/thread_primitives.hpp
index d9f63e6cf4..d0d4f0aec3 100644
--- a/boost/thread/win32/thread_primitives.hpp
+++ b/boost/thread/win32/thread_primitives.hpp
@@ -35,6 +35,7 @@ namespace boost
typedef HANDLE handle;
typedef SYSTEM_INFO system_info;
typedef unsigned __int64 ticks_type;
+ typedef FARPROC farproc_t;
unsigned const infinite=INFINITE;
unsigned const timeout=WAIT_TIMEOUT;
handle const invalid_handle_value=INVALID_HANDLE_VALUE;
@@ -58,17 +59,20 @@ namespace boost
using ::CreateSemaphoreExW;
# endif
using ::OpenEventW;
+ using ::GetModuleGandleW;
# else
using ::CreateMutexA;
using ::CreateEventA;
using ::OpenEventA;
using ::CreateSemaphoreA;
+ using ::GetModuleHandleA;
# endif
#if BOOST_PLAT_WINDOWS_RUNTIME
using ::GetNativeSystemInfo;
using ::GetTickCount64;
#else
using ::GetSystemInfo;
+ using ::GetTickCount;
#endif
using ::CloseHandle;
using ::ReleaseMutex;
@@ -86,6 +90,7 @@ namespace boost
using ::SleepEx;
using ::Sleep;
using ::QueueUserAPC;
+ using ::GetProcAddress;
#endif
}
}
@@ -135,6 +140,7 @@ namespace boost
typedef void* handle;
typedef _SYSTEM_INFO system_info;
typedef unsigned __int64 ticks_type;
+ typedef int (__stdcall *farproc_t)();
unsigned const infinite=~0U;
unsigned const timeout=258U;
handle const invalid_handle_value=(handle)(-1);
@@ -160,17 +166,20 @@ namespace boost
__declspec(dllimport) void* __stdcall CreateSemaphoreExW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*,unsigned long,unsigned long);
# endif
__declspec(dllimport) void* __stdcall OpenEventW(unsigned long,int,wchar_t const*);
+ __declspec(dllimport) void* __stdcall GetModuleHandleW(wchar_t const*);
# else
__declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*);
__declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*);
__declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*);
__declspec(dllimport) void* __stdcall OpenEventA(unsigned long,int,char const*);
+ __declspec(dllimport) void* __stdcall GetModuleHandleA(char const*);
# endif
#if BOOST_PLAT_WINDOWS_RUNTIME
__declspec(dllimport) void __stdcall GetNativeSystemInfo(_SYSTEM_INFO*);
__declspec(dllimport) ticks_type __stdcall GetTickCount64();
#else
__declspec(dllimport) void __stdcall GetSystemInfo(_SYSTEM_INFO*);
+ __declspec(dllimport) unsigned long __stdcall GetTickCount();
#endif
__declspec(dllimport) int __stdcall CloseHandle(void*);
__declspec(dllimport) int __stdcall ReleaseMutex(void*);
@@ -183,6 +192,7 @@ namespace boost
__declspec(dllimport) void __stdcall Sleep(unsigned long);
typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr);
__declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr);
+ __declspec(dllimport) farproc_t __stdcall GetProcAddress(void *, const char *);
#endif
# ifndef UNDER_CE
@@ -216,17 +226,10 @@ namespace boost
{
namespace win32
{
- namespace detail { typedef int (__stdcall *farproc_t)(); typedef ticks_type (__stdcall *gettickcount64_t)(); }
+ namespace detail { typedef ticks_type (__stdcall *gettickcount64_t)(); }
#if !BOOST_PLAT_WINDOWS_RUNTIME
extern "C"
{
- __declspec(dllimport) detail::farproc_t __stdcall GetProcAddress(void *, const char *);
-#if !defined(BOOST_NO_ANSI_APIS)
- __declspec(dllimport) void * __stdcall GetModuleHandleA(const char *);
-#else
- __declspec(dllimport) void * __stdcall GetModuleHandleW(const wchar_t *);
-#endif
- __declspec(dllimport) unsigned long __stdcall GetTickCount();
#ifdef _MSC_VER
long _InterlockedCompareExchange(long volatile *, long, long);
#pragma intrinsic(_InterlockedCompareExchange)
@@ -285,6 +288,7 @@ namespace boost
// Oops, we weren't called often enough, we're stuck
return 0xFFFFFFFF;
}
+#else
#endif
inline detail::gettickcount64_t GetTickCount64_()
{
@@ -297,7 +301,7 @@ namespace boost
#if BOOST_PLAT_WINDOWS_RUNTIME
gettickcount64impl = &GetTickCount64;
#else
- detail::farproc_t addr=GetProcAddress(
+ farproc_t addr=GetProcAddress(
#if !defined(BOOST_NO_ANSI_APIS)
GetModuleHandleA("KERNEL32.DLL"),
#else
diff --git a/boost/type_index/detail/compile_time_type_info.hpp b/boost/type_index/detail/compile_time_type_info.hpp
index c68f385d19..635b45d67c 100644
--- a/boost/type_index/detail/compile_time_type_info.hpp
+++ b/boost/type_index/detail/compile_time_type_info.hpp
@@ -42,28 +42,28 @@
#elif defined(_MSC_VER)
// sizeof("const char *__cdecl boost::detail::ctti<") - 1, sizeof(">::n(void)") - 1
- BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 10, false, "");
+ BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 10, false, "")
#elif defined(__clang__) && defined(__APPLE__)
// Someone made __clang_major__ equal to LLVM version rather than compiler version
// on APPLE platform.
//
// Using less efficient solution because there is no good way to detect real version of Clang.
// sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "???????????>::n() [T = int"
- BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ");
+ BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ")
#elif defined(__clang__) && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ == 0))
// sizeof("static const char *boost::detail::ctti<") - 1, sizeof(">::n()") - 1
// note: checked on 3.0
- BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 6, false, "");
+ BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 6, false, "")
#elif defined(__clang__) && __clang_major__ == 3 && __clang_minor__ > 0
// sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "int>::n() [T = int"
// note: checked on 3.1, 3.4
- BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ");
+ BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ")
#elif defined(__GNUC__)
// sizeof("static const char* boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
- BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "");
+ BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
#else
// Deafult code for other platforms... Just skip nothing!
- BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(0, 0, false, "");
+ BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(0, 0, false, "")
#endif
#undef BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS
diff --git a/boost/type_index/stl_type_index.hpp b/boost/type_index/stl_type_index.hpp
index 1b3b0c4c80..c801e70f62 100644
--- a/boost/type_index/stl_type_index.hpp
+++ b/boost/type_index/stl_type_index.hpp
@@ -39,7 +39,6 @@
#include <boost/type_traits/remove_reference.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/or.hpp>
-#include <boost/functional/hash_fwd.hpp>
#if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
diff --git a/boost/type_index/type_index_facade.hpp b/boost/type_index/type_index_facade.hpp
index c18ea4bada..931dedca25 100644
--- a/boost/type_index/type_index_facade.hpp
+++ b/boost/type_index/type_index_facade.hpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) Antony Polukhin, 2013-2014.
+// Copyright (c) Antony Polukhin, 2013-2015.
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -10,7 +10,6 @@
#define BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
#include <boost/config.hpp>
-#include <boost/functional/hash_fwd.hpp>
#include <string>
#include <cstring>
@@ -26,6 +25,11 @@
# pragma once
#endif
+// Forward declaration from #include <boost/functional/hash_fwd.hpp>
+namespace boost {
+ template <class It> std::size_t hash_range(It, It);
+}
+
namespace boost { namespace typeindex {
/// \class type_index_facade
@@ -101,8 +105,8 @@ public:
/// \return Hash code of a type. By default hashes types by raw_name().
/// \note <boost/functional/hash.hpp> has to be included if this function is used.
inline std::size_t hash_code() const BOOST_NOEXCEPT {
- const char* const name = derived().raw_name();
- return boost::hash_range(name, name + std::strlen(name));
+ const char* const name_raw = derived().raw_name();
+ return boost::hash_range(name_raw, name_raw + std::strlen(name_raw));
}
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
diff --git a/boost/type_traits/is_virtual_base_of.hpp b/boost/type_traits/is_virtual_base_of.hpp
index 33db914d34..3daad1b51b 100644
--- a/boost/type_traits/is_virtual_base_of.hpp
+++ b/boost/type_traits/is_virtual_base_of.hpp
@@ -36,6 +36,17 @@ struct is_virtual_base_of_impl
template<typename Base, typename Derived>
struct is_virtual_base_of_impl<Base, Derived, mpl::true_>
{
+ union max_align
+ {
+ unsigned u;
+ unsigned long ul;
+ void* v;
+ double d;
+ long double ld;
+#ifndef BOOST_NO_LONG_LONG
+ long long ll;
+#endif
+ };
#ifdef __BORLANDC__
struct boost_type_traits_internal_struct_X : public virtual Derived, public virtual Base
{
@@ -43,6 +54,7 @@ struct is_virtual_base_of_impl<Base, Derived, mpl::true_>
boost_type_traits_internal_struct_X(const boost_type_traits_internal_struct_X&);
boost_type_traits_internal_struct_X& operator=(const boost_type_traits_internal_struct_X&);
~boost_type_traits_internal_struct_X()throw();
+ max_align data[4];
};
struct boost_type_traits_internal_struct_Y : public virtual Derived
{
@@ -50,6 +62,7 @@ struct is_virtual_base_of_impl<Base, Derived, mpl::true_>
boost_type_traits_internal_struct_Y(const boost_type_traits_internal_struct_Y&);
boost_type_traits_internal_struct_Y& operator=(const boost_type_traits_internal_struct_Y&);
~boost_type_traits_internal_struct_Y()throw();
+ max_align data[4];
};
#else
struct boost_type_traits_internal_struct_X : public Derived, virtual Base
@@ -58,6 +71,7 @@ struct is_virtual_base_of_impl<Base, Derived, mpl::true_>
boost_type_traits_internal_struct_X(const boost_type_traits_internal_struct_X&);
boost_type_traits_internal_struct_X& operator=(const boost_type_traits_internal_struct_X&);
~boost_type_traits_internal_struct_X()throw();
+ max_align data[16];
};
struct boost_type_traits_internal_struct_Y : public Derived
{
@@ -65,6 +79,7 @@ struct is_virtual_base_of_impl<Base, Derived, mpl::true_>
boost_type_traits_internal_struct_Y(const boost_type_traits_internal_struct_Y&);
boost_type_traits_internal_struct_Y& operator=(const boost_type_traits_internal_struct_Y&);
~boost_type_traits_internal_struct_Y()throw();
+ max_align data[16];
};
#endif
BOOST_STATIC_CONSTANT(bool, value = (sizeof(boost_type_traits_internal_struct_X)==sizeof(boost_type_traits_internal_struct_Y)));
diff --git a/boost/units/scaled_base_unit.hpp b/boost/units/scaled_base_unit.hpp
index 201de5e85d..24f9f4f6b6 100644
--- a/boost/units/scaled_base_unit.hpp
+++ b/boost/units/scaled_base_unit.hpp
@@ -16,8 +16,6 @@
#include <boost/mpl/bool.hpp>
#include <boost/mpl/less.hpp>
#include <boost/type_traits/is_same.hpp>
-#include <boost/type_traits/detail/ice_and.hpp>
-#include <boost/type_traits/detail/ice_or.hpp>
#include <boost/units/config.hpp>
#include <boost/units/dimension.hpp>
@@ -110,8 +108,8 @@ struct less_impl<boost::units::scaled_base_unit_tag, Tag>
{
template<class T0, class T1>
struct apply : mpl::bool_<
- boost::type_traits::ice_or<(mpl::less<typename T0::system_type, T1>::value),
- (boost::type_traits::ice_and<boost::is_same<typename T0::system_type, T1>::value, (T0::scale_type::exponent::Numerator) < 0>::value)>::value> {};
+ mpl::less<typename T0::system_type, T1>::value ||
+ (boost::is_same<typename T0::system_type, T1>::value && ((T0::scale_type::exponent::Numerator) < 0)) > {};
};
/// INTERNAL ONLY
@@ -120,8 +118,8 @@ struct less_impl<Tag, boost::units::scaled_base_unit_tag>
{
template<class T0, class T1>
struct apply : mpl::bool_<
- boost::type_traits::ice_or<(mpl::less<T0, typename T1::system_type>::value),
- boost::type_traits::ice_and<(boost::is_same<T0, typename T1::system_type>::value), ((T1::scale_type::exponent::Numerator) > 0)>::value>::value> {};
+ mpl::less<T0, typename T1::system_type>::value ||
+ (boost::is_same<T0, typename T1::system_type>::value && ((T1::scale_type::exponent::Numerator) > 0)) > {};
};
/// INTERNAL ONLY
@@ -130,11 +128,11 @@ struct less_impl<boost::units::scaled_base_unit_tag, boost::units::scaled_base_u
{
template<class T0, class T1>
struct apply : mpl::bool_<
- boost::type_traits::ice_or<(mpl::less<typename T0::system_type, typename T1::system_type>::value),
- boost::type_traits::ice_and<(boost::is_same<typename T0::system_type, typename T1::system_type>::value),
- boost::type_traits::ice_or<((T0::scale_type::base) < (T1::scale_type::base)),
- boost::type_traits::ice_and<((T0::scale_type::base) == (T1::scale_type::base)),
- (mpl::less<typename T0::scale_type::exponent,typename T1::scale_type::exponent>::value)>::value>::value>::value>::value> {};
+ mpl::less<typename T0::system_type, typename T1::system_type>::value ||
+ ((boost::is_same<typename T0::system_type, typename T1::system_type>::value) &&
+ ((T0::scale_type::base) < (T1::scale_type::base) ||
+ ((T0::scale_type::base) == (T1::scale_type::base) &&
+ mpl::less<typename T0::scale_type::exponent, typename T1::scale_type::exponent>::value))) > {};
};
} // namespace mpl
diff --git a/boost/uuid/detail/uuid_x86.hpp b/boost/uuid/detail/uuid_x86.hpp
index 1a329b02cc..5b573aac15 100644
--- a/boost/uuid/detail/uuid_x86.hpp
+++ b/boost/uuid/detail/uuid_x86.hpp
@@ -39,7 +39,7 @@ BOOST_FORCEINLINE __m128i load_unaligned_si128(const uint8_t* p) BOOST_NOEXCEPT
inline bool uuid::is_nil() const BOOST_NOEXCEPT
{
- register __m128i mm = uuids::detail::load_unaligned_si128(data);
+ __m128i mm = uuids::detail::load_unaligned_si128(data);
#if defined(BOOST_UUID_USE_SSE41)
return _mm_test_all_zeros(mm, mm) != 0;
#else
@@ -50,18 +50,18 @@ inline bool uuid::is_nil() const BOOST_NOEXCEPT
inline void uuid::swap(uuid& rhs) BOOST_NOEXCEPT
{
- register __m128i mm_this = uuids::detail::load_unaligned_si128(data);
- register __m128i mm_rhs = uuids::detail::load_unaligned_si128(rhs.data);
+ __m128i mm_this = uuids::detail::load_unaligned_si128(data);
+ __m128i mm_rhs = uuids::detail::load_unaligned_si128(rhs.data);
_mm_storeu_si128(reinterpret_cast< __m128i* >(rhs.data), mm_this);
_mm_storeu_si128(reinterpret_cast< __m128i* >(data), mm_rhs);
}
inline bool operator== (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
- register __m128i mm_left = uuids::detail::load_unaligned_si128(lhs.data);
- register __m128i mm_right = uuids::detail::load_unaligned_si128(rhs.data);
+ __m128i mm_left = uuids::detail::load_unaligned_si128(lhs.data);
+ __m128i mm_right = uuids::detail::load_unaligned_si128(rhs.data);
- register __m128i mm_cmp = _mm_cmpeq_epi32(mm_left, mm_right);
+ __m128i mm_cmp = _mm_cmpeq_epi32(mm_left, mm_right);
#if defined(BOOST_UUID_USE_SSE41)
return _mm_test_all_ones(mm_cmp);
#else
@@ -71,8 +71,8 @@ inline bool operator== (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
inline bool operator< (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
- register __m128i mm_left = uuids::detail::load_unaligned_si128(lhs.data);
- register __m128i mm_right = uuids::detail::load_unaligned_si128(rhs.data);
+ __m128i mm_left = uuids::detail::load_unaligned_si128(lhs.data);
+ __m128i mm_right = uuids::detail::load_unaligned_si128(rhs.data);
// To emulate lexicographical_compare behavior we have to perform two comparisons - the forward and reverse one.
// Then we know which bytes are equivalent and which ones are different, and for those different the comparison results
@@ -100,7 +100,7 @@ inline bool operator< (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
cmp = (cmp - 1u) ^ cmp;
rcmp = (rcmp - 1u) ^ rcmp;
- return static_cast< uint16_t >(cmp) < static_cast< uint16_t >(rcmp);
+ return cmp < rcmp;
}
} // namespace uuids
diff --git a/boost/uuid/seed_rng.hpp b/boost/uuid/seed_rng.hpp
index 97b505f852..877e4ebb20 100644
--- a/boost/uuid/seed_rng.hpp
+++ b/boost/uuid/seed_rng.hpp
@@ -9,6 +9,7 @@
// 09 Nov 2007 - Initial Revision
// 25 Feb 2008 - moved to namespace boost::uuids::detail
// 28 Nov 2009 - disabled deprecated warnings for MSVC
+// 28 Jul 2014 - fixed valgrind warnings and better entropy sources for MSVC
// seed_rng models a UniformRandomNumberGenerator (see Boost.Random).
// Random number generators are hard to seed well. This is intended to provide
@@ -27,6 +28,7 @@
#include <ctime> // for time_t, time, clock_t, clock
#include <cstdlib> // for rand
#include <cstdio> // for FILE, fopen, fread, fclose
+#include <boost/core/noncopyable.hpp>
#include <boost/uuid/sha1.hpp>
//#include <boost/nondet_random.hpp> //forward declare boost::random::random_device
@@ -36,8 +38,17 @@
# include <boost/iterator/iterator_facade.hpp>
#if defined(_MSC_VER)
-#pragma warning(push) // Save warning settings.
-#pragma warning(disable : 4996) // Disable deprecated std::fopen
+# pragma warning(push) // Save warning settings.
+# pragma warning(disable : 4996) // Disable deprecated std::fopen
+# include <boost/detail/winapi/crypt.hpp> // for CryptAcquireContextA, CryptGenRandom, CryptReleaseContext
+# include <boost/detail/winapi/timers.hpp>
+# include <boost/detail/winapi/process.hpp>
+# include <boost/detail/winapi/thread.hpp>
+# pragma comment(lib, "advapi32.lib")
+#else
+# include <sys/time.h> // for gettimeofday
+# include <sys/types.h> // for pid_t
+# include <unistd.h> // for getpid()
#endif
#ifdef BOOST_NO_STDC_NAMESPACE
@@ -65,33 +76,51 @@ namespace uuids {
namespace detail {
// should this be part of Boost.Random?
-class seed_rng
+class seed_rng: private boost::noncopyable
{
public:
typedef unsigned int result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
- //BOOST_STATIC_CONSTANT(unsigned int, min_value = 0);
- //BOOST_STATIC_CONSTANT(unsigned int, max_value = UINT_MAX);
public:
// note: rd_ intentionally left uninitialized
- seed_rng()
+ seed_rng() BOOST_NOEXCEPT
: rd_index_(5)
- , random_(std::fopen( "/dev/urandom", "rb" ))
- {}
+ , random_(NULL)
+ {
+#if defined(BOOST_WINDOWS)
+ if (!boost::detail::winapi::CryptAcquireContextA(
+ &random_,
+ NULL,
+ NULL,
+ boost::detail::winapi::PROV_RSA_FULL_,
+ boost::detail::winapi::CRYPT_VERIFYCONTEXT_ | boost::detail::winapi::CRYPT_SILENT_))
+ {
+ random_ = NULL;
+ }
+#else
+ random_ = std::fopen( "/dev/urandom", "rb" );
+#endif
- ~seed_rng()
+ std::memset(rd_, 0, sizeof(rd_));
+ }
+
+ ~seed_rng() BOOST_NOEXCEPT
{
if (random_) {
+#if defined(BOOST_WINDOWS)
+ boost::detail::winapi::CryptReleaseContext(random_, 0);
+#else
std::fclose(random_);
+#endif
}
}
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const BOOST_NOEXCEPT
{
return (std::numeric_limits<result_type>::min)();
}
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const
+ result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const BOOST_NOEXCEPT
{
return (std::numeric_limits<result_type>::max)();
}
@@ -109,11 +138,12 @@ public:
}
private:
+ BOOST_STATIC_CONSTANT(std::size_t, internal_state_size = 5);
inline void ignore_size(size_t) {}
static unsigned int * sha1_random_digest_state_()
{
- static unsigned int state[ 5 ];
+ static unsigned int state[ internal_state_size ];
return state;
}
@@ -121,19 +151,50 @@ private:
{
boost::uuids::detail::sha1 sha;
- unsigned int * ps = sha1_random_digest_state_();
-
- unsigned int state[ 5 ];
- std::memcpy( state, ps, sizeof( state ) ); // harmless data race
- sha.process_bytes( (unsigned char const*)state, sizeof( state ) );
- sha.process_bytes( (unsigned char const*)&ps, sizeof( ps ) );
+ if (random_)
+ {
+ // intentionally left uninitialized
+ unsigned char state[ 20 ];
+#if defined(BOOST_WINDOWS)
+ boost::detail::winapi::CryptGenRandom(random_, sizeof(state), state);
+#else
+ ignore_size(std::fread( state, 1, sizeof(state), random_ ));
+#endif
+ sha.process_bytes( state, sizeof( state ) );
+ }
{
+ // Getting enropy from some system specific sources
+#if defined(BOOST_WINDOWS)
+ boost::detail::winapi::DWORD_ procid = boost::detail::winapi::GetCurrentProcessId();
+ sha.process_bytes( (unsigned char const*)&procid, sizeof( procid ) );
+
+ boost::detail::winapi::DWORD_ threadid = boost::detail::winapi::GetCurrentThreadId();
+ sha.process_bytes( (unsigned char const*)&threadid, sizeof( threadid ) );
+
+ boost::detail::winapi::LARGE_INTEGER_ ts;
+ ts.QuadPart = 0;
+ boost::detail::winapi::QueryPerformanceCounter( &ts );
+ sha.process_bytes( (unsigned char const*)&ts, sizeof( ts ) );
+
std::time_t tm = std::time( 0 );
sha.process_bytes( (unsigned char const*)&tm, sizeof( tm ) );
+#else
+ pid_t pid = getpid();
+ sha.process_bytes( (unsigned char const*)&pid, sizeof( pid ) );
+
+ timeval ts;
+ gettimeofday(&ts, NULL); // We do not use `clock_gettime` to avoid linkage with -lrt
+ sha.process_bytes( (unsigned char const*)&ts, sizeof( ts ) );
+#endif
}
+
+ unsigned int * ps = sha1_random_digest_state_();
+ sha.process_bytes( ps, internal_state_size * sizeof( unsigned int ) );
+ sha.process_bytes( (unsigned char const*)&ps, sizeof( ps ) );
+
{
std::clock_t ck = std::clock();
sha.process_bytes( (unsigned char const*)&ck, sizeof( ck ) );
@@ -149,27 +210,13 @@ private:
}
{
- // intentionally left uninitialized
- unsigned char buffer[ 20 ];
-
- if(random_)
- {
- ignore_size(std::fread( buffer, 1, 20, random_ ));
- }
-
- // using an uninitialized buffer[] if fopen fails
- // intentional, we rely on its contents being random
- sha.process_bytes( buffer, sizeof( buffer ) );
- }
-
- {
- // *p is intentionally left uninitialized
unsigned int * p = new unsigned int;
-
- sha.process_bytes( (unsigned char const*)p, sizeof( *p ) );
sha.process_bytes( (unsigned char const*)&p, sizeof( p ) );
-
delete p;
+
+ const seed_rng* this_ptr = this;
+ sha.process_bytes( (unsigned char const*)&this_ptr, sizeof( this_ptr ) );
+ sha.process_bytes( (unsigned char const*)&std::rand, sizeof( void(*)() ) );
}
sha.process_bytes( (unsigned char const*)rd_, sizeof( rd_ ) );
@@ -188,11 +235,12 @@ private:
private:
unsigned int rd_[5];
int rd_index_;
- std::FILE * random_;
-private: // make seed_rng noncopyable
- seed_rng(seed_rng const&);
- seed_rng& operator=(seed_rng const&);
+#if defined(BOOST_WINDOWS)
+ boost::detail::winapi::HCRYPTPROV_ random_;
+#else
+ std::FILE * random_;
+#endif
};
// almost a copy of boost::generator_iterator
diff --git a/boost/variant/detail/element_index.hpp b/boost/variant/detail/element_index.hpp
index bd80bdd15c..8ea92ecc5e 100644
--- a/boost/variant/detail/element_index.hpp
+++ b/boost/variant/detail/element_index.hpp
@@ -16,6 +16,8 @@
#include "boost/variant/recursive_wrapper_fwd.hpp"
#include "boost/variant/variant_fwd.hpp"
+#include "boost/type_traits/remove_cv.hpp"
+#include "boost/type_traits/remove_reference.hpp"
#include "boost/mpl/find_if.hpp"
namespace boost { namespace detail { namespace variant {
@@ -42,7 +44,7 @@ struct element_iterator_impl :
template <class Variant, class T>
struct element_iterator :
- element_iterator_impl< typename Variant::types, T>
+ element_iterator_impl< typename Variant::types, typename boost::remove_reference<T>::type >
{};
template <class Variant, class T>
diff --git a/boost/variant/detail/has_result_type.hpp b/boost/variant/detail/has_result_type.hpp
index d3a78b1937..8ec3d361ee 100644
--- a/boost/variant/detail/has_result_type.hpp
+++ b/boost/variant/detail/has_result_type.hpp
@@ -3,7 +3,7 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
-// Copyright (c) 2014 Antony Polukhin
+// Copyright (c) 2014-2015 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,6 +13,7 @@
#define BOOST_VARIANT_DETAIL_HAS_RESULT_TYPE_HPP
#include "boost/config.hpp"
+#include "boost/type_traits/remove_reference.hpp"
namespace boost { namespace detail { namespace variant {
@@ -23,7 +24,7 @@ private:
typedef char yes;
typedef struct { char array[2]; } no;
- template<typename C> static yes test(typename C::result_type*);
+ template<typename C> static yes test(typename boost::remove_reference<typename C::result_type>::type*);
template<typename C> static no test(...);
public:
diff --git a/boost/variant/polymorphic_get.hpp b/boost/variant/polymorphic_get.hpp
index 36ca386800..05d9b0dcc8 100644
--- a/boost/variant/polymorphic_get.hpp
+++ b/boost/variant/polymorphic_get.hpp
@@ -77,7 +77,7 @@ struct holds_element_polymorphic :
boost::mpl::not_<
boost::is_same<
typename boost::mpl::end<typename Variant::types>::type,
- typename element_polymorphic_iterator_impl<typename Variant::types, T>::type
+ typename element_polymorphic_iterator_impl<typename Variant::types, typename boost::remove_reference<T>::type >::type
>
>
{};
diff --git a/boost/variant/recursive_wrapper_fwd.hpp b/boost/variant/recursive_wrapper_fwd.hpp
index cf0395920b..b46774d92c 100644
--- a/boost/variant/recursive_wrapper_fwd.hpp
+++ b/boost/variant/recursive_wrapper_fwd.hpp
@@ -16,11 +16,8 @@
#define BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP
#include "boost/mpl/aux_/config/ctps.hpp"
-
#include "boost/mpl/aux_/lambda_support.hpp"
-
-// should be the last #include
-#include "boost/type_traits/detail/bool_trait_def.hpp"
+#include <boost/type_traits/integral_constant.hpp>
namespace boost {
@@ -66,11 +63,12 @@ struct is_recursive_wrapper_impl< recursive_wrapper<T> >
} // namespace detail
-BOOST_TT_AUX_BOOL_TRAIT_DEF1(
- is_recursive_wrapper
- , T
- , (::boost::detail::is_recursive_wrapper_impl<T>::value)
- )
+template< typename T > struct is_recursive_wrapper
+ : public ::boost::integral_constant<bool,(::boost::detail::is_recursive_wrapper_impl<T>::value)>
+{
+public:
+ BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_recursive_wrapper,(T))
+};
///////////////////////////////////////////////////////////////////////////////
// metafunction unwrap_recursive
@@ -98,6 +96,4 @@ struct unwrap_recursive< recursive_wrapper<T> >
} // namespace boost
-#include "boost/type_traits/detail/bool_trait_undef.hpp"
-
#endif // BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP
diff --git a/boost/variant/static_visitor.hpp b/boost/variant/static_visitor.hpp
index 492d34f5df..27f56747ef 100644
--- a/boost/variant/static_visitor.hpp
+++ b/boost/variant/static_visitor.hpp
@@ -19,8 +19,8 @@
#include "boost/mpl/if.hpp"
#include "boost/type_traits/is_base_and_derived.hpp"
-// should be the last #include
-#include "boost/type_traits/detail/bool_trait_def.hpp"
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
namespace boost {
@@ -83,14 +83,13 @@ struct is_static_visitor_impl
} // namespace detail
-BOOST_TT_AUX_BOOL_TRAIT_DEF1(
- is_static_visitor
- , T
- , (::boost::detail::is_static_visitor_impl<T>::value)
- )
+template< typename T > struct is_static_visitor
+ : public ::boost::integral_constant<bool,(::boost::detail::is_static_visitor_impl<T>::value)>
+{
+public:
+ BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_static_visitor,(T))
+};
} // namespace boost
-#include "boost/type_traits/detail/bool_trait_undef.hpp"
-
#endif // BOOST_VARIANT_STATIC_VISITOR_HPP
diff --git a/boost/version.hpp b/boost/version.hpp
index ece5fe6e51..7b64aedb1b 100644
--- a/boost/version.hpp
+++ b/boost/version.hpp
@@ -19,7 +19,7 @@
// BOOST_VERSION / 100 % 1000 is the minor version
// BOOST_VERSION / 100000 is the major version
-#define BOOST_VERSION 105800
+#define BOOST_VERSION 105900
//
// BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION
@@ -27,6 +27,6 @@
// number, y is the minor version number, and z is the patch level if not 0.
// This is used by <config/auto_link.hpp> to select which library version to link to.
-#define BOOST_LIB_VERSION "1_58"
+#define BOOST_LIB_VERSION "1_59"
#endif
diff --git a/boost/wave/cpp_exceptions.hpp b/boost/wave/cpp_exceptions.hpp
index 805e56fc22..e2cc933953 100644
--- a/boost/wave/cpp_exceptions.hpp
+++ b/boost/wave/cpp_exceptions.hpp
@@ -155,7 +155,7 @@ public:
code(code)
{
unsigned int off = 0;
- while (off < sizeof(buffer) && *what_)
+ while (off < sizeof(buffer) - 1 && *what_)
buffer[off++] = *what_++;
buffer[off] = 0;
}