From dfb313f8357b8f6601fa7420be1a39a51ba86f77 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Sun, 5 Nov 2023 02:44:27 +0200 Subject: [PATCH] boost: Readd and adjust libraries * Add back variant. Turns out dynarmic needs this * Explicitely add circular_buffer. We rely on this but it was removed previously * Trim down url and iostreams libraries to what we need --- boost/blank.hpp | 106 + boost/blank_fwd.hpp | 22 + boost/checked_delete.hpp | 17 - boost/circular_buffer.hpp | 65 + boost/circular_buffer/base.hpp | 3134 +++++++++++++++++ boost/circular_buffer/debug.hpp | 248 ++ boost/circular_buffer/details.hpp | 491 +++ boost/circular_buffer/space_optimized.hpp | 1713 +++++++++ boost/circular_buffer_fwd.hpp | 43 + boost/detail/templated_streams.hpp | 74 + boost/integer/common_factor_ct.hpp | 102 + boost/integer/integer_log2.hpp | 117 - boost/integer/integer_mask.hpp | 134 - boost/integer/static_log2.hpp | 126 - boost/iostreams/chain.hpp | 594 ---- boost/iostreams/code_converter.hpp | 417 --- boost/iostreams/combine.hpp | 260 -- boost/iostreams/compose.hpp | 493 --- boost/iostreams/copy.hpp | 248 -- boost/iostreams/detail/absolute_path.hpp | 46 - boost/iostreams/detail/access_control.hpp | 87 - .../detail/adapter/device_adapter.hpp | 67 - .../detail/adapter/direct_adapter.hpp | 282 -- .../detail/adapter/filter_adapter.hpp | 69 - boost/iostreams/detail/add_facet.hpp | 49 - boost/iostreams/detail/codecvt_helper.hpp | 214 -- boost/iostreams/detail/codecvt_holder.hpp | 63 - boost/iostreams/detail/counted_array.hpp | 74 - boost/iostreams/detail/current_directory.hpp | 65 - boost/iostreams/detail/fstream.hpp | 33 - boost/iostreams/detail/newline.hpp | 32 - boost/iostreams/detail/param_type.hpp | 27 - boost/iostreams/detail/restrict_impl.hpp | 483 --- boost/iostreams/detail/streambuf/chainbuf.hpp | 113 - boost/iostreams/detail/translate_int_type.hpp | 62 - boost/iostreams/device/file.hpp | 191 - boost/iostreams/filter/aggregate.hpp | 168 - boost/iostreams/filter/counter.hpp | 82 - boost/iostreams/filter/grep.hpp | 109 - boost/iostreams/filter/line.hpp | 221 -- boost/iostreams/filter/newline.hpp | 443 --- boost/iostreams/filter/regex.hpp | 98 - boost/iostreams/filter/stdio.hpp | 84 - boost/iostreams/filter/test.hpp | 319 -- boost/iostreams/filtering_stream.hpp | 187 - boost/iostreams/filtering_streambuf.hpp | 70 - boost/iostreams/invert.hpp | 167 - boost/iostreams/restrict.hpp | 26 - boost/iostreams/skip.hpp | 112 - boost/iostreams/slice.hpp | 28 - boost/iostreams/tee.hpp | 232 -- boost/mpl/O1_size.hpp | 40 + boost/mpl/O1_size_fwd.hpp | 24 + boost/mpl/advance.hpp | 76 + boost/mpl/advance_fwd.hpp | 28 + boost/mpl/aux_/O1_size_impl.hpp | 87 + boost/mpl/aux_/advance_backward.hpp | 128 + boost/mpl/aux_/advance_forward.hpp | 127 + boost/mpl/aux_/begin_end_impl.hpp | 101 + boost/mpl/aux_/clear_impl.hpp | 35 + boost/mpl/aux_/empty_impl.hpp | 43 + boost/mpl/aux_/find_if_pred.hpp | 31 + boost/mpl/aux_/fold_impl.hpp | 43 + boost/mpl/aux_/fold_impl_body.hpp | 365 ++ boost/mpl/aux_/front_impl.hpp | 41 + boost/mpl/aux_/has_begin.hpp | 23 + boost/mpl/aux_/has_size.hpp | 23 + boost/mpl/aux_/insert_impl.hpp | 68 + boost/mpl/aux_/insert_range_impl.hpp | 80 + boost/mpl/aux_/inserter_algorithm.hpp | 159 + boost/mpl/aux_/iter_apply.hpp | 47 + boost/mpl/aux_/iter_fold_if_impl.hpp | 210 ++ boost/mpl/aux_/iter_fold_impl.hpp | 42 + boost/mpl/aux_/iter_push_front.hpp | 36 + boost/mpl/aux_/joint_iter.hpp | 120 + boost/mpl/aux_/lambda_spec.hpp | 49 + boost/mpl/aux_/msvc_type.hpp | 62 + boost/mpl/aux_/push_back_impl.hpp | 70 + boost/mpl/aux_/push_front_impl.hpp | 71 + boost/mpl/aux_/reverse_fold_impl.hpp | 44 + boost/mpl/aux_/reverse_fold_impl_body.hpp | 412 +++ boost/mpl/aux_/sequence_wrapper.hpp | 292 ++ boost/mpl/aux_/size_impl.hpp | 52 + boost/mpl/aux_/traits_lambda_spec.hpp | 63 + boost/mpl/back_inserter.hpp | 34 + boost/mpl/begin_end.hpp | 57 + boost/mpl/begin_end_fwd.hpp | 27 + boost/mpl/clear.hpp | 39 + boost/mpl/clear_fwd.hpp | 24 + boost/mpl/deref.hpp | 41 + boost/mpl/distance.hpp | 78 + boost/mpl/distance_fwd.hpp | 28 + boost/mpl/empty.hpp | 39 + boost/mpl/empty_fwd.hpp | 24 + boost/mpl/equal.hpp | 112 + boost/mpl/find_if.hpp | 50 + boost/mpl/fold.hpp | 48 + boost/mpl/front.hpp | 39 + boost/mpl/front_fwd.hpp | 24 + boost/mpl/front_inserter.hpp | 33 + boost/mpl/insert.hpp | 41 + boost/mpl/insert_fwd.hpp | 24 + boost/mpl/insert_range.hpp | 41 + boost/mpl/insert_range_fwd.hpp | 24 + boost/mpl/inserter.hpp | 32 + boost/mpl/is_sequence.hpp | 112 + boost/mpl/iter_fold.hpp | 49 + boost/mpl/iter_fold_if.hpp | 117 + boost/mpl/iterator_category.hpp | 35 + boost/mpl/iterator_range.hpp | 42 + boost/mpl/iterator_tags.hpp | 27 + boost/mpl/joint_view.hpp | 65 + boost/mpl/limits/list.hpp | 21 + boost/mpl/limits/unrolling.hpp | 21 + boost/mpl/list.hpp | 57 + boost/mpl/list/aux_/O1_size.hpp | 33 + boost/mpl/list/aux_/begin_end.hpp | 44 + boost/mpl/list/aux_/clear.hpp | 34 + boost/mpl/list/aux_/empty.hpp | 34 + boost/mpl/list/aux_/front.hpp | 33 + boost/mpl/list/aux_/include_preprocessed.hpp | 35 + boost/mpl/list/aux_/item.hpp | 55 + boost/mpl/list/aux_/iterator.hpp | 76 + boost/mpl/list/aux_/numbered.hpp | 68 + boost/mpl/list/aux_/numbered_c.hpp | 71 + boost/mpl/list/aux_/pop_front.hpp | 34 + .../list/aux_/preprocessed/plain/list10.hpp | 149 + .../list/aux_/preprocessed/plain/list10_c.hpp | 164 + .../list/aux_/preprocessed/plain/list20.hpp | 169 + .../list/aux_/preprocessed/plain/list20_c.hpp | 173 + .../list/aux_/preprocessed/plain/list30.hpp | 189 + .../list/aux_/preprocessed/plain/list30_c.hpp | 183 + .../list/aux_/preprocessed/plain/list40.hpp | 209 ++ .../list/aux_/preprocessed/plain/list40_c.hpp | 193 + .../list/aux_/preprocessed/plain/list50.hpp | 229 ++ .../list/aux_/preprocessed/plain/list50_c.hpp | 203 ++ boost/mpl/list/aux_/push_back.hpp | 36 + boost/mpl/list/aux_/push_front.hpp | 39 + boost/mpl/list/aux_/size.hpp | 33 + boost/mpl/list/aux_/tag.hpp | 24 + boost/mpl/list/list0.hpp | 42 + boost/mpl/list/list0_c.hpp | 31 + boost/mpl/list/list10.hpp | 43 + boost/mpl/list/list10_c.hpp | 43 + boost/mpl/list/list20.hpp | 43 + boost/mpl/list/list20_c.hpp | 43 + boost/mpl/list/list30.hpp | 43 + boost/mpl/list/list30_c.hpp | 43 + boost/mpl/list/list40.hpp | 43 + boost/mpl/list/list40_c.hpp | 43 + boost/mpl/list/list50.hpp | 43 + boost/mpl/list/list50_c.hpp | 43 + boost/mpl/long.hpp | 22 + boost/mpl/long_fwd.hpp | 27 + boost/mpl/max_element.hpp | 72 + boost/mpl/min_max.hpp | 46 + boost/mpl/negate.hpp | 81 + boost/mpl/pair.hpp | 70 + boost/mpl/pair_view.hpp | 169 + boost/mpl/plus.hpp | 21 + boost/mpl/pop_front_fwd.hpp | 24 + boost/mpl/prior.hpp | 19 + boost/mpl/push_back.hpp | 53 + boost/mpl/push_back_fwd.hpp | 24 + boost/mpl/push_front.hpp | 52 + boost/mpl/push_front_fwd.hpp | 24 + boost/mpl/reverse_fold.hpp | 50 + boost/mpl/same_as.hpp | 55 + boost/mpl/sequence_tag.hpp | 124 + boost/mpl/sequence_tag_fwd.hpp | 26 + boost/mpl/size.hpp | 42 + boost/mpl/size_fwd.hpp | 24 + boost/mpl/size_t.hpp | 25 + boost/mpl/size_t_fwd.hpp | 28 + boost/mpl/sizeof.hpp | 36 + boost/mpl/transform.hpp | 145 + .../enum_params_with_a_default.hpp | 17 + .../repetition/enum_params_with_a_default.hpp | 25 + boost/random/detail/config.hpp | 18 - boost/random/detail/const_mod.hpp | 216 -- boost/random/detail/disable_warnings.hpp | 29 - boost/random/detail/enable_warnings.hpp | 22 - boost/random/detail/generator_bits.hpp | 36 - boost/random/detail/integer_log2.hpp | 84 - boost/random/detail/large_arithmetic.hpp | 122 - boost/random/detail/operators.hpp | 84 - boost/random/detail/ptr_helper.hpp | 67 - boost/random/detail/seed.hpp | 113 - boost/random/detail/seed_impl.hpp | 397 --- boost/random/detail/signed_unsigned_tools.hpp | 89 - boost/random/linear_congruential.hpp | 468 --- boost/random/traits.hpp | 107 - boost/random/uniform_01.hpp | 257 -- boost/random/uniform_smallint.hpp | 306 -- boost/type_index.hpp | 285 ++ boost/type_index/ctti_type_index.hpp | 213 ++ .../detail/compile_time_type_info.hpp | 339 ++ .../type_index/detail/ctti_register_class.hpp | 40 + .../type_index/detail/stl_register_class.hpp | 40 + boost/type_index/stl_type_index.hpp | 278 ++ boost/type_index/type_index_facade.hpp | 297 ++ boost/type_traits/same_traits.hpp | 15 + boost/url.hpp | 70 + boost/url/src.hpp | 24 - boost/url/string_view.hpp | 52 - boost/url/url.natvis | 97 - boost/variant.hpp | 27 + boost/variant/apply_visitor.hpp | 20 + boost/variant/bad_visit.hpp | 43 + boost/variant/detail/apply_visitor_binary.hpp | 358 ++ .../variant/detail/apply_visitor_delayed.hpp | 146 + boost/variant/detail/apply_visitor_unary.hpp | 145 + boost/variant/detail/backup_holder.hpp | 95 + boost/variant/detail/cast_storage.hpp | 42 + boost/variant/detail/config.hpp | 37 + boost/variant/detail/element_index.hpp | 63 + boost/variant/detail/enable_recursive.hpp | 133 + boost/variant/detail/enable_recursive_fwd.hpp | 87 + boost/variant/detail/forced_return.hpp | 52 + boost/variant/detail/has_result_type.hpp | 37 + boost/variant/detail/hash_variant.hpp | 46 + boost/variant/detail/initializer.hpp | 249 ++ boost/variant/detail/make_variant_list.hpp | 73 + boost/variant/detail/move.hpp | 50 + boost/variant/detail/over_sequence.hpp | 58 + boost/variant/detail/std_hash.hpp | 46 + boost/variant/detail/substitute.hpp | 279 ++ boost/variant/detail/substitute_fwd.hpp | 58 + boost/variant/detail/variant_io.hpp | 95 + boost/variant/detail/visitation_impl.hpp | 277 ++ boost/variant/get.hpp | 388 ++ boost/variant/recursive_variant.hpp | 209 ++ boost/variant/recursive_wrapper.hpp | 158 + boost/variant/recursive_wrapper_fwd.hpp | 130 + boost/variant/static_visitor.hpp | 93 + boost/variant/variant.hpp | 2457 +++++++++++++ boost/variant/variant_fwd.hpp | 322 ++ boost/variant/visitor_ptr.hpp | 88 + build.cmd | 9 +- 239 files changed, 22752 insertions(+), 9301 deletions(-) create mode 100644 boost/blank.hpp create mode 100644 boost/blank_fwd.hpp delete mode 100644 boost/checked_delete.hpp create mode 100644 boost/circular_buffer.hpp create mode 100644 boost/circular_buffer/base.hpp create mode 100644 boost/circular_buffer/debug.hpp create mode 100644 boost/circular_buffer/details.hpp create mode 100644 boost/circular_buffer/space_optimized.hpp create mode 100644 boost/circular_buffer_fwd.hpp create mode 100644 boost/detail/templated_streams.hpp create mode 100644 boost/integer/common_factor_ct.hpp delete mode 100644 boost/integer/integer_log2.hpp delete mode 100644 boost/integer/integer_mask.hpp delete mode 100644 boost/integer/static_log2.hpp delete mode 100644 boost/iostreams/chain.hpp delete mode 100644 boost/iostreams/code_converter.hpp delete mode 100644 boost/iostreams/combine.hpp delete mode 100644 boost/iostreams/compose.hpp delete mode 100644 boost/iostreams/copy.hpp delete mode 100644 boost/iostreams/detail/absolute_path.hpp delete mode 100644 boost/iostreams/detail/access_control.hpp delete mode 100644 boost/iostreams/detail/adapter/device_adapter.hpp delete mode 100644 boost/iostreams/detail/adapter/direct_adapter.hpp delete mode 100644 boost/iostreams/detail/adapter/filter_adapter.hpp delete mode 100644 boost/iostreams/detail/add_facet.hpp delete mode 100644 boost/iostreams/detail/codecvt_helper.hpp delete mode 100644 boost/iostreams/detail/codecvt_holder.hpp delete mode 100644 boost/iostreams/detail/counted_array.hpp delete mode 100644 boost/iostreams/detail/current_directory.hpp delete mode 100644 boost/iostreams/detail/fstream.hpp delete mode 100644 boost/iostreams/detail/newline.hpp delete mode 100644 boost/iostreams/detail/param_type.hpp delete mode 100644 boost/iostreams/detail/restrict_impl.hpp delete mode 100644 boost/iostreams/detail/streambuf/chainbuf.hpp delete mode 100644 boost/iostreams/detail/translate_int_type.hpp delete mode 100644 boost/iostreams/device/file.hpp delete mode 100644 boost/iostreams/filter/aggregate.hpp delete mode 100644 boost/iostreams/filter/counter.hpp delete mode 100644 boost/iostreams/filter/grep.hpp delete mode 100644 boost/iostreams/filter/line.hpp delete mode 100644 boost/iostreams/filter/newline.hpp delete mode 100644 boost/iostreams/filter/regex.hpp delete mode 100644 boost/iostreams/filter/stdio.hpp delete mode 100644 boost/iostreams/filter/test.hpp delete mode 100644 boost/iostreams/filtering_stream.hpp delete mode 100644 boost/iostreams/filtering_streambuf.hpp delete mode 100644 boost/iostreams/invert.hpp delete mode 100644 boost/iostreams/restrict.hpp delete mode 100644 boost/iostreams/skip.hpp delete mode 100644 boost/iostreams/slice.hpp delete mode 100644 boost/iostreams/tee.hpp create mode 100644 boost/mpl/O1_size.hpp create mode 100644 boost/mpl/O1_size_fwd.hpp create mode 100644 boost/mpl/advance.hpp create mode 100644 boost/mpl/advance_fwd.hpp create mode 100644 boost/mpl/aux_/O1_size_impl.hpp create mode 100644 boost/mpl/aux_/advance_backward.hpp create mode 100644 boost/mpl/aux_/advance_forward.hpp create mode 100644 boost/mpl/aux_/begin_end_impl.hpp create mode 100644 boost/mpl/aux_/clear_impl.hpp create mode 100644 boost/mpl/aux_/empty_impl.hpp create mode 100644 boost/mpl/aux_/find_if_pred.hpp create mode 100644 boost/mpl/aux_/fold_impl.hpp create mode 100644 boost/mpl/aux_/fold_impl_body.hpp create mode 100644 boost/mpl/aux_/front_impl.hpp create mode 100644 boost/mpl/aux_/has_begin.hpp create mode 100644 boost/mpl/aux_/has_size.hpp create mode 100644 boost/mpl/aux_/insert_impl.hpp create mode 100644 boost/mpl/aux_/insert_range_impl.hpp create mode 100644 boost/mpl/aux_/inserter_algorithm.hpp create mode 100644 boost/mpl/aux_/iter_apply.hpp create mode 100644 boost/mpl/aux_/iter_fold_if_impl.hpp create mode 100644 boost/mpl/aux_/iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/iter_push_front.hpp create mode 100644 boost/mpl/aux_/joint_iter.hpp create mode 100644 boost/mpl/aux_/lambda_spec.hpp create mode 100644 boost/mpl/aux_/msvc_type.hpp create mode 100644 boost/mpl/aux_/push_back_impl.hpp create mode 100644 boost/mpl/aux_/push_front_impl.hpp create mode 100644 boost/mpl/aux_/reverse_fold_impl.hpp create mode 100644 boost/mpl/aux_/reverse_fold_impl_body.hpp create mode 100644 boost/mpl/aux_/sequence_wrapper.hpp create mode 100644 boost/mpl/aux_/size_impl.hpp create mode 100644 boost/mpl/aux_/traits_lambda_spec.hpp create mode 100644 boost/mpl/back_inserter.hpp create mode 100644 boost/mpl/begin_end.hpp create mode 100644 boost/mpl/begin_end_fwd.hpp create mode 100644 boost/mpl/clear.hpp create mode 100644 boost/mpl/clear_fwd.hpp create mode 100644 boost/mpl/deref.hpp create mode 100644 boost/mpl/distance.hpp create mode 100644 boost/mpl/distance_fwd.hpp create mode 100644 boost/mpl/empty.hpp create mode 100644 boost/mpl/empty_fwd.hpp create mode 100644 boost/mpl/equal.hpp create mode 100644 boost/mpl/find_if.hpp create mode 100644 boost/mpl/fold.hpp create mode 100644 boost/mpl/front.hpp create mode 100644 boost/mpl/front_fwd.hpp create mode 100644 boost/mpl/front_inserter.hpp create mode 100644 boost/mpl/insert.hpp create mode 100644 boost/mpl/insert_fwd.hpp create mode 100644 boost/mpl/insert_range.hpp create mode 100644 boost/mpl/insert_range_fwd.hpp create mode 100644 boost/mpl/inserter.hpp create mode 100644 boost/mpl/is_sequence.hpp create mode 100644 boost/mpl/iter_fold.hpp create mode 100644 boost/mpl/iter_fold_if.hpp create mode 100644 boost/mpl/iterator_category.hpp create mode 100644 boost/mpl/iterator_range.hpp create mode 100644 boost/mpl/iterator_tags.hpp create mode 100644 boost/mpl/joint_view.hpp create mode 100644 boost/mpl/limits/list.hpp create mode 100644 boost/mpl/limits/unrolling.hpp create mode 100644 boost/mpl/list.hpp create mode 100644 boost/mpl/list/aux_/O1_size.hpp create mode 100644 boost/mpl/list/aux_/begin_end.hpp create mode 100644 boost/mpl/list/aux_/clear.hpp create mode 100644 boost/mpl/list/aux_/empty.hpp create mode 100644 boost/mpl/list/aux_/front.hpp create mode 100644 boost/mpl/list/aux_/include_preprocessed.hpp create mode 100644 boost/mpl/list/aux_/item.hpp create mode 100644 boost/mpl/list/aux_/iterator.hpp create mode 100644 boost/mpl/list/aux_/numbered.hpp create mode 100644 boost/mpl/list/aux_/numbered_c.hpp create mode 100644 boost/mpl/list/aux_/pop_front.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list10.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list10_c.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list20.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list20_c.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list30.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list30_c.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list40.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list40_c.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list50.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list50_c.hpp create mode 100644 boost/mpl/list/aux_/push_back.hpp create mode 100644 boost/mpl/list/aux_/push_front.hpp create mode 100644 boost/mpl/list/aux_/size.hpp create mode 100644 boost/mpl/list/aux_/tag.hpp create mode 100644 boost/mpl/list/list0.hpp create mode 100644 boost/mpl/list/list0_c.hpp create mode 100644 boost/mpl/list/list10.hpp create mode 100644 boost/mpl/list/list10_c.hpp create mode 100644 boost/mpl/list/list20.hpp create mode 100644 boost/mpl/list/list20_c.hpp create mode 100644 boost/mpl/list/list30.hpp create mode 100644 boost/mpl/list/list30_c.hpp create mode 100644 boost/mpl/list/list40.hpp create mode 100644 boost/mpl/list/list40_c.hpp create mode 100644 boost/mpl/list/list50.hpp create mode 100644 boost/mpl/list/list50_c.hpp create mode 100644 boost/mpl/long.hpp create mode 100644 boost/mpl/long_fwd.hpp create mode 100644 boost/mpl/max_element.hpp create mode 100644 boost/mpl/min_max.hpp create mode 100644 boost/mpl/negate.hpp create mode 100644 boost/mpl/pair.hpp create mode 100644 boost/mpl/pair_view.hpp create mode 100644 boost/mpl/plus.hpp create mode 100644 boost/mpl/pop_front_fwd.hpp create mode 100644 boost/mpl/prior.hpp create mode 100644 boost/mpl/push_back.hpp create mode 100644 boost/mpl/push_back_fwd.hpp create mode 100644 boost/mpl/push_front.hpp create mode 100644 boost/mpl/push_front_fwd.hpp create mode 100644 boost/mpl/reverse_fold.hpp create mode 100644 boost/mpl/same_as.hpp create mode 100644 boost/mpl/sequence_tag.hpp create mode 100644 boost/mpl/sequence_tag_fwd.hpp create mode 100644 boost/mpl/size.hpp create mode 100644 boost/mpl/size_fwd.hpp create mode 100644 boost/mpl/size_t.hpp create mode 100644 boost/mpl/size_t_fwd.hpp create mode 100644 boost/mpl/sizeof.hpp create mode 100644 boost/mpl/transform.hpp create mode 100644 boost/preprocessor/enum_params_with_a_default.hpp create mode 100644 boost/preprocessor/repetition/enum_params_with_a_default.hpp delete mode 100644 boost/random/detail/config.hpp delete mode 100644 boost/random/detail/const_mod.hpp delete mode 100644 boost/random/detail/disable_warnings.hpp delete mode 100644 boost/random/detail/enable_warnings.hpp delete mode 100644 boost/random/detail/generator_bits.hpp delete mode 100644 boost/random/detail/integer_log2.hpp delete mode 100644 boost/random/detail/large_arithmetic.hpp delete mode 100644 boost/random/detail/operators.hpp delete mode 100644 boost/random/detail/ptr_helper.hpp delete mode 100644 boost/random/detail/seed.hpp delete mode 100644 boost/random/detail/seed_impl.hpp delete mode 100644 boost/random/detail/signed_unsigned_tools.hpp delete mode 100644 boost/random/linear_congruential.hpp delete mode 100644 boost/random/traits.hpp delete mode 100644 boost/random/uniform_01.hpp delete mode 100644 boost/random/uniform_smallint.hpp create mode 100644 boost/type_index.hpp create mode 100644 boost/type_index/ctti_type_index.hpp create mode 100644 boost/type_index/detail/compile_time_type_info.hpp create mode 100644 boost/type_index/detail/ctti_register_class.hpp create mode 100644 boost/type_index/detail/stl_register_class.hpp create mode 100644 boost/type_index/stl_type_index.hpp create mode 100644 boost/type_index/type_index_facade.hpp create mode 100644 boost/type_traits/same_traits.hpp create mode 100644 boost/url.hpp delete mode 100644 boost/url/src.hpp delete mode 100644 boost/url/string_view.hpp delete mode 100644 boost/url/url.natvis create mode 100644 boost/variant.hpp create mode 100644 boost/variant/apply_visitor.hpp create mode 100644 boost/variant/bad_visit.hpp create mode 100644 boost/variant/detail/apply_visitor_binary.hpp create mode 100644 boost/variant/detail/apply_visitor_delayed.hpp create mode 100644 boost/variant/detail/apply_visitor_unary.hpp create mode 100644 boost/variant/detail/backup_holder.hpp create mode 100644 boost/variant/detail/cast_storage.hpp create mode 100644 boost/variant/detail/config.hpp create mode 100644 boost/variant/detail/element_index.hpp create mode 100644 boost/variant/detail/enable_recursive.hpp create mode 100644 boost/variant/detail/enable_recursive_fwd.hpp create mode 100644 boost/variant/detail/forced_return.hpp create mode 100644 boost/variant/detail/has_result_type.hpp create mode 100644 boost/variant/detail/hash_variant.hpp create mode 100644 boost/variant/detail/initializer.hpp create mode 100644 boost/variant/detail/make_variant_list.hpp create mode 100644 boost/variant/detail/move.hpp create mode 100644 boost/variant/detail/over_sequence.hpp create mode 100644 boost/variant/detail/std_hash.hpp create mode 100644 boost/variant/detail/substitute.hpp create mode 100644 boost/variant/detail/substitute_fwd.hpp create mode 100644 boost/variant/detail/variant_io.hpp create mode 100644 boost/variant/detail/visitation_impl.hpp create mode 100644 boost/variant/get.hpp create mode 100644 boost/variant/recursive_variant.hpp create mode 100644 boost/variant/recursive_wrapper.hpp create mode 100644 boost/variant/recursive_wrapper_fwd.hpp create mode 100644 boost/variant/static_visitor.hpp create mode 100644 boost/variant/variant.hpp create mode 100644 boost/variant/variant_fwd.hpp create mode 100644 boost/variant/visitor_ptr.hpp diff --git a/boost/blank.hpp b/boost/blank.hpp new file mode 100644 index 00000000..918723ca --- /dev/null +++ b/boost/blank.hpp @@ -0,0 +1,106 @@ +//----------------------------------------------------------------------------- +// boost blank.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_BLANK_HPP +#define BOOST_BLANK_HPP + +#include "boost/blank_fwd.hpp" + +#if !defined(BOOST_NO_IOSTREAM) +#include // for std::basic_ostream forward declare +#include "boost/detail/templated_streams.hpp" +#endif // BOOST_NO_IOSTREAM + +#include "boost/type_traits/integral_constant.hpp" +#include "boost/type_traits/is_empty.hpp" +#include "boost/type_traits/is_pod.hpp" +#include "boost/type_traits/is_stateless.hpp" + +namespace boost { + +struct blank +{ +}; + +// type traits specializations +// + +template <> +struct is_pod< blank > + : boost::true_type +{ +}; + +template <> +struct is_empty< blank > + : boost::true_type +{ +}; + +template <> +struct is_stateless< blank > + : boost::true_type +{ +}; + +// relational operators +// + +inline bool operator==(const blank&, const blank&) +{ + return true; +} + +inline bool operator<=(const blank&, const blank&) +{ + return true; +} + +inline bool operator>=(const blank&, const blank&) +{ + return true; +} + +inline bool operator!=(const blank&, const blank&) +{ + return false; +} + +inline bool operator<(const blank&, const blank&) +{ + return false; +} + +inline bool operator>(const blank&, const blank&) +{ + return false; +} + +// streaming support +// +#if !defined(BOOST_NO_IOSTREAM) + +BOOST_TEMPLATED_STREAM_TEMPLATE(E,T) +inline BOOST_TEMPLATED_STREAM(ostream, E,T)& operator<<( + BOOST_TEMPLATED_STREAM(ostream, E,T)& out + , const blank& + ) +{ + // (output nothing) + return out; +} + +#endif // BOOST_NO_IOSTREAM + +} // namespace boost + +#endif // BOOST_BLANK_HPP diff --git a/boost/blank_fwd.hpp b/boost/blank_fwd.hpp new file mode 100644 index 00000000..8bfe97c4 --- /dev/null +++ b/boost/blank_fwd.hpp @@ -0,0 +1,22 @@ +//----------------------------------------------------------------------------- +// boost blank_fwd.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_BLANK_FWD_HPP +#define BOOST_BLANK_FWD_HPP + +namespace boost { + +struct blank; + +} // namespace boost + +#endif // BOOST_BLANK_FWD_HPP diff --git a/boost/checked_delete.hpp b/boost/checked_delete.hpp deleted file mode 100644 index fb71c789..00000000 --- a/boost/checked_delete.hpp +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2014 Glen Fernandes - * - * Distributed under the Boost Software License, Version 1.0. (See - * accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ - -#ifndef BOOST_CHECKED_DELETE_HPP -#define BOOST_CHECKED_DELETE_HPP - -// The header file at this path is deprecated; -// use boost/core/checked_delete.hpp instead. - -#include - -#endif diff --git a/boost/circular_buffer.hpp b/boost/circular_buffer.hpp new file mode 100644 index 00000000..aa8a2e5b --- /dev/null +++ b/boost/circular_buffer.hpp @@ -0,0 +1,65 @@ +// Circular buffer library header file. + +// Copyright (c) 2003-2008 Jan Gaspar + +// 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 www.boost.org/libs/circular_buffer for documentation. + +/*! @file +Includes +*/ + +#if !defined(BOOST_CIRCULAR_BUFFER_HPP) +#define BOOST_CIRCULAR_BUFFER_HPP + +#if defined(_MSC_VER) + #pragma once +#endif + +#include +#include +#include + +/*! Debug support control. */ +#if !defined(BOOST_CB_ENABLE_DEBUG) + #define BOOST_CB_ENABLE_DEBUG 0 +#endif + +/*! INTERNAL ONLY */ +#if BOOST_CB_ENABLE_DEBUG + #include + #define BOOST_CB_ASSERT(Expr) BOOST_ASSERT(Expr) +#else + #define BOOST_CB_ASSERT(Expr) ((void)0) +#endif + +/*! INTERNAL ONLY */ +#if BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x0550) || BOOST_WORKAROUND(__MWERKS__, <= 0x2407) + #define BOOST_CB_IS_CONVERTIBLE(Iterator, Type) ((void)0) +#else + #include + #include + #define BOOST_CB_IS_CONVERTIBLE(Iterator, Type) \ + BOOST_STATIC_ASSERT((is_convertible::value_type, Type>::value)) +#endif + +/*! INTERNAL ONLY */ +#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + #define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS BOOST_STATIC_ASSERT(false); +#else + #define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS ((void)0); +#endif + +#include +#include +#include +#include + +#undef BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS +#undef BOOST_CB_IS_CONVERTIBLE +#undef BOOST_CB_ASSERT + +#endif // #if !defined(BOOST_CIRCULAR_BUFFER_HPP) diff --git a/boost/circular_buffer/base.hpp b/boost/circular_buffer/base.hpp new file mode 100644 index 00000000..47441544 --- /dev/null +++ b/boost/circular_buffer/base.hpp @@ -0,0 +1,3134 @@ +// Implementation of the base circular buffer. + +// Copyright (c) 2003-2008 Jan Gaspar +// Copyright (c) 2013 Paul A. Bristow // Doxygen comments changed. +// Copyright (c) 2013 Antony Polukhin // Move semantics implementation. + +// Copyright 2014,2018 Glen Joseph Fernandes +// (glenjofe@gmail.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) + +#if !defined(BOOST_CIRCULAR_BUFFER_BASE_HPP) +#define BOOST_CIRCULAR_BUFFER_BASE_HPP + +#if defined(_MSC_VER) + #pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + #include +#endif + +namespace boost { + +/*! + \class circular_buffer + \brief Circular buffer - a STL compliant container. + \tparam T The type of the elements stored in the circular_buffer. + \par Type Requirements T + The T has to be + SGIAssignable (SGI STL defined combination of + Assignable and CopyConstructible). + Moreover T has to be + DefaultConstructible if supplied as a default parameter when invoking some of the + circular_buffer's methods e.g. + insert(iterator pos, const value_type& item = %value_type()). And + EqualityComparable and/or + LessThanComparable if the circular_buffer + will be compared with another container. + \tparam Alloc The allocator type used for all internal memory management. + \par Type Requirements Alloc + The Alloc has to meet the allocator requirements imposed by STL. + \par Default Alloc + std::allocator + + For detailed documentation of the circular_buffer visit: + http://www.boost.org/libs/circular_buffer/doc/circular_buffer.html +*/ +template +class circular_buffer +: +/*! \cond */ +#if BOOST_CB_ENABLE_DEBUG +public cb_details::debug_iterator_registry, +#endif +/*! \endcond */ +private empty_value +{ + typedef empty_value base; + + // Requirements + //BOOST_CLASS_REQUIRE(T, boost, SGIAssignableConcept); + + + //BOOST_CONCEPT_ASSERT((Assignable)); + //BOOST_CONCEPT_ASSERT((CopyConstructible)); + //BOOST_CONCEPT_ASSERT((DefaultConstructible)); + + // Required if the circular_buffer will be compared with anther container. + //BOOST_CONCEPT_ASSERT((EqualityComparable)); + //BOOST_CONCEPT_ASSERT((LessThanComparable)); + +public: +// Basic types + + //! The type of this circular_buffer. + typedef circular_buffer this_type; + + //! The type of elements stored in the circular_buffer. + typedef typename Alloc::value_type value_type; + + //! A pointer to an element. + typedef typename allocator_pointer::type pointer; + + //! A const pointer to the element. + typedef typename allocator_const_pointer::type const_pointer; + + //! A reference to an element. + typedef value_type& reference; + + //! A const reference to an element. + typedef const value_type& const_reference; + + //! The distance type. + /*! + (A signed integral type used to represent the distance between two iterators.) + */ + typedef typename allocator_difference_type::type difference_type; + + //! The size type. + /*! + (An unsigned integral type that can represent any non-negative value of the container's distance type.) + */ + typedef typename allocator_size_type::type size_type; + + //! The type of an allocator used in the circular_buffer. + typedef Alloc allocator_type; + +// Iterators + + //! A const (random access) iterator used to iterate through the circular_buffer. + typedef cb_details::iterator< circular_buffer, cb_details::const_traits > const_iterator; + + //! A (random access) iterator used to iterate through the circular_buffer. + typedef cb_details::iterator< circular_buffer, cb_details::nonconst_traits > iterator; + + //! A const iterator used to iterate backwards through a circular_buffer. + typedef std::reverse_iterator const_reverse_iterator; + + //! An iterator used to iterate backwards through a circular_buffer. + typedef std::reverse_iterator reverse_iterator; + +// Container specific types + + //! An array range. + /*! + (A typedef for the std::pair where + its first element is a pointer to a beginning of an array and its second element represents + a size of the array.) + */ + typedef std::pair array_range; + + //! A range of a const array. + /*! + (A typedef for the std::pair where + its first element is a pointer to a beginning of a const array and its second element represents + a size of the const array.) + */ + typedef std::pair const_array_range; + + //! The capacity type. + /*! + (Same as size_type - defined for consistency with the __cbso class. + + */ + // circular_buffer_space_optimized.) + + typedef size_type capacity_type; + +// Helper types + + //! A type representing the "best" way to pass the value_type to a method. + typedef const value_type& param_value_type; + + //! A type representing rvalue from param type. + //! On compilers without rvalue references support this type is the Boost.Moves type used for emulation. + typedef BOOST_RV_REF(value_type) rvalue_type; + +private: +// Member variables + + //! The internal buffer used for storing elements in the circular buffer. + pointer m_buff; + + //! The internal buffer's end (end of the storage space). + pointer m_end; + + //! The virtual beginning of the circular buffer. + pointer m_first; + + //! The virtual end of the circular buffer (one behind the last element). + pointer m_last; + + //! The number of items currently stored in the circular buffer. + size_type m_size; + +// Friends +#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + friend iterator; + friend const_iterator; +#else + template friend struct cb_details::iterator; +#endif + +public: +// Allocator + + //! Get the allocator. + /*! + \return The allocator. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa get_allocator() for obtaining an allocator %reference. + */ + allocator_type get_allocator() const BOOST_NOEXCEPT { return alloc(); } + + //! Get the allocator reference. + /*! + \return A reference to the allocator. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \note This method was added in order to optimize obtaining of the allocator with a state, + although use of stateful allocators in STL is discouraged. + \sa get_allocator() const + */ + allocator_type& get_allocator() BOOST_NOEXCEPT { return alloc(); } + +// Element access + + //! Get the iterator pointing to the beginning of the circular_buffer. + /*! + \return A random access iterator pointing to the first element of the circular_buffer. If the + circular_buffer is empty it returns an iterator equal to the one returned by + end(). + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa end(), rbegin(), rend() + */ + iterator begin() BOOST_NOEXCEPT { return iterator(this, empty() ? 0 : m_first); } + + //! Get the iterator pointing to the end of the circular_buffer. + /*! + \return A random access iterator pointing to the element "one behind" the last element of the + circular_buffer. If the circular_buffer is empty it returns an iterator equal to + the one returned by begin(). + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa begin(), rbegin(), rend() + */ + iterator end() BOOST_NOEXCEPT { return iterator(this, 0); } + + //! Get the const iterator pointing to the beginning of the circular_buffer. + /*! + \return A const random access iterator pointing to the first element of the circular_buffer. If + the circular_buffer is empty it returns an iterator equal to the one returned by + end() const. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa end() const, rbegin() const, rend() const + */ + const_iterator begin() const BOOST_NOEXCEPT { return const_iterator(this, empty() ? 0 : m_first); } + + const_iterator cbegin() const BOOST_NOEXCEPT { return begin(); } + //! Get the const iterator pointing to the end of the circular_buffer. + /*! + \return A const random access iterator pointing to the element "one behind" the last element of the + circular_buffer. If the circular_buffer is empty it returns an iterator equal to + the one returned by begin() const const. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa begin() const, rbegin() const, rend() const + */ + const_iterator end() const BOOST_NOEXCEPT { return const_iterator(this, 0); } + + const_iterator cend() const BOOST_NOEXCEPT { return end(); } + //! Get the iterator pointing to the beginning of the "reversed" circular_buffer. + /*! + \return A reverse random access iterator pointing to the last element of the circular_buffer. + If the circular_buffer is empty it returns an iterator equal to the one returned by + rend(). + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa rend(), begin(), end() + */ + reverse_iterator rbegin() BOOST_NOEXCEPT { return reverse_iterator(end()); } + + //! Get the iterator pointing to the end of the "reversed" circular_buffer. + /*! + \return A reverse random access iterator pointing to the element "one before" the first element of the + circular_buffer. If the circular_buffer is empty it returns an iterator equal to + the one returned by rbegin(). + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa rbegin(), begin(), end() + */ + reverse_iterator rend() BOOST_NOEXCEPT { return reverse_iterator(begin()); } + + //! Get the const iterator pointing to the beginning of the "reversed" circular_buffer. + /*! + \return A const reverse random access iterator pointing to the last element of the + circular_buffer. If the circular_buffer is empty it returns an iterator equal + to the one returned by rend() const. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa rend() const, begin() const, end() const + */ + const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); } + + //! Get the const iterator pointing to the end of the "reversed" circular_buffer. + /*! + \return A const reverse random access iterator pointing to the element "one before" the first element of the + circular_buffer. If the circular_buffer is empty it returns an iterator equal + to the one returned by rbegin() const. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa rbegin() const, begin() const, end() const + */ + const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); } + + //! Get the element at the index position. + /*! + \pre 0 \<= index \&\& index \< size() + \param index The position of the element. + \return A reference to the element at the index position. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa at() + */ + reference operator [] (size_type index) { + BOOST_CB_ASSERT(index < size()); // check for invalid index + return *add(m_first, index); + } + + //! Get the element at the index position. + /*! + \pre 0 \<= index \&\& index \< size() + \param index The position of the element. + \return A const reference to the element at the index position. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link at(size_type)const at() const \endlink + */ + const_reference operator [] (size_type index) const { + BOOST_CB_ASSERT(index < size()); // check for invalid index + return *add(m_first, index); + } + + //! Get the element at the index position. + /*! + \param index The position of the element. + \return A reference to the element at the index position. + \throws std::out_of_range when the index is invalid (when + index >= size()). + \par Exception Safety + Strong. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link operator[](size_type) operator[] \endlink + */ + reference at(size_type index) { + check_position(index); + return (*this)[index]; + } + + //! Get the element at the index position. + /*! + \param index The position of the element. + \return A const reference to the element at the index position. + \throws std::out_of_range when the index is invalid (when + index >= size()). + \par Exception Safety + Strong. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link operator[](size_type)const operator[] const \endlink + */ + const_reference at(size_type index) const { + check_position(index); + return (*this)[index]; + } + + //! Get the first element. + /*! + \pre !empty() + \return A reference to the first element of the circular_buffer. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa back() + */ + reference front() { + BOOST_CB_ASSERT(!empty()); // check for empty buffer (front element not available) + return *m_first; + } + + //! Get the last element. + /*! + \pre !empty() + \return A reference to the last element of the circular_buffer. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa front() + */ + reference back() { + BOOST_CB_ASSERT(!empty()); // check for empty buffer (back element not available) + return *((m_last == m_buff ? m_end : m_last) - 1); + } + + //! Get the first element. + /*! + \pre !empty() + \return A const reference to the first element of the circular_buffer. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa back() const + */ + const_reference front() const { + BOOST_CB_ASSERT(!empty()); // check for empty buffer (front element not available) + return *m_first; + } + + //! Get the last element. + /*! + \pre !empty() + \return A const reference to the last element of the circular_buffer. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa front() const + */ + const_reference back() const { + BOOST_CB_ASSERT(!empty()); // check for empty buffer (back element not available) + return *((m_last == m_buff ? m_end : m_last) - 1); + } + + //! Get the first continuous array of the internal buffer. + /*! + This method in combination with array_two() can be useful when passing the stored data into + a legacy C API as an array. Suppose there is a circular_buffer of capacity 10, containing 7 + characters 'a', 'b', ..., 'g' where buff[0] == 'a', buff[1] == 'b', + ... and buff[6] == 'g':

+ circular_buffer buff(10);

+ The internal representation is often not linear and the state of the internal buffer may look like this:
+
+ |e|f|g| | | |a|b|c|d|
+ end ___^
+ begin _______^


+ + where |a|b|c|d| represents the "array one", |e|f|g| represents the "array two" and + | | | | is a free space.
+ Now consider a typical C style function for writing data into a file:

+ int write(int file_desc, char* buff, int num_bytes);

+ There are two ways how to write the content of the circular_buffer into a file. Either relying + on array_one() and array_two() methods and calling the write function twice:

+ array_range ar = buff.array_one();
+ write(file_desc, ar.first, ar.second);
+ ar = buff.array_two();
+ write(file_desc, ar.first, ar.second);


+ Or relying on the linearize() method:

+ write(file_desc, buff.linearize(), buff.size());

+ Since the complexity of array_one() and array_two() methods is constant the first + option is suitable when calling the write method is "cheap". On the other hand the second option is more + suitable when calling the write method is more "expensive" than calling the linearize() method + whose complexity is linear. + \return The array range of the first continuous array of the internal buffer. In the case the + circular_buffer is empty the size of the returned array is 0. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \warning In general invoking any method which modifies the internal state of the circular_buffer may + delinearize the internal buffer and invalidate the array ranges returned by array_one() + and array_two() (and their const versions). + \note In the case the internal buffer is linear e.g. |a|b|c|d|e|f|g| | | | the "array one" is + represented by |a|b|c|d|e|f|g| and the "array two" does not exist (the + array_two() method returns an array with the size 0). + \sa array_two(), linearize() + */ + array_range array_one() { + return array_range(m_first, (m_last <= m_first && !empty() ? m_end : m_last) - m_first); + } + + //! Get the second continuous array of the internal buffer. + /*! + This method in combination with array_one() can be useful when passing the stored data into + a legacy C API as an array. + \return The array range of the second continuous array of the internal buffer. In the case the internal buffer + is linear or the circular_buffer is empty the size of the returned array is + 0. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa array_one() + */ + array_range array_two() { + return array_range(m_buff, m_last <= m_first && !empty() ? m_last - m_buff : 0); + } + + //! Get the first continuous array of the internal buffer. + /*! + This method in combination with array_two() const can be useful when passing the stored data into + a legacy C API as an array. + \return The array range of the first continuous array of the internal buffer. In the case the + circular_buffer is empty the size of the returned array is 0. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa array_two() const; array_one() for more details how to pass data into a legacy C + API. + */ + const_array_range array_one() const { + return const_array_range(m_first, (m_last <= m_first && !empty() ? m_end : m_last) - m_first); + } + + //! Get the second continuous array of the internal buffer. + /*! + This method in combination with array_one() const can be useful when passing the stored data into + a legacy C API as an array. + \return The array range of the second continuous array of the internal buffer. In the case the internal buffer + is linear or the circular_buffer is empty the size of the returned array is + 0. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa array_one() const + */ + const_array_range array_two() const { + return const_array_range(m_buff, m_last <= m_first && !empty() ? m_last - m_buff : 0); + } + + //! Linearize the internal buffer into a continuous array. + /*! + This method can be useful when passing the stored data into a legacy C API as an array. + \post \&(*this)[0] \< \&(*this)[1] \< ... \< \&(*this)[size() - 1] + \return A pointer to the beginning of the array or 0 if empty. + \throws Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operations in the Throws section do not throw anything. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer (except iterators equal to + end()); does not invalidate any iterators if the postcondition (the Effect) is already + met prior calling this method. + \par Complexity + Linear (in the size of the circular_buffer); constant if the postcondition (the + Effect) is already met. + \warning In general invoking any method which modifies the internal state of the circular_buffer + may delinearize the internal buffer and invalidate the returned pointer. + \sa array_one() and array_two() for the other option how to pass data into a legacy + C API; is_linearized(), rotate(const_iterator) + */ + pointer linearize() { + if (empty()) + return 0; + if (m_first < m_last || m_last == m_buff) + return m_first; + pointer src = m_first; + pointer dest = m_buff; + size_type moved = 0; + size_type constructed = 0; + BOOST_TRY { + for (pointer first = m_first; dest < src; src = first) { + for (size_type ii = 0; src < m_end; ++src, ++dest, ++moved, ++ii) { + if (moved == size()) { + first = dest; + break; + } + if (dest == first) { + first += ii; + break; + } + if (is_uninitialized(dest)) { + boost::allocator_construct(alloc(), boost::to_address(dest), boost::move_if_noexcept(*src)); + ++constructed; + } else { + value_type tmp = boost::move_if_noexcept(*src); + replace(src, boost::move_if_noexcept(*dest)); + replace(dest, boost::move(tmp)); + } + } + } + } BOOST_CATCH(...) { + m_last += constructed; + m_size += constructed; + BOOST_RETHROW + } + BOOST_CATCH_END + for (src = m_end - constructed; src < m_end; ++src) + destroy_item(src); + m_first = m_buff; + m_last = add(m_buff, size()); +#if BOOST_CB_ENABLE_DEBUG + invalidate_iterators_except(end()); +#endif + return m_buff; + } + + //! Is the circular_buffer linearized? + /*! + \return true if the internal buffer is linearized into a continuous array (i.e. the + circular_buffer meets a condition + \&(*this)[0] \< \&(*this)[1] \< ... \< \&(*this)[size() - 1]); + false otherwise. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa linearize(), array_one(), array_two() + */ + bool is_linearized() const BOOST_NOEXCEPT { return m_first < m_last || m_last == m_buff; } + + //! Rotate elements in the circular_buffer. + /*! + A more effective implementation of + std::rotate. + \pre new_begin is a valid iterator pointing to the circular_buffer except its + end. + \post Before calling the method suppose:

+ m == std::distance(new_begin, end())
n == std::distance(begin(), new_begin) +
val_0 == *new_begin, val_1 == *(new_begin + 1), ... val_m == *(new_begin + m)
+ val_r1 == *(new_begin - 1), val_r2 == *(new_begin - 2), ... val_rn == *(new_begin - n)
+
then after call to the method:

+ val_0 == (*this)[0] \&\& val_1 == (*this)[1] \&\& ... \&\& val_m == (*this)[m - 1] \&\& val_r1 == + (*this)[m + n - 1] \&\& val_r2 == (*this)[m + n - 2] \&\& ... \&\& val_rn == (*this)[m] + \param new_begin The new beginning. + \throws See Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the circular_buffer is full or new_begin points to + begin() or if the operations in the Throws section do not throw anything. + \par Iterator Invalidation + If m \< n invalidates iterators pointing to the last m elements + (including new_begin, but not iterators equal to end()) else invalidates + iterators pointing to the first n elements; does not invalidate any iterators if the + circular_buffer is full. + \par Complexity + Linear (in (std::min)(m, n)); constant if the circular_buffer is full. + \sa std::rotate + */ + void rotate(const_iterator new_begin) { + BOOST_CB_ASSERT(new_begin.is_valid(this)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(new_begin.m_it != 0); // check for iterator pointing to end() + if (full()) { + m_first = m_last = const_cast(new_begin.m_it); + } else { + difference_type m = end() - new_begin; + difference_type n = new_begin - begin(); + if (m < n) { + for (; m > 0; --m) { + push_front(boost::move_if_noexcept(back())); + pop_back(); + } + } else { + for (; n > 0; --n) { + push_back(boost::move_if_noexcept(front())); + pop_front(); + } + } + } + } + +// Size and capacity + + //! Get the number of elements currently stored in the circular_buffer. + /*! + \return The number of elements stored in the circular_buffer. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa capacity(), max_size(), reserve(), + \link resize() resize(size_type, const_reference)\endlink + */ + size_type size() const BOOST_NOEXCEPT { return m_size; } + + /*! \brief Get the largest possible size or capacity of the circular_buffer. (It depends on + allocator's %max_size()). + \return The maximum size/capacity the circular_buffer can be set to. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa size(), capacity(), reserve() + */ + size_type max_size() const BOOST_NOEXCEPT { + return (std::min)(boost::allocator_max_size(alloc()), (std::numeric_limits::max)()); + } + + //! Is the circular_buffer empty? + /*! + \return true if there are no elements stored in the circular_buffer; + false otherwise. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa full() + */ + bool empty() const BOOST_NOEXCEPT { return size() == 0; } + + //! Is the circular_buffer full? + /*! + \return true if the number of elements stored in the circular_buffer + equals the capacity of the circular_buffer; false otherwise. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa empty() + */ + bool full() const BOOST_NOEXCEPT { return capacity() == size(); } + + /*! \brief Get the maximum number of elements which can be inserted into the circular_buffer without + overwriting any of already stored elements. + \return capacity() - size() + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa capacity(), size(), max_size() + */ + size_type reserve() const BOOST_NOEXCEPT { return capacity() - size(); } + + //! Get the capacity of the circular_buffer. + /*! + \return The maximum number of elements which can be stored in the circular_buffer. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer). + \sa reserve(), size(), max_size(), + set_capacity(capacity_type) + */ + capacity_type capacity() const BOOST_NOEXCEPT { return m_end - m_buff; } + + //! Change the capacity of the circular_buffer. + /*! + \pre If T is a move only type, then compiler shall support noexcept modifiers + and move constructor of T must be marked with it (must not throw exceptions). + \post capacity() == new_capacity \&\& size() \<= new_capacity

+ If the current number of elements stored in the circular_buffer is greater than the desired + new capacity then number of [size() - new_capacity] last elements will be removed and + the new size will be equal to new_capacity. + \param new_capacity The new capacity. + \throws "An allocation error" if memory is exhausted, (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Strong. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer (except iterators equal to + end()) if the new capacity is different from the original. + \par Complexity + Linear (in min[size(), new_capacity]). + \sa rset_capacity(capacity_type), + \link resize() resize(size_type, const_reference)\endlink + */ + void set_capacity(capacity_type new_capacity) { + if (new_capacity == capacity()) + return; + pointer buff = allocate(new_capacity); + iterator b = begin(); + BOOST_TRY { + reset(buff, + cb_details::uninitialized_move_if_noexcept(b, b + (std::min)(new_capacity, size()), buff, alloc()), + new_capacity); + } BOOST_CATCH(...) { + deallocate(buff, new_capacity); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + //! Change the size of the circular_buffer. + /*! + \post size() == new_size \&\& capacity() >= new_size

+ If the new size is greater than the current size, copies of item will be inserted at the + back of the of the circular_buffer in order to achieve the desired size. In the case + the resulting size exceeds the current capacity the capacity will be set to new_size.
+ If the current number of elements stored in the circular_buffer is greater than the desired + new size then number of [size() - new_size] last elements will be removed. (The + capacity will remain unchanged.) + \param new_size The new size. + \param item The element the circular_buffer will be filled with in order to gain the requested + size. (See the Effect.) + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer (except iterators equal to + end()) if the new size is greater than the current capacity. Invalidates iterators pointing + to the removed elements if the new size is lower that the original size. Otherwise it does not invalidate + any iterator. + \par Complexity + Linear (in the new size of the circular_buffer). + \sa \link rresize() rresize(size_type, const_reference)\endlink, + set_capacity(capacity_type) + */ + void resize(size_type new_size, param_value_type item = value_type()) { + if (new_size > size()) { + if (new_size > capacity()) + set_capacity(new_size); + insert(end(), new_size - size(), item); + } else { + iterator e = end(); + erase(e - (size() - new_size), e); + } + } + + //! Change the capacity of the circular_buffer. + /*! + \pre If T is a move only type, then compiler shall support noexcept modifiers + and move constructor of T must be marked with it (must not throw exceptions). + \post capacity() == new_capacity \&\& size() \<= new_capacity

+ If the current number of elements stored in the circular_buffer is greater than the desired + new capacity then number of [size() - new_capacity] first elements will be removed + and the new size will be equal to new_capacity. + \param new_capacity The new capacity. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Strong. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer (except iterators equal to + end()) if the new capacity is different from the original. + \par Complexity + Linear (in min[size(), new_capacity]). + \sa set_capacity(capacity_type), + \link rresize() rresize(size_type, const_reference)\endlink + */ + void rset_capacity(capacity_type new_capacity) { + if (new_capacity == capacity()) + return; + pointer buff = allocate(new_capacity); + iterator e = end(); + BOOST_TRY { + reset(buff, cb_details::uninitialized_move_if_noexcept(e - (std::min)(new_capacity, size()), + e, buff, alloc()), new_capacity); + } BOOST_CATCH(...) { + deallocate(buff, new_capacity); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + //! Change the size of the circular_buffer. + /*! + \post size() == new_size \&\& capacity() >= new_size

+ If the new size is greater than the current size, copies of item will be inserted at the + front of the of the circular_buffer in order to achieve the desired size. In the case + the resulting size exceeds the current capacity the capacity will be set to new_size.
+ If the current number of elements stored in the circular_buffer is greater than the desired + new size then number of [size() - new_size] first elements will be removed. (The + capacity will remain unchanged.) + \param new_size The new size. + \param item The element the circular_buffer will be filled with in order to gain the requested + size. (See the Effect.) + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer (except iterators equal to + end()) if the new size is greater than the current capacity. Invalidates iterators pointing + to the removed elements if the new size is lower that the original size. Otherwise it does not invalidate + any iterator. + \par Complexity + Linear (in the new size of the circular_buffer). + \sa \link resize() resize(size_type, const_reference)\endlink, + rset_capacity(capacity_type) + */ + void rresize(size_type new_size, param_value_type item = value_type()) { + if (new_size > size()) { + if (new_size > capacity()) + set_capacity(new_size); + rinsert(begin(), new_size - size(), item); + } else { + rerase(begin(), end() - new_size); + } + } + +// Construction/Destruction + + //! Create an empty circular_buffer with zero capacity. + /*! + \post capacity() == 0 \&\& size() == 0 + \param alloc The allocator. + \throws Nothing. + \par Complexity + Constant. + \warning Since Boost version 1.36 the behaviour of this constructor has changed. Now the constructor does not + allocate any memory and both capacity and size are set to zero. Also note when inserting an element + into a circular_buffer with zero capacity (e.g. by + \link push_back() push_back(const_reference)\endlink or + \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink) nothing + will be inserted and the size (as well as capacity) remains zero. + \note You can explicitly set the capacity by calling the set_capacity(capacity_type) method or you + can use the other constructor with the capacity specified. + \sa circular_buffer(capacity_type, const allocator_type& alloc), + set_capacity(capacity_type) + */ + explicit circular_buffer(const allocator_type& alloc = allocator_type()) BOOST_NOEXCEPT + : base(boost::empty_init_t(), alloc), m_buff(0), m_end(0), m_first(0), m_last(0), m_size(0) {} + + //! Create an empty circular_buffer with the specified capacity. + /*! + \post capacity() == buffer_capacity \&\& size() == 0 + \param buffer_capacity The maximum number of elements which can be stored in the circular_buffer. + \param alloc The allocator. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + \par Complexity + Constant. + */ + explicit circular_buffer(capacity_type buffer_capacity, const allocator_type& alloc = allocator_type()) + : base(boost::empty_init_t(), alloc), m_size(0) { + initialize_buffer(buffer_capacity); + m_first = m_last = m_buff; + } + + /*! \brief Create a full circular_buffer with the specified capacity and filled with n + copies of item. + \post capacity() == n \&\& full() \&\& (*this)[0] == item \&\& (*this)[1] == item \&\& ... \&\& + (*this)[n - 1] == item + \param n The number of elements the created circular_buffer will be filled with. + \param item The element the created circular_buffer will be filled with. + \param alloc The allocator. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Complexity + Linear (in the n). + */ + circular_buffer(size_type n, param_value_type item, const allocator_type& alloc = allocator_type()) + : base(boost::empty_init_t(), alloc), m_size(n) { + initialize_buffer(n, item); + m_first = m_last = m_buff; + } + + /*! \brief Create a circular_buffer with the specified capacity and filled with n + copies of item. + \pre buffer_capacity >= n + \post capacity() == buffer_capacity \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item + \&\& ... \&\& (*this)[n - 1] == item + \param buffer_capacity The capacity of the created circular_buffer. + \param n The number of elements the created circular_buffer will be filled with. + \param item The element the created circular_buffer will be filled with. + \param alloc The allocator. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Complexity + Linear (in the n). + */ + circular_buffer(capacity_type buffer_capacity, size_type n, param_value_type item, + const allocator_type& alloc = allocator_type()) + : base(boost::empty_init_t(), alloc), m_size(n) { + BOOST_CB_ASSERT(buffer_capacity >= size()); // check for capacity lower than size + initialize_buffer(buffer_capacity, item); + m_first = m_buff; + m_last = buffer_capacity == n ? m_buff : m_buff + n; + } + + //! The copy constructor. + /*! + Creates a copy of the specified circular_buffer. + \post *this == cb + \param cb The circular_buffer to be copied. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Complexity + Linear (in the size of cb). + */ + circular_buffer(const circular_buffer& cb) + : +#if BOOST_CB_ENABLE_DEBUG + debug_iterator_registry(), +#endif + base(boost::empty_init_t(), cb.get_allocator()), + m_size(cb.size()) { + initialize_buffer(cb.capacity()); + m_first = m_buff; + BOOST_TRY { + m_last = cb_details::uninitialized_copy(cb.begin(), cb.end(), m_buff, alloc()); + } BOOST_CATCH(...) { + deallocate(m_buff, cb.capacity()); + BOOST_RETHROW + } + BOOST_CATCH_END + if (m_last == m_end) + m_last = m_buff; + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + //! The move constructor. + /*! \brief Move constructs a circular_buffer from cb, leaving cb empty. + \pre C++ compiler with rvalue references support. + \post cb.empty() + \param cb circular_buffer to 'steal' value from. + \throws Nothing. + \par Constant. + */ + circular_buffer(circular_buffer&& cb) BOOST_NOEXCEPT + : base(boost::empty_init_t(), cb.get_allocator()), m_buff(0), m_end(0), m_first(0), m_last(0), m_size(0) { + cb.swap(*this); + } +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES + + //! Create a full circular_buffer filled with a copy of the range. + /*! + \pre Valid range [first, last).
+ first and last have to meet the requirements of + InputIterator. + \post capacity() == std::distance(first, last) \&\& full() \&\& (*this)[0]== *first \&\& + (*this)[1] == *(first + 1) \&\& ... \&\& (*this)[std::distance(first, last) - 1] == *(last - 1) + \param first The beginning of the range to be copied. + \param last The end of the range to be copied. + \param alloc The allocator. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Complexity + Linear (in the std::distance(first, last)). + */ + template + circular_buffer(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()) + : base(boost::empty_init_t(), alloc) { + initialize(first, last, is_integral()); + } + + //! Create a circular_buffer with the specified capacity and filled with a copy of the range. + /*! + \pre Valid range [first, last).
+ first and last have to meet the requirements of + InputIterator. + \post capacity() == buffer_capacity \&\& size() \<= std::distance(first, last) \&\& + (*this)[0]== *(last - buffer_capacity) \&\& (*this)[1] == *(last - buffer_capacity + 1) \&\& ... \&\& + (*this)[buffer_capacity - 1] == *(last - 1)

+ If the number of items to be copied from the range [first, last) is greater than the + specified buffer_capacity then only elements from the range + [last - buffer_capacity, last) will be copied. + \param buffer_capacity The capacity of the created circular_buffer. + \param first The beginning of the range to be copied. + \param last The end of the range to be copied. + \param alloc The allocator. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Complexity + Linear (in std::distance(first, last); in + min[capacity, std::distance(first, last)] if the InputIterator is a + RandomAccessIterator). + */ + template + circular_buffer(capacity_type buffer_capacity, InputIterator first, InputIterator last, + const allocator_type& alloc = allocator_type()) + : base(boost::empty_init_t(), alloc) { + initialize(buffer_capacity, first, last, is_integral()); + } + + //! The destructor. + /*! + Destroys the circular_buffer. + \throws Nothing. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer (including iterators equal to + end()). + \par Complexity + Constant (in the size of the circular_buffer) for scalar types; linear for other types. + \sa clear() + */ + ~circular_buffer() BOOST_NOEXCEPT { + destroy(); +#if BOOST_CB_ENABLE_DEBUG + invalidate_all_iterators(); +#endif + } + +public: +// Assign methods + + //! The assign operator. + /*! + Makes this circular_buffer to become a copy of the specified circular_buffer. + \post *this == cb + \param cb The circular_buffer to be copied. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Exception Safety + Strong. + \par Iterator Invalidation + Invalidates all iterators pointing to this circular_buffer (except iterators equal to + end()). + \par Complexity + Linear (in the size of cb). + \sa \link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink, + \link assign(capacity_type, size_type, param_value_type) + assign(capacity_type, size_type, const_reference)\endlink, + assign(InputIterator, InputIterator), + assign(capacity_type, InputIterator, InputIterator) + */ + circular_buffer& operator = (const circular_buffer& cb) { + if (this == &cb) + return *this; + pointer buff = allocate(cb.capacity()); + BOOST_TRY { + reset(buff, cb_details::uninitialized_copy(cb.begin(), cb.end(), buff, alloc()), cb.capacity()); + } BOOST_CATCH(...) { + deallocate(buff, cb.capacity()); + BOOST_RETHROW + } + BOOST_CATCH_END + return *this; + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + /*! \brief Move assigns content of cb to *this, leaving cb empty. + \pre C++ compiler with rvalue references support. + \post cb.empty() + \param cb circular_buffer to 'steal' value from. + \throws Nothing. + \par Complexity + Constant. + */ + circular_buffer& operator = (circular_buffer&& cb) BOOST_NOEXCEPT { + cb.swap(*this); // now `this` holds `cb` + circular_buffer(get_allocator()) // temporary that holds initial `cb` allocator + .swap(cb); // makes `cb` empty + return *this; + } +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES + + //! Assign n items into the circular_buffer. + /*! + The content of the circular_buffer will be removed and replaced with n copies of the + item. + \post capacity() == n \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item \&\& ... \&\& + (*this) [n - 1] == item + \param n The number of elements the circular_buffer will be filled with. + \param item The element the circular_buffer will be filled with. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer (except iterators equal to + end()). + \par Complexity + Linear (in the n). + \sa \link operator=(const circular_buffer&) operator=\endlink, + \link assign(capacity_type, size_type, param_value_type) + assign(capacity_type, size_type, const_reference)\endlink, + assign(InputIterator, InputIterator), + assign(capacity_type, InputIterator, InputIterator) + */ + void assign(size_type n, param_value_type item) { + assign_n(n, n, cb_details::assign_n(n, item, alloc())); + } + + //! Assign n items into the circular_buffer specifying the capacity. + /*! + The capacity of the circular_buffer will be set to the specified value and the content of the + circular_buffer will be removed and replaced with n copies of the item. + \pre capacity >= n + \post capacity() == buffer_capacity \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item + \&\& ... \&\& (*this) [n - 1] == item + \param buffer_capacity The new capacity. + \param n The number of elements the circular_buffer will be filled with. + \param item The element the circular_buffer will be filled with. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer (except iterators equal to + end()). + \par Complexity + Linear (in the n). + \sa \link operator=(const circular_buffer&) operator=\endlink, + \link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink, + assign(InputIterator, InputIterator), + assign(capacity_type, InputIterator, InputIterator) + */ + void assign(capacity_type buffer_capacity, size_type n, param_value_type item) { + BOOST_CB_ASSERT(buffer_capacity >= n); // check for new capacity lower than n + assign_n(buffer_capacity, n, cb_details::assign_n(n, item, alloc())); + } + + //! Assign a copy of the range into the circular_buffer. + /*! + The content of the circular_buffer will be removed and replaced with copies of elements from the + specified range. + \pre Valid range [first, last).
+ first and last have to meet the requirements of + InputIterator. + \post capacity() == std::distance(first, last) \&\& size() == std::distance(first, last) \&\& + (*this)[0]== *first \&\& (*this)[1] == *(first + 1) \&\& ... \&\& (*this)[std::distance(first, last) - 1] + == *(last - 1) + \param first The beginning of the range to be copied. + \param last The end of the range to be copied. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer (except iterators equal to + end()). + \par Complexity + Linear (in the std::distance(first, last)). + \sa \link operator=(const circular_buffer&) operator=\endlink, + \link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink, + \link assign(capacity_type, size_type, param_value_type) + assign(capacity_type, size_type, const_reference)\endlink, + assign(capacity_type, InputIterator, InputIterator) + */ + template + void assign(InputIterator first, InputIterator last) { + assign(first, last, is_integral()); + } + + //! Assign a copy of the range into the circular_buffer specifying the capacity. + /*! + The capacity of the circular_buffer will be set to the specified value and the content of the + circular_buffer will be removed and replaced with copies of elements from the specified range. + \pre Valid range [first, last).
+ first and last have to meet the requirements of + InputIterator. + \post capacity() == buffer_capacity \&\& size() \<= std::distance(first, last) \&\& + (*this)[0]== *(last - buffer_capacity) \&\& (*this)[1] == *(last - buffer_capacity + 1) \&\& ... \&\& + (*this)[buffer_capacity - 1] == *(last - 1)

+ If the number of items to be copied from the range [first, last) is greater than the + specified buffer_capacity then only elements from the range + [last - buffer_capacity, last) will be copied. + \param buffer_capacity The new capacity. + \param first The beginning of the range to be copied. + \param last The end of the range to be copied. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer (except iterators equal to + end()). + \par Complexity + Linear (in std::distance(first, last); in + min[capacity, std::distance(first, last)] if the InputIterator is a + RandomAccessIterator). + \sa \link operator=(const circular_buffer&) operator=\endlink, + \link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink, + \link assign(capacity_type, size_type, param_value_type) + assign(capacity_type, size_type, const_reference)\endlink, + assign(InputIterator, InputIterator) + */ + template + void assign(capacity_type buffer_capacity, InputIterator first, InputIterator last) { + assign(buffer_capacity, first, last, is_integral()); + } + + //! Swap the contents of two circular_buffers. + /*! + \post this contains elements of cb and vice versa; the capacity of this + equals to the capacity of cb and vice versa. + \param cb The circular_buffer whose content will be swapped. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Invalidates all iterators of both circular_buffers. (On the other hand the iterators still + point to the same elements but within another container. If you want to rely on this feature you have to + turn the Debug Support off otherwise an assertion will report an error if such + invalidated iterator is used.) + \par Complexity + Constant (in the size of the circular_buffer). + \sa swap(circular_buffer&, circular_buffer&) + */ + void swap(circular_buffer& cb) BOOST_NOEXCEPT { + swap_allocator(cb, is_stateless()); + adl_move_swap(m_buff, cb.m_buff); + adl_move_swap(m_end, cb.m_end); + adl_move_swap(m_first, cb.m_first); + adl_move_swap(m_last, cb.m_last); + adl_move_swap(m_size, cb.m_size); +#if BOOST_CB_ENABLE_DEBUG + invalidate_all_iterators(); + cb.invalidate_all_iterators(); +#endif + } + +// push and pop +private: + /*! INTERNAL ONLY */ + template + void push_back_impl(ValT item) { + if (full()) { + if (empty()) + return; + replace(m_last, static_cast(item)); + increment(m_last); + m_first = m_last; + } else { + boost::allocator_construct(alloc(), boost::to_address(m_last), static_cast(item)); + increment(m_last); + ++m_size; + } + } + + /*! INTERNAL ONLY */ + template + void push_front_impl(ValT item) { + BOOST_TRY { + if (full()) { + if (empty()) + return; + decrement(m_first); + replace(m_first, static_cast(item)); + m_last = m_first; + } else { + decrement(m_first); + boost::allocator_construct(alloc(), boost::to_address(m_first), static_cast(item)); + ++m_size; + } + } BOOST_CATCH(...) { + increment(m_first); + BOOST_RETHROW + } + BOOST_CATCH_END + } + +public: + //! Insert a new element at the end of the circular_buffer. + /*! + \post if capacity() > 0 then back() == item
+ If the circular_buffer is full, the first element will be removed. If the capacity is + 0, nothing will be inserted. + \param item The element to be inserted. + \throws Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Does not invalidate any iterators with the exception of iterators pointing to the overwritten element. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link push_front() push_front(const_reference)\endlink, + pop_back(), pop_front() + */ + void push_back(param_value_type item) { + push_back_impl(item); + } + + //! Insert a new element at the end of the circular_buffer using rvalue references or rvalues references emulation. + /*! + \post if capacity() > 0 then back() == item
+ If the circular_buffer is full, the first element will be removed. If the capacity is + 0, nothing will be inserted. + \param item The element to be inserted. + \throws Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Does not invalidate any iterators with the exception of iterators pointing to the overwritten element. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link push_front() push_front(const_reference)\endlink, + pop_back(), pop_front() + */ + void push_back(rvalue_type item) { + push_back_impl(boost::move(item)); + } + + //! Insert a new default-constructed element at the end of the circular_buffer. + /*! + \post if capacity() > 0 then back() == item
+ If the circular_buffer is full, the first element will be removed. If the capacity is + 0, nothing will be inserted. + \throws Whatever T::T() throws. + Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Does not invalidate any iterators with the exception of iterators pointing to the overwritten element. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link push_front() push_front(const_reference)\endlink, + pop_back(), pop_front() + */ + void push_back() { + value_type temp; + push_back(boost::move(temp)); + } + + //! Insert a new element at the beginning of the circular_buffer. + /*! + \post if capacity() > 0 then front() == item
+ If the circular_buffer is full, the last element will be removed. If the capacity is + 0, nothing will be inserted. + \param item The element to be inserted. + \throws Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Does not invalidate any iterators with the exception of iterators pointing to the overwritten element. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link push_back() push_back(const_reference)\endlink, + pop_back(), pop_front() + */ + void push_front(param_value_type item) { + push_front_impl(item); + } + + //! Insert a new element at the beginning of the circular_buffer using rvalue references or rvalues references emulation. + /*! + \post if capacity() > 0 then front() == item
+ If the circular_buffer is full, the last element will be removed. If the capacity is + 0, nothing will be inserted. + \param item The element to be inserted. + \throws Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Does not invalidate any iterators with the exception of iterators pointing to the overwritten element. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link push_back() push_back(const_reference)\endlink, + pop_back(), pop_front() + */ + void push_front(rvalue_type item) { + push_front_impl(boost::move(item)); + } + + //! Insert a new default-constructed element at the beginning of the circular_buffer. + /*! + \post if capacity() > 0 then front() == item
+ If the circular_buffer is full, the last element will be removed. If the capacity is + 0, nothing will be inserted. + \throws Whatever T::T() throws. + Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Does not invalidate any iterators with the exception of iterators pointing to the overwritten element. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link push_back() push_back(const_reference)\endlink, + pop_back(), pop_front() + */ + void push_front() { + value_type temp; + push_front(boost::move(temp)); + } + + //! Remove the last element from the circular_buffer. + /*! + \pre !empty() + \post The last element is removed from the circular_buffer. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Invalidates only iterators pointing to the removed element. + \par Complexity + Constant (in the size of the circular_buffer). + \sa pop_front(), \link push_back() push_back(const_reference)\endlink, + \link push_front() push_front(const_reference)\endlink + */ + void pop_back() { + BOOST_CB_ASSERT(!empty()); // check for empty buffer (back element not available) + decrement(m_last); + destroy_item(m_last); + --m_size; + } + + //! Remove the first element from the circular_buffer. + /*! + \pre !empty() + \post The first element is removed from the circular_buffer. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Invalidates only iterators pointing to the removed element. + \par Complexity + Constant (in the size of the circular_buffer). + \sa pop_back(), \link push_back() push_back(const_reference)\endlink, + \link push_front() push_front(const_reference)\endlink + */ + void pop_front() { + BOOST_CB_ASSERT(!empty()); // check for empty buffer (front element not available) + destroy_item(m_first); + increment(m_first); + --m_size; + } +private: + /*! INTERNAL ONLY */ + template + iterator insert_impl(iterator pos, ValT item) { + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator + iterator b = begin(); + if (full() && pos == b) + return b; + return insert_item(pos, static_cast(item)); + } + +public: +// Insert + + //! Insert an element at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end. + \post The item will be inserted at the position pos.
+ If the circular_buffer is full, the first element will be overwritten. If the + circular_buffer is full and the pos points to begin(), then the + item will not be inserted. If the capacity is 0, nothing will be inserted. + \param pos An iterator specifying the position where the item will be inserted. + \param item The element to be inserted. + \return Iterator to the inserted element or begin() if the item is not inserted. (See + the Effect.) + \throws Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. + Exceptions of move_if_noexcept(T&). + + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements at the insertion point (including pos) and + iterators behind the insertion point (towards the end; except iterators equal to end()). It + also invalidates iterators pointing to the overwritten element. + \par Complexity + Linear (in std::distance(pos, end())). + \sa \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator), + \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator) + */ + iterator insert(iterator pos, param_value_type item) { + return insert_impl(pos, item); + } + + //! Insert an element at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end. + \post The item will be inserted at the position pos.
+ If the circular_buffer is full, the first element will be overwritten. If the + circular_buffer is full and the pos points to begin(), then the + item will not be inserted. If the capacity is 0, nothing will be inserted. + \param pos An iterator specifying the position where the item will be inserted. + \param item The element to be inserted. + \return Iterator to the inserted element or begin() if the item is not inserted. (See + the Effect.) + \throws Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements at the insertion point (including pos) and + iterators behind the insertion point (towards the end; except iterators equal to end()). It + also invalidates iterators pointing to the overwritten element. + \par Complexity + Linear (in std::distance(pos, end())). + \sa \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator), + \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator) + */ + iterator insert(iterator pos, rvalue_type item) { + return insert_impl(pos, boost::move(item)); + } + + //! Insert a default-constructed element at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end. + \post The item will be inserted at the position pos.
+ If the circular_buffer is full, the first element will be overwritten. If the + circular_buffer is full and the pos points to begin(), then the + item will not be inserted. If the capacity is 0, nothing will be inserted. + \param pos An iterator specifying the position where the item will be inserted. + \return Iterator to the inserted element or begin() if the item is not inserted. (See + the Effect.) + \throws Whatever T::T() throws. + Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements at the insertion point (including pos) and + iterators behind the insertion point (towards the end; except iterators equal to end()). It + also invalidates iterators pointing to the overwritten element. + \par Complexity + Linear (in std::distance(pos, end())). + \sa \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator), + \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator) + */ + iterator insert(iterator pos) { + value_type temp; + return insert(pos, boost::move(temp)); + } + + //! Insert n copies of the item at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end. + \post The number of min[n, (pos - begin()) + reserve()] elements will be inserted at the position + pos.
The number of min[pos - begin(), max[0, n - reserve()]] elements will + be overwritten at the beginning of the circular_buffer.
(See Example for the + explanation.) + \param pos An iterator specifying the position where the items will be inserted. + \param n The number of items the to be inserted. + \param item The element whose copies will be inserted. + \throws Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. + Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operations in the Throws section do not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements at the insertion point (including pos) and + iterators behind the insertion point (towards the end; except iterators equal to end()). It + also invalidates iterators pointing to the overwritten elements. + \par Complexity + Linear (in min[capacity(), std::distance(pos, end()) + n]). + \par Example + Consider a circular_buffer with the capacity of 6 and the size of 4. Its internal buffer may + look like the one below.

+ |1|2|3|4| | |
+ p ___^

After inserting 5 elements at the position p:

+ insert(p, (size_t)5, 0);

actually only 4 elements get inserted and elements + 1 and 2 are overwritten. This is due to the fact the insert operation preserves + the capacity. After insertion the internal buffer looks like this:

|0|0|0|0|3|4|
+
For comparison if the capacity would not be preserved the internal buffer would then result in + |1|2|0|0|0|0|0|3|4|. + \sa \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + insert(iterator, InputIterator, InputIterator), + \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator) + */ + void insert(iterator pos, size_type n, param_value_type item) { + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator + if (n == 0) + return; + size_type copy = capacity() - (end() - pos); + if (copy == 0) + return; + if (n > copy) + n = copy; + insert_n(pos, n, cb_details::item_wrapper(item)); + } + + //! Insert the range [first, last) at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end.
+ Valid range [first, last) where first and last meet the + requirements of an InputIterator. + \post Elements from the range + [first + max[0, distance(first, last) - (pos - begin()) - reserve()], last) will be + inserted at the position pos.
The number of min[pos - begin(), max[0, + distance(first, last) - reserve()]] elements will be overwritten at the beginning of the + circular_buffer.
(See Example for the explanation.) + \param pos An iterator specifying the position where the range will be inserted. + \param first The beginning of the range to be inserted. + \param last The end of the range to be inserted. + \throws Whatever T::T(const T&) throws if the InputIterator is not a move iterator. + Whatever T::operator = (const T&) throws if the InputIterator is not a move iterator. + Whatever T::T(T&&) throws if the InputIterator is a move iterator. + Whatever T::operator = (T&&) throws if the InputIterator is a move iterator. + \par Exception Safety + Basic; no-throw if the operations in the Throws section do not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements at the insertion point (including pos) and + iterators behind the insertion point (towards the end; except iterators equal to end()). It + also invalidates iterators pointing to the overwritten elements. + \par Complexity + Linear (in [std::distance(pos, end()) + std::distance(first, last)]; in + min[capacity(), std::distance(pos, end()) + std::distance(first, last)] if the + InputIterator is a + RandomAccessIterator). + \par Example + Consider a circular_buffer with the capacity of 6 and the size of 4. Its internal buffer may + look like the one below.

+ |1|2|3|4| | |
+ p ___^

After inserting a range of elements at the position p:

+ int array[] = { 5, 6, 7, 8, 9 };
insert(p, array, array + 5);

+ actually only elements 6, 7, 8 and 9 from the + specified range get inserted and elements 1 and 2 are overwritten. This is due + to the fact the insert operation preserves the capacity. After insertion the internal buffer looks like + this:

|6|7|8|9|3|4|

For comparison if the capacity would not be preserved the + internal buffer would then result in |1|2|5|6|7|8|9|3|4|. + \sa \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, \link rinsert(iterator, param_value_type) + rinsert(iterator, value_type)\endlink, \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator) + */ + template + void insert(iterator pos, InputIterator first, InputIterator last) { + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator + insert(pos, first, last, is_integral()); + } + +private: + /*! INTERNAL ONLY */ + template + iterator rinsert_impl(iterator pos, ValT item) { + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator + if (full() && pos.m_it == 0) + return end(); + if (pos == begin()) { + BOOST_TRY { + decrement(m_first); + construct_or_replace(!full(), m_first, static_cast(item)); + } BOOST_CATCH(...) { + increment(m_first); + BOOST_RETHROW + } + BOOST_CATCH_END + pos.m_it = m_first; + } else { + pointer src = m_first; + pointer dest = m_first; + decrement(dest); + pos.m_it = map_pointer(pos.m_it); + bool construct = !full(); + BOOST_TRY { + while (src != pos.m_it) { + construct_or_replace(construct, dest, boost::move_if_noexcept(*src)); + increment(src); + increment(dest); + construct = false; + } + decrement(pos.m_it); + replace(pos.m_it, static_cast(item)); + } BOOST_CATCH(...) { + if (!construct && !full()) { + decrement(m_first); + ++m_size; + } + BOOST_RETHROW + } + BOOST_CATCH_END + decrement(m_first); + } + if (full()) + m_last = m_first; + else + ++m_size; + return iterator(this, pos.m_it); + } + +public: + + //! Insert an element before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end. + \post The item will be inserted before the position pos.
+ If the circular_buffer is full, the last element will be overwritten. If the + circular_buffer is full and the pos points to end(), then the + item will not be inserted. If the capacity is 0, nothing will be inserted. + \param pos An iterator specifying the position before which the item will be inserted. + \param item The element to be inserted. + \return Iterator to the inserted element or end() if the item is not inserted. (See + the Effect.) + \throws Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. + Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operations in the Throws section do not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements before the insertion point (towards the beginning and + excluding pos). It also invalidates iterators pointing to the overwritten element. + \par Complexity + Linear (in std::distance(begin(), pos)). + \sa \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator), + \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + iterator rinsert(iterator pos, param_value_type item) { + return rinsert_impl(pos, item); + } + + //! Insert an element before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end. + \post The item will be inserted before the position pos.
+ If the circular_buffer is full, the last element will be overwritten. If the + circular_buffer is full and the pos points to end(), then the + item will not be inserted. If the capacity is 0, nothing will be inserted. + \param pos An iterator specifying the position before which the item will be inserted. + \param item The element to be inserted. + \return Iterator to the inserted element or end() if the item is not inserted. (See + the Effect.) + \throws Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operations in the Throws section do not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements before the insertion point (towards the beginning and + excluding pos). It also invalidates iterators pointing to the overwritten element. + \par Complexity + Linear (in std::distance(begin(), pos)). + \sa \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator), + \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + iterator rinsert(iterator pos, rvalue_type item) { + return rinsert_impl(pos, boost::move(item)); + } + + //! Insert an element before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end. + \post The item will be inserted before the position pos.
+ If the circular_buffer is full, the last element will be overwritten. If the + circular_buffer is full and the pos points to end(), then the + item will not be inserted. If the capacity is 0, nothing will be inserted. + \param pos An iterator specifying the position before which the item will be inserted. + \return Iterator to the inserted element or end() if the item is not inserted. (See + the Effect.) + \throws Whatever T::T() throws. + Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operations in the Throws section do not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements before the insertion point (towards the beginning and + excluding pos). It also invalidates iterators pointing to the overwritten element. + \par Complexity + Linear (in std::distance(begin(), pos)). + \sa \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator), + \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + iterator rinsert(iterator pos) { + value_type temp; + return rinsert(pos, boost::move(temp)); + } + + //! Insert n copies of the item before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end. + \post The number of min[n, (end() - pos) + reserve()] elements will be inserted before the + position pos.
The number of min[end() - pos, max[0, n - reserve()]] elements + will be overwritten at the end of the circular_buffer.
(See Example for the + explanation.) + \param pos An iterator specifying the position where the items will be inserted. + \param n The number of items the to be inserted. + \param item The element whose copies will be inserted. + \throws Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. + Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operations in the Throws section do not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements before the insertion point (towards the beginning and + excluding pos). It also invalidates iterators pointing to the overwritten elements. + \par Complexity + Linear (in min[capacity(), std::distance(begin(), pos) + n]). + \par Example + Consider a circular_buffer with the capacity of 6 and the size of 4. Its internal buffer may + look like the one below.

+ |1|2|3|4| | |
+ p ___^

After inserting 5 elements before the position p:

+ rinsert(p, (size_t)5, 0);

actually only 4 elements get inserted and elements + 3 and 4 are overwritten. This is due to the fact the rinsert operation preserves + the capacity. After insertion the internal buffer looks like this:

|1|2|0|0|0|0|
+
For comparison if the capacity would not be preserved the internal buffer would then result in + |1|2|0|0|0|0|0|3|4|. + \sa \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator), + \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + void rinsert(iterator pos, size_type n, param_value_type item) { + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator + rinsert_n(pos, n, cb_details::item_wrapper(item)); + } + + //! Insert the range [first, last) before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end.
+ Valid range [first, last) where first and last meet the + requirements of an InputIterator. + \post Elements from the range + [first, last - max[0, distance(first, last) - (end() - pos) - reserve()]) will be inserted + before the position pos.
The number of min[end() - pos, max[0, + distance(first, last) - reserve()]] elements will be overwritten at the end of the + circular_buffer.
(See Example for the explanation.) + \param pos An iterator specifying the position where the range will be inserted. + \param first The beginning of the range to be inserted. + \param last The end of the range to be inserted. + \throws Whatever T::T(const T&) throws if the InputIterator is not a move iterator. + Whatever T::operator = (const T&) throws if the InputIterator is not a move iterator. + Whatever T::T(T&&) throws if the InputIterator is a move iterator. + Whatever T::operator = (T&&) throws if the InputIterator is a move iterator. + \par Exception Safety + Basic; no-throw if the operations in the Throws section do not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements before the insertion point (towards the beginning and + excluding pos). It also invalidates iterators pointing to the overwritten elements. + \par Complexity + Linear (in [std::distance(begin(), pos) + std::distance(first, last)]; in + min[capacity(), std::distance(begin(), pos) + std::distance(first, last)] if the + InputIterator is a + RandomAccessIterator). + \par Example + Consider a circular_buffer with the capacity of 6 and the size of 4. Its internal buffer may + look like the one below.

+ |1|2|3|4| | |
+ p ___^

After inserting a range of elements before the position p:

+ int array[] = { 5, 6, 7, 8, 9 };
insert(p, array, array + 5);

+ actually only elements 5, 6, 7 and 8 from the + specified range get inserted and elements 3 and 4 are overwritten. This is due + to the fact the rinsert operation preserves the capacity. After insertion the internal buffer looks like + this:

|1|2|5|6|7|8|

For comparison if the capacity would not be preserved the + internal buffer would then result in |1|2|5|6|7|8|9|3|4|. + \sa \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, \link insert(iterator, param_value_type) + insert(iterator, value_type)\endlink, \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + template + void rinsert(iterator pos, InputIterator first, InputIterator last) { + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator + rinsert(pos, first, last, is_integral()); + } + +// Erase + + //! Remove an element at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer (but not an + end()). + \post The element at the position pos is removed. + \param pos An iterator pointing at the element to be removed. + \return Iterator to the first element remaining beyond the removed element or end() if no such + element exists. + \throws Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the erased element and iterators pointing to the elements behind + the erased element (towards the end; except iterators equal to end()). + \par Complexity + Linear (in std::distance(pos, end())). + \sa erase(iterator, iterator), rerase(iterator), + rerase(iterator, iterator), erase_begin(size_type), + erase_end(size_type), clear() + */ + iterator erase(iterator pos) { + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(pos.m_it != 0); // check for iterator pointing to end() + pointer next = pos.m_it; + increment(next); + for (pointer p = pos.m_it; next != m_last; p = next, increment(next)) + replace(p, boost::move_if_noexcept(*next)); + decrement(m_last); + destroy_item(m_last); + --m_size; +#if BOOST_CB_ENABLE_DEBUG + return m_last == pos.m_it ? end() : iterator(this, pos.m_it); +#else + return m_last == pos.m_it ? end() : pos; +#endif + } + + //! Erase the range [first, last). + /*! + \pre Valid range [first, last). + \post The elements from the range [first, last) are removed. (If first == last + nothing is removed.) + \param first The beginning of the range to be removed. + \param last The end of the range to be removed. + \return Iterator to the first element remaining beyond the removed elements or end() if no such + element exists. + \throws Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the erased elements and iterators pointing to the elements behind + the erased range (towards the end; except iterators equal to end()). + \par Complexity + Linear (in std::distance(first, end())). + \sa erase(iterator), rerase(iterator), rerase(iterator, iterator), + erase_begin(size_type), erase_end(size_type), clear() + */ + iterator erase(iterator first, iterator last) { + BOOST_CB_ASSERT(first.is_valid(this)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(last.is_valid(this)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(first <= last); // check for wrong range + if (first == last) + return first; + pointer p = first.m_it; + while (last.m_it != 0) + replace((first++).m_it, boost::move_if_noexcept(*last++)); + do { + decrement(m_last); + destroy_item(m_last); + --m_size; + } while(m_last != first.m_it); + return m_last == p ? end() : iterator(this, p); + } + + //! Remove an element at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer (but not an + end()). + \post The element at the position pos is removed. + \param pos An iterator pointing at the element to be removed. + \return Iterator to the first element remaining in front of the removed element or begin() if no + such element exists. + \throws Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the erased element and iterators pointing to the elements in front of + the erased element (towards the beginning). + \par Complexity + Linear (in std::distance(begin(), pos)). + \note This method is symmetric to the erase(iterator) method and is more effective than + erase(iterator) if the iterator pos is close to the beginning of the + circular_buffer. (See the Complexity.) + \sa erase(iterator), erase(iterator, iterator), + rerase(iterator, iterator), erase_begin(size_type), + erase_end(size_type), clear() + */ + iterator rerase(iterator pos) { + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(pos.m_it != 0); // check for iterator pointing to end() + pointer prev = pos.m_it; + pointer p = prev; + for (decrement(prev); p != m_first; p = prev, decrement(prev)) + replace(p, boost::move_if_noexcept(*prev)); + destroy_item(m_first); + increment(m_first); + --m_size; +#if BOOST_CB_ENABLE_DEBUG + return p == pos.m_it ? begin() : iterator(this, pos.m_it); +#else + return p == pos.m_it ? begin() : pos; +#endif + } + + //! Erase the range [first, last). + /*! + \pre Valid range [first, last). + \post The elements from the range [first, last) are removed. (If first == last + nothing is removed.) + \param first The beginning of the range to be removed. + \param last The end of the range to be removed. + \return Iterator to the first element remaining in front of the removed elements or begin() if no + such element exists. + \throws Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the erased elements and iterators pointing to the elements in front of + the erased range (towards the beginning). + \par Complexity + Linear (in std::distance(begin(), last)). + \note This method is symmetric to the erase(iterator, iterator) method and is more effective than + erase(iterator, iterator) if std::distance(begin(), first) is lower that + std::distance(last, end()). + \sa erase(iterator), erase(iterator, iterator), rerase(iterator), + erase_begin(size_type), erase_end(size_type), clear() + */ + iterator rerase(iterator first, iterator last) { + BOOST_CB_ASSERT(first.is_valid(this)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(last.is_valid(this)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(first <= last); // check for wrong range + if (first == last) + return first; + pointer p = map_pointer(last.m_it); + last.m_it = p; + while (first.m_it != m_first) { + decrement(first.m_it); + decrement(p); + replace(p, boost::move_if_noexcept(*first.m_it)); + } + do { + destroy_item(m_first); + increment(m_first); + --m_size; + } while(m_first != p); + if (m_first == last.m_it) + return begin(); + decrement(last.m_it); + return iterator(this, last.m_it); + } + + //! Remove first n elements (with constant complexity for scalar types). + /*! + \pre n \<= size() + \post The n elements at the beginning of the circular_buffer will be removed. + \param n The number of elements to be removed. + \throws Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. (I.e. no throw in + case of scalars.) + \par Iterator Invalidation + Invalidates iterators pointing to the first n erased elements. + \par Complexity + Constant (in n) for scalar types; linear for other types. + \note This method has been specially designed for types which do not require an explicit destructruction (e.g. + integer, float or a pointer). For these scalar types a call to a destructor is not required which makes + it possible to implement the "erase from beginning" operation with a constant complexity. For non-sacalar + types the complexity is linear (hence the explicit destruction is needed) and the implementation is + actually equivalent to + \link circular_buffer::rerase(iterator, iterator) rerase(begin(), begin() + n)\endlink. + \sa erase(iterator), erase(iterator, iterator), + rerase(iterator), rerase(iterator, iterator), + erase_end(size_type), clear() + */ + void erase_begin(size_type n) { + BOOST_CB_ASSERT(n <= size()); // check for n greater than size +#if BOOST_CB_ENABLE_DEBUG + erase_begin(n, false_type()); +#else + erase_begin(n, is_scalar()); +#endif + } + + //! Remove last n elements (with constant complexity for scalar types). + /*! + \pre n \<= size() + \post The n elements at the end of the circular_buffer will be removed. + \param n The number of elements to be removed. + \throws Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. (I.e. no throw in + case of scalars.) + \par Iterator Invalidation + Invalidates iterators pointing to the last n erased elements. + \par Complexity + Constant (in n) for scalar types; linear for other types. + \note This method has been specially designed for types which do not require an explicit destructruction (e.g. + integer, float or a pointer). For these scalar types a call to a destructor is not required which makes + it possible to implement the "erase from end" operation with a constant complexity. For non-sacalar + types the complexity is linear (hence the explicit destruction is needed) and the implementation is + actually equivalent to + \link circular_buffer::erase(iterator, iterator) erase(end() - n, end())\endlink. + \sa erase(iterator), erase(iterator, iterator), + rerase(iterator), rerase(iterator, iterator), + erase_begin(size_type), clear() + */ + void erase_end(size_type n) { + BOOST_CB_ASSERT(n <= size()); // check for n greater than size +#if BOOST_CB_ENABLE_DEBUG + erase_end(n, false_type()); +#else + erase_end(n, is_scalar()); +#endif + } + + //! Remove all stored elements from the circular_buffer. + /*! + \post size() == 0 + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer (except iterators equal to + end()). + \par Complexity + Constant (in the size of the circular_buffer) for scalar types; linear for other types. + \sa ~circular_buffer(), erase(iterator), erase(iterator, iterator), + rerase(iterator), rerase(iterator, iterator), + erase_begin(size_type), erase_end(size_type) + */ + void clear() BOOST_NOEXCEPT { + destroy_content(); + m_size = 0; + } + +private: +// Helper methods + + /*! INTERNAL ONLY */ + void check_position(size_type index) const { + if (index >= size()) + throw_exception(std::out_of_range("circular_buffer")); + } + + /*! INTERNAL ONLY */ + template + void increment(Pointer& p) const { + if (++p == m_end) + p = m_buff; + } + + /*! INTERNAL ONLY */ + template + void decrement(Pointer& p) const { + if (p == m_buff) + p = m_end; + --p; + } + + /*! INTERNAL ONLY */ + template + Pointer add(Pointer p, difference_type n) const { + return p + (n < (m_end - p) ? n : n - (m_end - m_buff)); + } + + /*! INTERNAL ONLY */ + template + Pointer sub(Pointer p, difference_type n) const { + return p - (n > (p - m_buff) ? n - (m_end - m_buff) : n); + } + + /*! INTERNAL ONLY */ + pointer map_pointer(pointer p) const { return p == 0 ? m_last : p; } + + /*! INTERNAL ONLY */ + const Alloc& alloc() const { + return base::get(); + } + + /*! INTERNAL ONLY */ + Alloc& alloc() { + return base::get(); + } + + /*! INTERNAL ONLY */ + pointer allocate(size_type n) { + if (n > max_size()) + throw_exception(std::length_error("circular_buffer")); +#if BOOST_CB_ENABLE_DEBUG + pointer p = (n == 0) ? 0 : alloc().allocate(n); + cb_details::do_fill_uninitialized_memory(p, sizeof(value_type) * n); + return p; +#else + return (n == 0) ? 0 : alloc().allocate(n); +#endif + } + + /*! INTERNAL ONLY */ + void deallocate(pointer p, size_type n) { + if (p != 0) + alloc().deallocate(p, n); + } + + /*! INTERNAL ONLY */ + bool is_uninitialized(const_pointer p) const BOOST_NOEXCEPT { + return (m_first < m_last) + ? (p >= m_last || p < m_first) + : (p >= m_last && p < m_first); + } + + /*! INTERNAL ONLY */ + void replace(pointer pos, param_value_type item) { + *pos = item; +#if BOOST_CB_ENABLE_DEBUG + invalidate_iterators(iterator(this, pos)); +#endif + } + + /*! INTERNAL ONLY */ + void replace(pointer pos, rvalue_type item) { + *pos = boost::move(item); +#if BOOST_CB_ENABLE_DEBUG + invalidate_iterators(iterator(this, pos)); +#endif + } + + /*! INTERNAL ONLY */ + void construct_or_replace(bool construct, pointer pos, param_value_type item) { + if (construct) + boost::allocator_construct(alloc(), boost::to_address(pos), item); + else + replace(pos, item); + } + + /*! INTERNAL ONLY */ + void construct_or_replace(bool construct, pointer pos, rvalue_type item) { + if (construct) + boost::allocator_construct(alloc(), boost::to_address(pos), boost::move(item)); + else + replace(pos, boost::move(item)); + } + + /*! INTERNAL ONLY */ + void destroy_item(pointer p) { + boost::allocator_destroy(alloc(), boost::to_address(p)); +#if BOOST_CB_ENABLE_DEBUG + invalidate_iterators(iterator(this, p)); + cb_details::do_fill_uninitialized_memory(p, sizeof(value_type)); +#endif + } + + /*! INTERNAL ONLY */ + void destroy_if_constructed(pointer pos) { + if (is_uninitialized(pos)) + destroy_item(pos); + } + + /*! INTERNAL ONLY */ + void destroy_content() { +#if BOOST_CB_ENABLE_DEBUG + destroy_content(false_type()); +#else + destroy_content(is_scalar()); +#endif + } + + /*! INTERNAL ONLY */ + void destroy_content(const true_type&) { + m_first = add(m_first, size()); + } + + /*! INTERNAL ONLY */ + void destroy_content(const false_type&) { + for (size_type ii = 0; ii < size(); ++ii, increment(m_first)) + destroy_item(m_first); + } + + /*! INTERNAL ONLY */ + void destroy() BOOST_NOEXCEPT { + destroy_content(); + deallocate(m_buff, capacity()); +#if BOOST_CB_ENABLE_DEBUG + m_buff = 0; + m_first = 0; + m_last = 0; + m_end = 0; +#endif + } + + /*! INTERNAL ONLY */ + void initialize_buffer(capacity_type buffer_capacity) { + m_buff = allocate(buffer_capacity); + m_end = m_buff + buffer_capacity; + } + + /*! INTERNAL ONLY */ + void initialize_buffer(capacity_type buffer_capacity, param_value_type item) { + initialize_buffer(buffer_capacity); + BOOST_TRY { + cb_details::uninitialized_fill_n_with_alloc(m_buff, size(), item, alloc()); + } BOOST_CATCH(...) { + deallocate(m_buff, size()); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + /*! INTERNAL ONLY */ + template + void initialize(IntegralType n, IntegralType item, const true_type&) { + m_size = static_cast(n); + initialize_buffer(size(), item); + m_first = m_last = m_buff; + } + + /*! INTERNAL ONLY */ + template + void initialize(Iterator first, Iterator last, const false_type&) { + BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581)) + initialize(first, last, std::iterator_traits::iterator_category()); +#else + initialize(first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits::iterator_category()); +#endif + } + + /*! INTERNAL ONLY */ + template + void initialize(InputIterator first, InputIterator last, const std::input_iterator_tag&) { + BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS // check if the STL provides templated iterator constructors + // for containers + std::deque tmp(first, last, alloc()); + size_type distance = tmp.size(); + initialize(distance, boost::make_move_iterator(tmp.begin()), boost::make_move_iterator(tmp.end()), distance); + } + + /*! INTERNAL ONLY */ + template + void initialize(ForwardIterator first, ForwardIterator last, const std::forward_iterator_tag&) { + BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range + size_type distance = std::distance(first, last); + initialize(distance, first, last, distance); + } + + /*! INTERNAL ONLY */ + template + void initialize(capacity_type buffer_capacity, IntegralType n, IntegralType item, const true_type&) { + BOOST_CB_ASSERT(buffer_capacity >= static_cast(n)); // check for capacity lower than n + m_size = static_cast(n); + initialize_buffer(buffer_capacity, item); + m_first = m_buff; + m_last = buffer_capacity == size() ? m_buff : m_buff + size(); + } + + /*! INTERNAL ONLY */ + template + void initialize(capacity_type buffer_capacity, Iterator first, Iterator last, const false_type&) { + BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581)) + initialize(buffer_capacity, first, last, std::iterator_traits::iterator_category()); +#else + initialize(buffer_capacity, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits::iterator_category()); +#endif + } + + /*! INTERNAL ONLY */ + template + void initialize(capacity_type buffer_capacity, + InputIterator first, + InputIterator last, + const std::input_iterator_tag&) { + initialize_buffer(buffer_capacity); + m_first = m_last = m_buff; + m_size = 0; + if (buffer_capacity == 0) + return; + while (first != last && !full()) { + boost::allocator_construct(alloc(), boost::to_address(m_last), *first++); + increment(m_last); + ++m_size; + } + while (first != last) { + replace(m_last, *first++); + increment(m_last); + m_first = m_last; + } + } + + /*! INTERNAL ONLY */ + template + void initialize(capacity_type buffer_capacity, + ForwardIterator first, + ForwardIterator last, + const std::forward_iterator_tag&) { + BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range + initialize(buffer_capacity, first, last, std::distance(first, last)); + } + + /*! INTERNAL ONLY */ + template + void initialize(capacity_type buffer_capacity, + ForwardIterator first, + ForwardIterator last, + size_type distance) { + initialize_buffer(buffer_capacity); + m_first = m_buff; + if (distance > buffer_capacity) { + std::advance(first, distance - buffer_capacity); + m_size = buffer_capacity; + } else { + m_size = distance; + } + BOOST_TRY { + m_last = cb_details::uninitialized_copy(first, last, m_buff, alloc()); + } BOOST_CATCH(...) { + deallocate(m_buff, buffer_capacity); + BOOST_RETHROW + } + BOOST_CATCH_END + if (m_last == m_end) + m_last = m_buff; + } + + /*! INTERNAL ONLY */ + void reset(pointer buff, pointer last, capacity_type new_capacity) { + destroy(); + m_size = last - buff; + m_first = m_buff = buff; + m_end = m_buff + new_capacity; + m_last = last == m_end ? m_buff : last; + } + + /*! INTERNAL ONLY */ + void swap_allocator(circular_buffer&, const true_type&) { + // Swap is not needed because allocators have no state. + } + + /*! INTERNAL ONLY */ + void swap_allocator(circular_buffer& cb, const false_type&) { + adl_move_swap(alloc(), cb.alloc()); + } + + /*! INTERNAL ONLY */ + template + void assign(IntegralType n, IntegralType item, const true_type&) { + assign(static_cast(n), static_cast(item)); + } + + /*! INTERNAL ONLY */ + template + void assign(Iterator first, Iterator last, const false_type&) { + BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581)) + assign(first, last, std::iterator_traits::iterator_category()); +#else + assign(first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits::iterator_category()); +#endif + } + + /*! INTERNAL ONLY */ + template + void assign(InputIterator first, InputIterator last, const std::input_iterator_tag&) { + BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS // check if the STL provides templated iterator constructors + // for containers + std::deque tmp(first, last, alloc()); + size_type distance = tmp.size(); + assign_n(distance, distance, + cb_details::make_assign_range + (boost::make_move_iterator(tmp.begin()), boost::make_move_iterator(tmp.end()), alloc())); + } + + /*! INTERNAL ONLY */ + template + void assign(ForwardIterator first, ForwardIterator last, const std::forward_iterator_tag&) { + BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range + size_type distance = std::distance(first, last); + assign_n(distance, distance, cb_details::make_assign_range(first, last, alloc())); + } + + /*! INTERNAL ONLY */ + template + void assign(capacity_type new_capacity, IntegralType n, IntegralType item, const true_type&) { + assign(new_capacity, static_cast(n), static_cast(item)); + } + + /*! INTERNAL ONLY */ + template + void assign(capacity_type new_capacity, Iterator first, Iterator last, const false_type&) { + BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581)) + assign(new_capacity, first, last, std::iterator_traits::iterator_category()); +#else + assign(new_capacity, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits::iterator_category()); +#endif + } + + /*! INTERNAL ONLY */ + template + void assign(capacity_type new_capacity, InputIterator first, InputIterator last, const std::input_iterator_tag&) { + if (new_capacity == capacity()) { + clear(); + insert(begin(), first, last); + } else { + circular_buffer tmp(new_capacity, first, last, alloc()); + tmp.swap(*this); + } + } + + /*! INTERNAL ONLY */ + template + void assign(capacity_type new_capacity, ForwardIterator first, ForwardIterator last, + const std::forward_iterator_tag&) { + BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range + size_type distance = std::distance(first, last); + if (distance > new_capacity) { + std::advance(first, distance - new_capacity); + distance = new_capacity; + } + assign_n(new_capacity, distance, + cb_details::make_assign_range(first, last, alloc())); + } + + /*! INTERNAL ONLY */ + template + void assign_n(capacity_type new_capacity, size_type n, const Functor& fnc) { + if (new_capacity == capacity()) { + destroy_content(); + BOOST_TRY { + fnc(m_buff); + } BOOST_CATCH(...) { + m_size = 0; + BOOST_RETHROW + } + BOOST_CATCH_END + } else { + pointer buff = allocate(new_capacity); + BOOST_TRY { + fnc(buff); + } BOOST_CATCH(...) { + deallocate(buff, new_capacity); + BOOST_RETHROW + } + BOOST_CATCH_END + destroy(); + m_buff = buff; + m_end = m_buff + new_capacity; + } + m_size = n; + m_first = m_buff; + m_last = add(m_buff, size()); + } + + /*! INTERNAL ONLY */ + template + iterator insert_item(const iterator& pos, ValT item) { + pointer p = pos.m_it; + if (p == 0) { + construct_or_replace(!full(), m_last, static_cast(item)); + p = m_last; + } else { + pointer src = m_last; + pointer dest = m_last; + bool construct = !full(); + BOOST_TRY { + while (src != p) { + decrement(src); + construct_or_replace(construct, dest, boost::move_if_noexcept(*src)); + decrement(dest); + construct = false; + } + replace(p, static_cast(item)); + } BOOST_CATCH(...) { + if (!construct && !full()) { + increment(m_last); + ++m_size; + } + BOOST_RETHROW + } + BOOST_CATCH_END + } + increment(m_last); + if (full()) + m_first = m_last; + else + ++m_size; + return iterator(this, p); + } + + /*! INTERNAL ONLY */ + template + void insert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) { + insert(pos, static_cast(n), static_cast(item)); + } + + /*! INTERNAL ONLY */ + template + void insert(const iterator& pos, Iterator first, Iterator last, const false_type&) { + BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581)) + insert(pos, first, last, std::iterator_traits::iterator_category()); +#else + insert(pos, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits::iterator_category()); +#endif + } + + /*! INTERNAL ONLY */ + template + void insert(iterator pos, InputIterator first, InputIterator last, const std::input_iterator_tag&) { + if (!full() || pos != begin()) { + for (;first != last; ++pos) + pos = insert(pos, *first++); + } + } + + /*! INTERNAL ONLY */ + template + void insert(const iterator& pos, ForwardIterator first, ForwardIterator last, const std::forward_iterator_tag&) { + BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range + size_type n = std::distance(first, last); + if (n == 0) + return; + size_type copy = capacity() - (end() - pos); + if (copy == 0) + return; + if (n > copy) { + std::advance(first, n - copy); + n = copy; + } + insert_n(pos, n, cb_details::iterator_wrapper(first)); + } + + /*! INTERNAL ONLY */ + template + void insert_n(const iterator& pos, size_type n, const Wrapper& wrapper) { + size_type construct = reserve(); + if (construct > n) + construct = n; + if (pos.m_it == 0) { + size_type ii = 0; + pointer p = m_last; + BOOST_TRY { + for (; ii < construct; ++ii, increment(p)) + boost::allocator_construct(alloc(), boost::to_address(p), *wrapper()); + for (;ii < n; ++ii, increment(p)) + replace(p, *wrapper()); + } BOOST_CATCH(...) { + size_type constructed = (std::min)(ii, construct); + m_last = add(m_last, constructed); + m_size += constructed; + BOOST_RETHROW + } + BOOST_CATCH_END + } else { + pointer src = m_last; + pointer dest = add(m_last, n - 1); + pointer p = pos.m_it; + size_type ii = 0; + BOOST_TRY { + while (src != pos.m_it) { + decrement(src); + construct_or_replace(is_uninitialized(dest), dest, *src); + decrement(dest); + } + for (; ii < n; ++ii, increment(p)) + construct_or_replace(is_uninitialized(p), p, *wrapper()); + } BOOST_CATCH(...) { + for (p = add(m_last, n - 1); p != dest; decrement(p)) + destroy_if_constructed(p); + for (n = 0, p = pos.m_it; n < ii; ++n, increment(p)) + destroy_if_constructed(p); + BOOST_RETHROW + } + BOOST_CATCH_END + } + m_last = add(m_last, n); + m_first = add(m_first, n - construct); + m_size += construct; + } + + /*! INTERNAL ONLY */ + template + void rinsert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) { + rinsert(pos, static_cast(n), static_cast(item)); + } + + /*! INTERNAL ONLY */ + template + void rinsert(const iterator& pos, Iterator first, Iterator last, const false_type&) { + BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581)) + rinsert(pos, first, last, std::iterator_traits::iterator_category()); +#else + rinsert(pos, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits::iterator_category()); +#endif + } + + /*! INTERNAL ONLY */ + template + void rinsert(iterator pos, InputIterator first, InputIterator last, const std::input_iterator_tag&) { + if (!full() || pos.m_it != 0) { + for (;first != last; ++pos) { + pos = rinsert(pos, *first++); + if (pos.m_it == 0) + break; + } + } + } + + /*! INTERNAL ONLY */ + template + void rinsert(const iterator& pos, ForwardIterator first, ForwardIterator last, const std::forward_iterator_tag&) { + BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range + rinsert_n(pos, std::distance(first, last), cb_details::iterator_wrapper(first)); + } + + /*! INTERNAL ONLY */ + template + void rinsert_n(const iterator& pos, size_type n, const Wrapper& wrapper) { + if (n == 0) + return; + iterator b = begin(); + size_type copy = capacity() - (pos - b); + if (copy == 0) + return; + if (n > copy) + n = copy; + size_type construct = reserve(); + if (construct > n) + construct = n; + if (pos == b) { + pointer p = sub(m_first, n); + size_type ii = n; + BOOST_TRY { + for (;ii > construct; --ii, increment(p)) + replace(p, *wrapper()); + for (; ii > 0; --ii, increment(p)) + boost::allocator_construct(alloc(), boost::to_address(p), *wrapper()); + } BOOST_CATCH(...) { + size_type constructed = ii < construct ? construct - ii : 0; + m_last = add(m_last, constructed); + m_size += constructed; + BOOST_RETHROW + } + BOOST_CATCH_END + } else { + pointer src = m_first; + pointer dest = sub(m_first, n); + pointer p = map_pointer(pos.m_it); + BOOST_TRY { + while (src != p) { + construct_or_replace(is_uninitialized(dest), dest, *src); + increment(src); + increment(dest); + } + for (size_type ii = 0; ii < n; ++ii, increment(dest)) + construct_or_replace(is_uninitialized(dest), dest, *wrapper()); + } BOOST_CATCH(...) { + for (src = sub(m_first, n); src != dest; increment(src)) + destroy_if_constructed(src); + BOOST_RETHROW + } + BOOST_CATCH_END + } + m_first = sub(m_first, n); + m_last = sub(m_last, n - construct); + m_size += construct; + } + + /*! INTERNAL ONLY */ + void erase_begin(size_type n, const true_type&) { + m_first = add(m_first, n); + m_size -= n; + } + + /*! INTERNAL ONLY */ + void erase_begin(size_type n, const false_type&) { + iterator b = begin(); + rerase(b, b + n); + } + + /*! INTERNAL ONLY */ + void erase_end(size_type n, const true_type&) { + m_last = sub(m_last, n); + m_size -= n; + } + + /*! INTERNAL ONLY */ + void erase_end(size_type n, const false_type&) { + iterator e = end(); + erase(e - n, e); + } +}; + +// Non-member functions + +//! Compare two circular_buffers element-by-element to determine if they are equal. +/*! + \param lhs The circular_buffer to compare. + \param rhs The circular_buffer to compare. + \return lhs.\link circular_buffer::size() size()\endlink == rhs.\link circular_buffer::size() size()\endlink + && std::equal(lhs.\link circular_buffer::begin() + begin()\endlink, lhs.\link circular_buffer::end() end()\endlink, + rhs.\link circular_buffer::begin() begin()\endlink) + \throws Nothing. + \par Complexity + Linear (in the size of the circular_buffers). + \par Iterator Invalidation + Does not invalidate any iterators. +*/ +template +inline bool operator == (const circular_buffer& lhs, const circular_buffer& rhs) { + return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin()); +} + +/*! + \brief Compare two circular_buffers element-by-element to determine if the left one is lesser than the + right one. + \param lhs The circular_buffer to compare. + \param rhs The circular_buffer to compare. + \return + std::lexicographical_compare(lhs.\link circular_buffer::begin() begin()\endlink, + lhs.\link circular_buffer::end() end()\endlink, rhs.\link circular_buffer::begin() begin()\endlink, + rhs.\link circular_buffer::end() end()\endlink) + \throws Nothing. + \par Complexity + Linear (in the size of the circular_buffers). + \par Iterator Invalidation + Does not invalidate any iterators. +*/ +template +inline bool operator < (const circular_buffer& lhs, const circular_buffer& rhs) { + return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); +} + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || defined(BOOST_MSVC) + +//! Compare two circular_buffers element-by-element to determine if they are non-equal. +/*! + \param lhs The circular_buffer to compare. + \param rhs The circular_buffer to compare. + \return !(lhs == rhs) + \throws Nothing. + \par Complexity + Linear (in the size of the circular_buffers). + \par Iterator Invalidation + Does not invalidate any iterators. + \sa operator==(const circular_buffer&, const circular_buffer&) +*/ +template +inline bool operator != (const circular_buffer& lhs, const circular_buffer& rhs) { + return !(lhs == rhs); +} + +/*! + \brief Compare two circular_buffers element-by-element to determine if the left one is greater than + the right one. + \param lhs The circular_buffer to compare. + \param rhs The circular_buffer to compare. + \return rhs \< lhs + \throws Nothing. + \par Complexity + Linear (in the size of the circular_buffers). + \par Iterator Invalidation + Does not invalidate any iterators. + \sa operator<(const circular_buffer&, const circular_buffer&) +*/ +template +inline bool operator > (const circular_buffer& lhs, const circular_buffer& rhs) { + return rhs < lhs; +} + +/*! + \brief Compare two circular_buffers element-by-element to determine if the left one is lesser or equal + to the right one. + \param lhs The circular_buffer to compare. + \param rhs The circular_buffer to compare. + \return !(rhs \< lhs) + \throws Nothing. + \par Complexity + Linear (in the size of the circular_buffers). + \par Iterator Invalidation + Does not invalidate any iterators. + \sa operator<(const circular_buffer&, const circular_buffer&) +*/ +template +inline bool operator <= (const circular_buffer& lhs, const circular_buffer& rhs) { + return !(rhs < lhs); +} + +/*! + \brief Compare two circular_buffers element-by-element to determine if the left one is greater or + equal to the right one. + \param lhs The circular_buffer to compare. + \param rhs The circular_buffer to compare. + \return !(lhs < rhs) + \throws Nothing. + \par Complexity + Linear (in the size of the circular_buffers). + \par Iterator Invalidation + Does not invalidate any iterators. + \sa operator<(const circular_buffer&, const circular_buffer&) +*/ +template +inline bool operator >= (const circular_buffer& lhs, const circular_buffer& rhs) { + return !(lhs < rhs); +} + +//! Swap the contents of two circular_buffers. +/*! + \post lhs contains elements of rhs and vice versa. + \param lhs The circular_buffer whose content will be swapped with rhs. + \param rhs The circular_buffer whose content will be swapped with lhs. + \throws Nothing. + \par Complexity + Constant (in the size of the circular_buffers). + \par Iterator Invalidation + Invalidates all iterators of both circular_buffers. (On the other hand the iterators still + point to the same elements but within another container. If you want to rely on this feature you have to + turn the Debug Support off otherwise an assertion will report an error if such + invalidated iterator is used.) + \sa \link circular_buffer::swap(circular_buffer&) swap(circular_buffer&)\endlink +*/ +template +inline void swap(circular_buffer& lhs, circular_buffer& rhs) BOOST_NOEXCEPT { + lhs.swap(rhs); +} + +#endif // #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || defined(BOOST_MSVC) + +} // namespace boost + +#endif // #if !defined(BOOST_CIRCULAR_BUFFER_BASE_HPP) diff --git a/boost/circular_buffer/debug.hpp b/boost/circular_buffer/debug.hpp new file mode 100644 index 00000000..b6ab0fef --- /dev/null +++ b/boost/circular_buffer/debug.hpp @@ -0,0 +1,248 @@ +// Debug support for the circular buffer library. + +// Copyright (c) 2003-2008 Jan Gaspar + +// 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) + +#if !defined(BOOST_CIRCULAR_BUFFER_DEBUG_HPP) +#define BOOST_CIRCULAR_BUFFER_DEBUG_HPP + +#if defined(_MSC_VER) + #pragma once +#endif + +#if BOOST_CB_ENABLE_DEBUG +#include + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std { + using ::memset; +} +#endif + +#endif // BOOST_CB_ENABLE_DEBUG +namespace boost { + +namespace cb_details { + +#if BOOST_CB_ENABLE_DEBUG + +// The value the uninitialized memory is filled with. +const int UNINITIALIZED = 0xcc; + +template +inline void do_fill_uninitialized_memory(T* data, std::size_t size_in_bytes) BOOST_NOEXCEPT { + std::memset(static_cast(data), UNINITIALIZED, size_in_bytes); +} + +template +inline void do_fill_uninitialized_memory(T& /*data*/, std::size_t /*size_in_bytes*/) BOOST_NOEXCEPT { + // Do nothing +} + + +class debug_iterator_registry; + +/*! + \class debug_iterator_base + \brief Registers/unregisters iterators into the registry of valid iterators. + + This class is intended to be a base class of an iterator. +*/ +class debug_iterator_base { + +private: +// Members + + //! Iterator registry. + mutable const debug_iterator_registry* m_registry; + + //! Next iterator in the iterator chain. + mutable const debug_iterator_base* m_next; + +public: +// Construction/destruction + + //! Default constructor. + debug_iterator_base(); + + //! Constructor taking the iterator registry as a parameter. + debug_iterator_base(const debug_iterator_registry* registry); + + //! Copy constructor. + debug_iterator_base(const debug_iterator_base& rhs); + + //! Destructor. + ~debug_iterator_base(); + +// Methods + + //! Assign operator. + debug_iterator_base& operator = (const debug_iterator_base& rhs); + + //! Is the iterator valid? + bool is_valid(const debug_iterator_registry* registry) const; + + //! Invalidate the iterator. + /*! + \note The method is const in order to invalidate const iterators, too. + */ + void invalidate() const; + + //! Return the next iterator in the iterator chain. + const debug_iterator_base* next() const; + + //! Set the next iterator in the iterator chain. + /*! + \note The method is const in order to set a next iterator to a const iterator, too. + */ + void set_next(const debug_iterator_base* it) const; + +private: +// Helpers + + //! Register self as a valid iterator. + void register_self(); + + //! Unregister self from valid iterators. + void unregister_self(); +}; + +/*! + \class debug_iterator_registry + \brief Registry of valid iterators. + + This class is intended to be a base class of a container. +*/ +class debug_iterator_registry { + + //! Pointer to the chain of valid iterators. + mutable const debug_iterator_base* m_iterators; + +public: +// Methods + + //! Default constructor. + debug_iterator_registry() : m_iterators(0) {} + + //! Register an iterator into the list of valid iterators. + /*! + \note The method is const in order to register iterators into const containers, too. + */ + void register_iterator(const debug_iterator_base* it) const { + it->set_next(m_iterators); + m_iterators = it; + } + + //! Unregister an iterator from the list of valid iterators. + /*! + \note The method is const in order to unregister iterators from const containers, too. + */ + void unregister_iterator(const debug_iterator_base* it) const { + const debug_iterator_base* previous = 0; + for (const debug_iterator_base* p = m_iterators; p != it; previous = p, p = p->next()) {} + remove(it, previous); + } + + //! Invalidate every iterator pointing to the same element as the iterator passed as a parameter. + template + void invalidate_iterators(const Iterator& it) { + const debug_iterator_base* previous = 0; + for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next()) { + if (((Iterator*)p)->m_it == it.m_it) { + p->invalidate(); + remove(p, previous); + continue; + } + previous = p; + } + } + + //! Invalidate all iterators except an iterator poining to the same element as the iterator passed as a parameter. + template + void invalidate_iterators_except(const Iterator& it) { + const debug_iterator_base* previous = 0; + for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next()) { + if (((Iterator*)p)->m_it != it.m_it) { + p->invalidate(); + remove(p, previous); + continue; + } + previous = p; + } + } + + //! Invalidate all iterators. + void invalidate_all_iterators() { + for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next()) + p->invalidate(); + m_iterators = 0; + } + +private: +// Helpers + + //! Remove the current iterator from the iterator chain. + void remove(const debug_iterator_base* current, + const debug_iterator_base* previous) const { + if (previous == 0) + m_iterators = m_iterators->next(); + else + previous->set_next(current->next()); + } +}; + +// Implementation of the debug_iterator_base methods. + +inline debug_iterator_base::debug_iterator_base() : m_registry(0), m_next(0) {} + +inline debug_iterator_base::debug_iterator_base(const debug_iterator_registry* registry) +: m_registry(registry), m_next(0) { + register_self(); +} + +inline debug_iterator_base::debug_iterator_base(const debug_iterator_base& rhs) +: m_registry(rhs.m_registry), m_next(0) { + register_self(); +} + +inline debug_iterator_base::~debug_iterator_base() { unregister_self(); } + +inline debug_iterator_base& debug_iterator_base::operator = (const debug_iterator_base& rhs) { + if (m_registry == rhs.m_registry) + return *this; + unregister_self(); + m_registry = rhs.m_registry; + register_self(); + return *this; +} + +inline bool debug_iterator_base::is_valid(const debug_iterator_registry* registry) const { + return m_registry == registry; +} + +inline void debug_iterator_base::invalidate() const { m_registry = 0; } + +inline const debug_iterator_base* debug_iterator_base::next() const { return m_next; } + +inline void debug_iterator_base::set_next(const debug_iterator_base* it) const { m_next = it; } + +inline void debug_iterator_base::register_self() { + if (m_registry != 0) + m_registry->register_iterator(this); +} + +inline void debug_iterator_base::unregister_self() { + if (m_registry != 0) + m_registry->unregister_iterator(this); +} + +#endif // #if BOOST_CB_ENABLE_DEBUG + +} // namespace cb_details + +} // namespace boost + +#endif // #if !defined(BOOST_CIRCULAR_BUFFER_DEBUG_HPP) diff --git a/boost/circular_buffer/details.hpp b/boost/circular_buffer/details.hpp new file mode 100644 index 00000000..d6d48f3a --- /dev/null +++ b/boost/circular_buffer/details.hpp @@ -0,0 +1,491 @@ +// Helper classes and functions for the circular buffer. + +// Copyright (c) 2003-2008 Jan Gaspar + +// Copyright 2014,2018 Glen Joseph Fernandes +// (glenjofe@gmail.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) + +#if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP) +#define BOOST_CIRCULAR_BUFFER_DETAILS_HPP + +#if defined(_MSC_VER) + #pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +// Silence MS /W4 warnings like C4913: +// "user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used" +// This might happen when previously including some boost headers that overload the coma operator. +#if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable:4913) +#endif + +namespace boost { + +namespace cb_details { + +template struct nonconst_traits; + +template +void uninitialized_fill_n_with_alloc( + ForwardIterator first, Diff n, const T& item, Alloc& alloc); + +template +ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a); + +template +ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a); + +/*! + \struct const_traits + \brief Defines the data types for a const iterator. +*/ +template +struct const_traits { + // Basic types + typedef typename Alloc::value_type value_type; + typedef typename boost::allocator_const_pointer::type pointer; + typedef const value_type& reference; + typedef typename boost::allocator_size_type::type size_type; + typedef typename boost::allocator_difference_type::type difference_type; + + // Non-const traits + typedef nonconst_traits nonconst_self; +}; + +/*! + \struct nonconst_traits + \brief Defines the data types for a non-const iterator. +*/ +template +struct nonconst_traits { + // Basic types + typedef typename Alloc::value_type value_type; + typedef typename boost::allocator_pointer::type pointer; + typedef value_type& reference; + typedef typename boost::allocator_size_type::type size_type; + typedef typename boost::allocator_difference_type::type difference_type; + + // Non-const traits + typedef nonconst_traits nonconst_self; +}; + +/*! + \struct iterator_wrapper + \brief Helper iterator dereference wrapper. +*/ +template +struct iterator_wrapper { + mutable Iterator m_it; + explicit iterator_wrapper(Iterator it) : m_it(it) {} + Iterator operator () () const { return m_it++; } +private: + iterator_wrapper& operator = (const iterator_wrapper&); // do not generate +}; + +/*! + \struct item_wrapper + \brief Helper item dereference wrapper. +*/ +template +struct item_wrapper { + Value m_item; + explicit item_wrapper(Value item) : m_item(item) {} + Pointer operator () () const { return &m_item; } +private: + item_wrapper& operator = (const item_wrapper&); // do not generate +}; + +/*! + \struct assign_n + \brief Helper functor for assigning n items. +*/ +template +struct assign_n { + typedef typename boost::allocator_size_type::type size_type; + size_type m_n; + Value m_item; + Alloc& m_alloc; + assign_n(size_type n, Value item, Alloc& alloc) : m_n(n), m_item(item), m_alloc(alloc) {} + template + void operator () (Pointer p) const { + uninitialized_fill_n_with_alloc(p, m_n, m_item, m_alloc); + } +private: + assign_n& operator = (const assign_n&); // do not generate +}; + +/*! + \struct assign_range + \brief Helper functor for assigning range of items. +*/ +template +struct assign_range { + Iterator m_first; + Iterator m_last; + Alloc& m_alloc; + + assign_range(const Iterator& first, const Iterator& last, Alloc& alloc) + : m_first(first), m_last(last), m_alloc(alloc) {} + + template + void operator () (Pointer p) const { + boost::cb_details::uninitialized_copy(m_first, m_last, p, m_alloc); + } +}; + +template +inline assign_range make_assign_range(const Iterator& first, const Iterator& last, Alloc& a) { + return assign_range(first, last, a); +} + +/*! + \class capacity_control + \brief Capacity controller of the space optimized circular buffer. +*/ +template +class capacity_control { + + //! The capacity of the space-optimized circular buffer. + Size m_capacity; + + //! The lowest guaranteed or minimum capacity of the adapted space-optimized circular buffer. + Size m_min_capacity; + +public: + + //! Constructor. + capacity_control(Size buffer_capacity, Size min_buffer_capacity = 0) + : m_capacity(buffer_capacity), m_min_capacity(min_buffer_capacity) + { // Check for capacity lower than min_capacity. + BOOST_CB_ASSERT(buffer_capacity >= min_buffer_capacity); + } + + // Default copy constructor. + + // Default assign operator. + + //! Get the capacity of the space optimized circular buffer. + Size capacity() const { return m_capacity; } + + //! Get the minimal capacity of the space optimized circular buffer. + Size min_capacity() const { return m_min_capacity; } + + //! Size operator - returns the capacity of the space optimized circular buffer. + operator Size() const { return m_capacity; } +}; + +/*! + \struct iterator + \brief Random access iterator for the circular buffer. + \param Buff The type of the underlying circular buffer. + \param Traits Basic iterator types. + \note This iterator is not circular. It was designed + for iterating from begin() to end() of the circular buffer. +*/ +template +struct iterator +#if BOOST_CB_ENABLE_DEBUG + : public debug_iterator_base +#endif // #if BOOST_CB_ENABLE_DEBUG +{ +// Helper types + + //! Non-const iterator. + typedef iterator nonconst_self; + +// Basic types + typedef std::random_access_iterator_tag iterator_category; + + //! The type of the elements stored in the circular buffer. + typedef typename Traits::value_type value_type; + + //! Pointer to the element. + typedef typename Traits::pointer pointer; + + //! Reference to the element. + typedef typename Traits::reference reference; + + //! Size type. + typedef typename Traits::size_type size_type; + + //! Difference type. + typedef typename Traits::difference_type difference_type; + +// Member variables + + //! The circular buffer where the iterator points to. + const Buff* m_buff; + + //! An internal iterator. + pointer m_it; + +// Construction & assignment + + // Default copy constructor. + + //! Default constructor. + iterator() : m_buff(0), m_it(0) {} + +#if BOOST_CB_ENABLE_DEBUG + + //! Copy constructor (used for converting from a non-const to a const iterator). + iterator(const nonconst_self& it) : debug_iterator_base(it), m_buff(it.m_buff), m_it(it.m_it) {} + + //! Internal constructor. + /*! + \note This constructor is not intended to be used directly by the user. + */ + iterator(const Buff* cb, const pointer p) : debug_iterator_base(cb), m_buff(cb), m_it(p) {} + +#else + + iterator(const nonconst_self& it) : m_buff(it.m_buff), m_it(it.m_it) {} + + iterator(const Buff* cb, const pointer p) : m_buff(cb), m_it(p) {} + +#endif // #if BOOST_CB_ENABLE_DEBUG + + //! Assign operator. +#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) + iterator& operator=(const iterator&) = default; +#else + iterator& operator=(const iterator& it) { + if (this == &it) + return *this; +#if BOOST_CB_ENABLE_DEBUG + debug_iterator_base::operator =(it); +#endif // #if BOOST_CB_ENABLE_DEBUG + m_buff = it.m_buff; + m_it = it.m_it; + return *this; + } +#endif + +// Random access iterator methods + + //! Dereferencing operator. + reference operator * () const { + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(m_it != 0); // check for iterator pointing to end() + return *m_it; + } + + //! Dereferencing operator. + pointer operator -> () const { return &(operator*()); } + + //! Difference operator. + template + difference_type operator - (const iterator& it) const { + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator + return linearize_pointer(*this) - linearize_pointer(it); + } + + //! Increment operator (prefix). + iterator& operator ++ () { + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(m_it != 0); // check for iterator pointing to end() + m_buff->increment(m_it); + if (m_it == m_buff->m_last) + m_it = 0; + return *this; + } + + //! Increment operator (postfix). + iterator operator ++ (int) { + iterator tmp = *this; + ++*this; + return tmp; + } + + //! Decrement operator (prefix). + iterator& operator -- () { + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(m_it != m_buff->m_first); // check for iterator pointing to begin() + if (m_it == 0) + m_it = m_buff->m_last; + m_buff->decrement(m_it); + return *this; + } + + //! Decrement operator (postfix). + iterator operator -- (int) { + iterator tmp = *this; + --*this; + return tmp; + } + + //! Iterator addition. + iterator& operator += (difference_type n) { + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + if (n > 0) { + BOOST_CB_ASSERT(m_buff->end() - *this >= n); // check for too large n + m_it = m_buff->add(m_it, n); + if (m_it == m_buff->m_last) + m_it = 0; + } else if (n < 0) { + *this -= -n; + } + return *this; + } + + //! Iterator addition. + iterator operator + (difference_type n) const { return iterator(*this) += n; } + + //! Iterator subtraction. + iterator& operator -= (difference_type n) { + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + if (n > 0) { + BOOST_CB_ASSERT(*this - m_buff->begin() >= n); // check for too large n + m_it = m_buff->sub(m_it == 0 ? m_buff->m_last : m_it, n); + } else if (n < 0) { + *this += -n; + } + return *this; + } + + //! Iterator subtraction. + iterator operator - (difference_type n) const { return iterator(*this) -= n; } + + //! Element access operator. + reference operator [] (difference_type n) const { return *(*this + n); } + +// Equality & comparison + + //! Equality. + template + bool operator == (const iterator& it) const { + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator + return m_it == it.m_it; + } + + //! Inequality. + template + bool operator != (const iterator& it) const { + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator + return m_it != it.m_it; + } + + //! Less. + template + bool operator < (const iterator& it) const { + BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator + BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator + return linearize_pointer(*this) < linearize_pointer(it); + } + + //! Greater. + template + bool operator > (const iterator& it) const { return it < *this; } + + //! Less or equal. + template + bool operator <= (const iterator& it) const { return !(it < *this); } + + //! Greater or equal. + template + bool operator >= (const iterator& it) const { return !(*this < it); } + +// Helpers + + //! Get a pointer which would point to the same element as the iterator in case the circular buffer is linearized. + template + typename Traits0::pointer linearize_pointer(const iterator& it) const { + return it.m_it == 0 ? m_buff->m_buff + m_buff->size() : + (it.m_it < m_buff->m_first ? it.m_it + (m_buff->m_end - m_buff->m_first) + : m_buff->m_buff + (it.m_it - m_buff->m_first)); + } +}; + +//! Iterator addition. +template +inline iterator +operator + (typename Traits::difference_type n, const iterator& it) { + return it + n; +} + +/*! + \fn ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest) + \brief Equivalent of std::uninitialized_copy but with explicit specification of value type. +*/ +template +inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) { + ForwardIterator next = dest; + BOOST_TRY { + for (; first != last; ++first, ++dest) + boost::allocator_construct(a, boost::to_address(dest), *first); + } BOOST_CATCH(...) { + for (; next != dest; ++next) + boost::allocator_destroy(a, boost::to_address(next)); + BOOST_RETHROW + } + BOOST_CATCH_END + return dest; +} + +template +ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a, + true_type) { + for (; first != last; ++first, ++dest) + boost::allocator_construct(a, boost::to_address(dest), boost::move(*first)); + return dest; +} + +template +ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a, + false_type) { + return uninitialized_copy(first, last, dest, a); +} + +/*! + \fn ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest) + \brief Equivalent of std::uninitialized_copy but with explicit specification of value type and moves elements if they have noexcept move constructors. +*/ +template +ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) { + typedef typename boost::is_nothrow_move_constructible::type tag_t; + return uninitialized_move_if_noexcept_impl(first, last, dest, a, tag_t()); +} + +/*! + \fn void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const T& item, Alloc& alloc) + \brief Equivalent of std::uninitialized_fill_n with allocator. +*/ +template +inline void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const T& item, Alloc& alloc) { + ForwardIterator next = first; + BOOST_TRY { + for (; n > 0; ++first, --n) + boost::allocator_construct(alloc, boost::to_address(first), item); + } BOOST_CATCH(...) { + for (; next != first; ++next) + boost::allocator_destroy(alloc, boost::to_address(next)); + BOOST_RETHROW + } + BOOST_CATCH_END +} + +} // namespace cb_details + +} // namespace boost + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif + +#endif // #if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP) diff --git a/boost/circular_buffer/space_optimized.hpp b/boost/circular_buffer/space_optimized.hpp new file mode 100644 index 00000000..21681fd3 --- /dev/null +++ b/boost/circular_buffer/space_optimized.hpp @@ -0,0 +1,1713 @@ +// Implementation of the circular buffer adaptor. + +// Copyright (c) 2003-2008 Jan Gaspar +// Copyright (c) 2013 Paul A. Bristow // Doxygen comments changed for new version of documentation. +// Copyright (c) 2013 Antony Polukhin // Move semantics implementation. + +// 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) + +#if !defined(BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP) +#define BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP + +#if defined(_MSC_VER) + #pragma once +#endif + +#include +#include + +namespace boost { + +/*! + \class circular_buffer_space_optimized + \brief Space optimized circular buffer container adaptor. + T must be a copyable class or must have an noexcept move constructor + and move assignment operator. +*/ +template +class circular_buffer_space_optimized : +/*! \cond */ +#if BOOST_CB_ENABLE_DEBUG +public +#endif +/*! \endcond */ +circular_buffer { +public: +// Typedefs + + typedef typename circular_buffer::value_type value_type; + typedef typename circular_buffer::pointer pointer; + typedef typename circular_buffer::const_pointer const_pointer; + typedef typename circular_buffer::reference reference; + typedef typename circular_buffer::const_reference const_reference; + typedef typename circular_buffer::size_type size_type; + typedef typename circular_buffer::difference_type difference_type; + typedef typename circular_buffer::allocator_type allocator_type; + typedef typename circular_buffer::const_iterator const_iterator; + typedef typename circular_buffer::iterator iterator; + typedef typename circular_buffer::const_reverse_iterator const_reverse_iterator; + typedef typename circular_buffer::reverse_iterator reverse_iterator; + typedef typename circular_buffer::array_range array_range; + typedef typename circular_buffer::const_array_range const_array_range; + typedef typename circular_buffer::param_value_type param_value_type; + typedef typename circular_buffer::rvalue_type rvalue_type; + //typedef typename circular_buffer::return_value_type return_value_type; + +/*
 is not passed through to html or pdf. So 
is used in code section below. Ugly :-( +Ideally want a link to capacity_control, but this would require include details +and this would expose all the functions in details. +There must be a better way of doing this. +*/ + + /*! Capacity controller of the space optimized circular buffer. + + \see capacity_control in details.hpp. +

+ +class capacity_control
+{
+ size_type m_capacity; // Available capacity.
+ size_type m_min_capacity; // Minimum capacity.
+public:
+ capacity_control(size_type capacity, size_type min_capacity = 0)
+ : m_capacity(capacity), m_min_capacity(min_capacity)
+ {};
+ size_type %capacity() const { return m_capacity; }
+ size_type min_capacity() const { return m_min_capacity; }
+ operator size_type() const { return m_capacity; }
+};
+
+

+ + +

Always + capacity >= min_capacity. +

+

+ The capacity() represents the capacity + of the circular_buffer_space_optimized and + the min_capacity() determines the minimal allocated size of its internal buffer. +

+

The converting constructor of the capacity_control allows implicit conversion from + size_type-like types which ensures compatibility of creating an instance of the + circular_buffer_space_optimized with other STL containers. + + On the other hand the operator %size_type() + provides implicit conversion to the size_type which allows to treat the + capacity of the circular_buffer_space_optimized the same way as in the + circular_buffer. +

+ */ + typedef cb_details::capacity_control capacity_type; + +// Inherited + + using circular_buffer::get_allocator; + using circular_buffer::begin; + using circular_buffer::end; + using circular_buffer::rbegin; + using circular_buffer::rend; + using circular_buffer::at; + using circular_buffer::front; + using circular_buffer::back; + using circular_buffer::array_one; + using circular_buffer::array_two; + using circular_buffer::linearize; + using circular_buffer::is_linearized; + using circular_buffer::rotate; + using circular_buffer::size; + using circular_buffer::max_size; + using circular_buffer::empty; + +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) + reference operator [] (size_type n) { return circular_buffer::operator[](n); } + const_reference operator [] (size_type n) const { return circular_buffer::operator[](n); } +#else + using circular_buffer::operator[]; +#endif + +private: +// Member variables + + //! The capacity controller of the space optimized circular buffer. + capacity_type m_capacity_ctrl; + +public: +// Overridden + + //! Is the circular_buffer_space_optimized full? + /*! + \return true if the number of elements stored in the circular_buffer_space_optimized + equals the capacity of the circular_buffer_space_optimized; false otherwise. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer_space_optimized). + \sa empty() + */ + bool full() const BOOST_NOEXCEPT { return m_capacity_ctrl == size(); } + + /*! \brief Get the maximum number of elements which can be inserted into the + circular_buffer_space_optimized without overwriting any of already stored elements. + \return capacity().%capacity() - size() + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer_space_optimized). + \sa capacity(), size(), max_size() + */ + size_type reserve() const BOOST_NOEXCEPT { return m_capacity_ctrl - size(); } + + //! Get the capacity of the circular_buffer_space_optimized. + /*! + \return The capacity controller representing the maximum number of elements which can be stored in the + circular_buffer_space_optimized and the minimal allocated size of the internal buffer. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Does not invalidate any iterators. + \par Complexity + Constant (in the size of the circular_buffer_space_optimized). + \sa reserve(), size(), max_size(), + set_capacity(const capacity_type&) + */ + const capacity_type& capacity() const BOOST_NOEXCEPT { return m_capacity_ctrl; } + +#if defined(BOOST_CB_TEST) + + // Return the current capacity of the adapted circular buffer. + /* + \note This method is not intended to be used directly by the user. + It is defined only for testing purposes. + */ + size_type internal_capacity() const BOOST_NOEXCEPT { return circular_buffer::capacity(); } + +#endif // #if defined(BOOST_CB_TEST) + + /*! \brief Change the capacity (and the minimal guaranteed amount of allocated memory) of the + circular_buffer_space_optimized. + \post capacity() == capacity_ctrl \&\& size() \<= capacity_ctrl.capacity()

+ If the current number of elements stored in the circular_buffer_space_optimized is greater + than the desired new capacity then number of [size() - capacity_ctrl.capacity()] last + elements will be removed and the new size will be equal to capacity_ctrl.capacity().

+ If the current number of elements stored in the circular_buffer_space_optimized is lower + than the new capacity then the amount of allocated memory in the internal buffer may be accommodated as + necessary but it will never drop below capacity_ctrl.min_capacity(). + \param capacity_ctrl The new capacity controller. + \throws "An allocation error" if memory is exhausted, (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Strong. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in min[size(), capacity_ctrl.%capacity()]). + \note To explicitly clear the extra allocated memory use the shrink-to-fit technique:

+ %boost::%circular_buffer_space_optimized\ cb(1000);
+ ...
+ %boost::%circular_buffer_space_optimized\(cb).swap(cb);


+ For more information about the shrink-to-fit technique in STL see + http://www.gotw.ca/gotw/054.htm. + \sa rset_capacity(const capacity_type&), + \link resize() resize(size_type, const_reference)\endlink + */ + void set_capacity(const capacity_type& capacity_ctrl) { + m_capacity_ctrl = capacity_ctrl; + if (capacity_ctrl < size()) { + iterator e = end(); + circular_buffer::erase(e - (size() - capacity_ctrl), e); + } + adjust_min_capacity(); + } + + //! Change the size of the circular_buffer_space_optimized. + /*! + \post size() == new_size \&\& capacity().%capacity() >= new_size

+ If the new size is greater than the current size, copies of item will be inserted at the + back of the of the circular_buffer_space_optimized in order to achieve the desired + size. In the case the resulting size exceeds the current capacity the capacity will be set to + new_size.

+ If the current number of elements stored in the circular_buffer_space_optimized is greater + than the desired new size then number of [size() - new_size] last elements will be + removed. (The capacity will remain unchanged.)

+ The amount of allocated memory in the internal buffer may be accommodated as necessary. + \param new_size The new size. + \param item The element the circular_buffer_space_optimized will be filled with in order to gain + the requested size. (See the Effect.) + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the new size of the circular_buffer_space_optimized). + \sa \link rresize() rresize(size_type, const_reference)\endlink, + set_capacity(const capacity_type&) + */ + void resize(size_type new_size, param_value_type item = value_type()) { + if (new_size > size()) { + if (new_size > m_capacity_ctrl) + m_capacity_ctrl = capacity_type(new_size, m_capacity_ctrl.min_capacity()); + insert(end(), new_size - size(), item); + } else { + iterator e = end(); + erase(e - (size() - new_size), e); + } + } + + /*! \brief Change the capacity (and the minimal guaranteed amount of allocated memory) of the + circular_buffer_space_optimized. + \post capacity() == capacity_ctrl \&\& size() \<= capacity_ctrl

+ If the current number of elements stored in the circular_buffer_space_optimized is greater + than the desired new capacity then number of [size() - capacity_ctrl.capacity()] + first elements will be removed and the new size will be equal to + capacity_ctrl.capacity().

+ If the current number of elements stored in the circular_buffer_space_optimized is lower + than the new capacity then the amount of allocated memory in the internal buffer may be accommodated as + necessary but it will never drop below capacity_ctrl.min_capacity(). + \param capacity_ctrl The new capacity controller. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Strong. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in min[size(), capacity_ctrl.%capacity()]). + \sa set_capacity(const capacity_type&), + \link rresize() rresize(size_type, const_reference)\endlink + */ + void rset_capacity(const capacity_type& capacity_ctrl) { + m_capacity_ctrl = capacity_ctrl; + if (capacity_ctrl < size()) { + iterator b = begin(); + circular_buffer::rerase(b, b + (size() - capacity_ctrl)); + } + adjust_min_capacity(); + } + + //! Change the size of the circular_buffer_space_optimized. + /*! + \post size() == new_size \&\& capacity().%capacity() >= new_size

+ If the new size is greater than the current size, copies of item will be inserted at the + front of the of the circular_buffer_space_optimized in order to achieve the desired + size. In the case the resulting size exceeds the current capacity the capacity will be set to + new_size.

+ If the current number of elements stored in the circular_buffer_space_optimized is greater + than the desired new size then number of [size() - new_size] first elements will be + removed. (The capacity will remain unchanged.)

+ The amount of allocated memory in the internal buffer may be accommodated as necessary. + \param new_size The new size. + \param item The element the circular_buffer_space_optimized will be filled with in order to gain + the requested size. (See the Effect.) + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the new size of the circular_buffer_space_optimized). + \sa \link resize() resize(size_type, const_reference)\endlink, + rset_capacity(const capacity_type&) + */ + void rresize(size_type new_size, param_value_type item = value_type()) { + if (new_size > size()) { + if (new_size > m_capacity_ctrl) + m_capacity_ctrl = capacity_type(new_size, m_capacity_ctrl.min_capacity()); + rinsert(begin(), new_size - size(), item); + } else { + rerase(begin(), end() - new_size); + } + } + + //! Create an empty space optimized circular buffer with zero capacity. + /*! + \post capacity().%capacity() == 0 \&\& capacity().min_capacity() == 0 \&\& size() == 0 + \param alloc The allocator. + \throws Nothing. + \par Complexity + Constant. + \warning Since Boost version 1.36 the behaviour of this constructor has changed. Now it creates a space + optimized circular buffer with zero capacity. + */ + explicit circular_buffer_space_optimized(const allocator_type& alloc = allocator_type()) BOOST_NOEXCEPT + : circular_buffer(0, alloc) + , m_capacity_ctrl(0) {} + + //! Create an empty space optimized circular buffer with the specified capacity. + /*! + \post capacity() == capacity_ctrl \&\& size() == 0

+ The amount of allocated memory in the internal buffer is capacity_ctrl.min_capacity(). + \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in + the circular_buffer_space_optimized and the minimal allocated size of the + internal buffer. + \param alloc The allocator. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + \par Complexity + Constant. + */ + explicit circular_buffer_space_optimized(capacity_type capacity_ctrl, + const allocator_type& alloc = allocator_type()) + : circular_buffer(capacity_ctrl.min_capacity(), alloc) + , m_capacity_ctrl(capacity_ctrl) {} + + /*! \brief Create a full space optimized circular buffer with the specified capacity filled with + capacity_ctrl.%capacity() copies of item. + \post capacity() == capacity_ctrl \&\& full() \&\& (*this)[0] == item \&\& (*this)[1] == item \&\& ... + \&\& (*this) [capacity_ctrl.%capacity() - 1] == item

+ The amount of allocated memory in the internal buffer is capacity_ctrl.capacity(). + \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in + the circular_buffer_space_optimized and the minimal allocated size of the + internal buffer. + \param item The element the created circular_buffer_space_optimized will be filled with. + \param alloc The allocator. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + \throws Whatever T::T(const T&) throws. + \par Complexity + Linear (in the capacity_ctrl.%capacity()). + */ + circular_buffer_space_optimized(capacity_type capacity_ctrl, param_value_type item, + const allocator_type& alloc = allocator_type()) + : circular_buffer(capacity_ctrl.capacity(), item, alloc) + , m_capacity_ctrl(capacity_ctrl) {} + + /*! \brief Create a space optimized circular buffer with the specified capacity filled with n copies + of item. + \pre capacity_ctrl.%capacity() >= n + \post capacity() == capacity_ctrl \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item + \&\& ... \&\& (*this)[n - 1] == item

+ The amount of allocated memory in the internal buffer is + max[n, capacity_ctrl.min_capacity()]. + \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in + the circular_buffer_space_optimized and the minimal allocated size of the + internal buffer. + \param n The number of elements the created circular_buffer_space_optimized will be filled with. + \param item The element the created circular_buffer_space_optimized will be filled with. + \param alloc The allocator. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Complexity + Linear (in the n). + */ + circular_buffer_space_optimized(capacity_type capacity_ctrl, size_type n, param_value_type item, + const allocator_type& alloc = allocator_type()) + : circular_buffer(init_capacity(capacity_ctrl, n), n, item, alloc) + , m_capacity_ctrl(capacity_ctrl) {} + + //! The copy constructor. + /*! + Creates a copy of the specified circular_buffer_space_optimized. + \post *this == cb

+ The amount of allocated memory in the internal buffer is cb.size(). + \param cb The circular_buffer_space_optimized to be copied. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Complexity + Linear (in the size of cb). + */ + circular_buffer_space_optimized(const circular_buffer_space_optimized& cb) + : circular_buffer(cb.begin(), cb.end(), cb.get_allocator()) + , m_capacity_ctrl(cb.m_capacity_ctrl) {} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + //! The move constructor. + /*! \brief Move constructs a circular_buffer_space_optimized from cb, + leaving cb empty. + \pre C++ compiler with rvalue references support. + \post cb.empty() + \param cb circular_buffer to 'steal' value from. + \throws Nothing. + \par Constant. + */ + circular_buffer_space_optimized(circular_buffer_space_optimized&& cb) BOOST_NOEXCEPT + : circular_buffer() + , m_capacity_ctrl(0) { + cb.swap(*this); + } +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES + + //! Create a full space optimized circular buffer filled with a copy of the range. + /*! + \pre Valid range [first, last).
+ first and last have to meet the requirements of + InputIterator. + \post capacity().%capacity() == std::distance(first, last) \&\& capacity().min_capacity() == 0 \&\& + full() \&\& (*this)[0]== *first \&\& (*this)[1] == *(first + 1) \&\& ... \&\& + (*this)[std::distance(first, last) - 1] == *(last - 1)

+ The amount of allocated memory in the internal buffer is std::distance(first, last). + \param first The beginning of the range to be copied. + \param last The end of the range to be copied. + \param alloc The allocator. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept + and InputIterator is a move iterator. + \par Complexity + Linear (in the std::distance(first, last)). + */ + template + circular_buffer_space_optimized(InputIterator first, InputIterator last, + const allocator_type& alloc = allocator_type()) + : circular_buffer(first, last, alloc) + , m_capacity_ctrl(circular_buffer::capacity()) {} + + /*! \brief Create a space optimized circular buffer with the specified capacity (and the minimal guaranteed amount + of allocated memory) filled with a copy of the range. + \pre Valid range [first, last).
+ first and last have to meet the requirements of + InputIterator. + \post capacity() == capacity_ctrl \&\& size() \<= std::distance(first, last) \&\& (*this)[0]== + *(last - capacity_ctrl.%capacity()) \&\& (*this)[1] == *(last - capacity_ctrl.%capacity() + 1) \&\& ... + \&\& (*this)[capacity_ctrl.%capacity() - 1] == *(last - 1)

+ If the number of items to be copied from the range [first, last) is greater than the + specified capacity_ctrl.%capacity() then only elements from the range + [last - capacity_ctrl.%capacity(), last) will be copied.

+ The amount of allocated memory in the internal buffer is max[capacity_ctrl.min_capacity(), + min[capacity_ctrl.%capacity(), std::distance(first, last)]]. + \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in + the circular_buffer_space_optimized and the minimal allocated size of the + internal buffer. + \param first The beginning of the range to be copied. + \param last The end of the range to be copied. + \param alloc The allocator. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Complexity + Linear (in std::distance(first, last); in + min[capacity_ctrl.%capacity(), std::distance(first, last)] if the InputIterator + is a RandomAccessIterator). + */ + template + circular_buffer_space_optimized(capacity_type capacity_ctrl, InputIterator first, InputIterator last, + const allocator_type& alloc = allocator_type()) + : circular_buffer( + init_capacity(capacity_ctrl, first, last, is_integral()), + first, last, alloc) + , m_capacity_ctrl(capacity_ctrl) { + reduce_capacity( + is_same< BOOST_DEDUCED_TYPENAME std::iterator_traits::iterator_category, std::input_iterator_tag >()); + } + +#if defined(BOOST_CB_NEVER_DEFINED) +// This section will never be compiled - the default destructor will be generated instead. +// Declared only for documentation purpose. + + //! The destructor. + /*! + Destroys the circular_buffer_space_optimized. + \throws Nothing. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (including + iterators equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa clear() + */ + ~circular_buffer_space_optimized(); + + //! no-comment + void erase_begin(size_type n); + + //! no-comment + void erase_end(size_type n); + +#endif // #if defined(BOOST_CB_NEVER_DEFINED) + + //! The assign operator. + /*! + Makes this circular_buffer_space_optimized to become a copy of the specified + circular_buffer_space_optimized. + \post *this == cb

+ The amount of allocated memory in the internal buffer is cb.size(). + \param cb The circular_buffer_space_optimized to be copied. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + \throws Whatever T::T(const T&) throws. + \par Exception Safety + Strong. + \par Iterator Invalidation + Invalidates all iterators pointing to this circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of cb). + \sa \link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink, + \link assign(capacity_type, size_type, param_value_type) + assign(capacity_type, size_type, const_reference)\endlink, + assign(InputIterator, InputIterator), + assign(capacity_type, InputIterator, InputIterator) + */ + circular_buffer_space_optimized& operator = (const circular_buffer_space_optimized& cb) { + if (this == &cb) + return *this; + circular_buffer::assign(cb.begin(), cb.end()); + m_capacity_ctrl = cb.m_capacity_ctrl; + return *this; + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + /*! \brief Move assigns content of cb to *this, leaving cb empty. + \pre C++ compiler with rvalue references support. + \post cb.empty() + \param cb circular_buffer to 'steal' value from. + \throws Nothing. + \par Complexity + Constant. + */ + circular_buffer_space_optimized& operator = (circular_buffer_space_optimized&& cb) BOOST_NOEXCEPT { + cb.swap(*this); // now `this` holds `cb` + circular_buffer(get_allocator()) // temporary that holds initial `cb` allocator + .swap(cb); // makes `cb` empty + return *this; + } +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES + + + //! Assign n items into the space optimized circular buffer. + /*! + The content of the circular_buffer_space_optimized will be removed and replaced with + n copies of the item. + \post capacity().%capacity() == n \&\& capacity().min_capacity() == 0 \&\& size() == n \&\& (*this)[0] == + item \&\& (*this)[1] == item \&\& ... \&\& (*this) [n - 1] == item

+ The amount of allocated memory in the internal buffer is n. + \param n The number of elements the circular_buffer_space_optimized will be filled with. + \param item The element the circular_buffer_space_optimized will be filled with. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the n). + \sa \link operator=(const circular_buffer_space_optimized&) operator=\endlink, + \link assign(capacity_type, size_type, param_value_type) + assign(capacity_type, size_type, const_reference)\endlink, + assign(InputIterator, InputIterator), + assign(capacity_type, InputIterator, InputIterator) + */ + void assign(size_type n, param_value_type item) { + circular_buffer::assign(n, item); + m_capacity_ctrl = capacity_type(n); + } + + //! Assign n items into the space optimized circular buffer specifying the capacity. + /*! + The capacity of the circular_buffer_space_optimized will be set to the specified value and the + content of the circular_buffer_space_optimized will be removed and replaced with n + copies of the item. + \pre capacity_ctrl.%capacity() >= n + \post capacity() == capacity_ctrl \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item + \&\& ... \&\& (*this) [n - 1] == item

+ The amount of allocated memory will be max[n, capacity_ctrl.min_capacity()]. + \param capacity_ctrl The new capacity controller. + \param n The number of elements the circular_buffer_space_optimized will be filled with. + \param item The element the circular_buffer_space_optimized will be filled with. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the n). + \sa \link operator=(const circular_buffer_space_optimized&) operator=\endlink, + \link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink, + assign(InputIterator, InputIterator), + assign(capacity_type, InputIterator, InputIterator) + */ + void assign(capacity_type capacity_ctrl, size_type n, param_value_type item) { + BOOST_CB_ASSERT(capacity_ctrl.capacity() >= n); // check for new capacity lower than n + circular_buffer::assign((std::max)(capacity_ctrl.min_capacity(), n), n, item); + m_capacity_ctrl = capacity_ctrl; + } + + //! Assign a copy of the range into the space optimized circular buffer. + /*! + The content of the circular_buffer_space_optimized will be removed and replaced with copies of + elements from the specified range. + \pre Valid range [first, last).
+ first and last have to meet the requirements of + InputIterator. + \post capacity().%capacity() == std::distance(first, last) \&\& capacity().min_capacity() == 0 \&\& + size() == std::distance(first, last) \&\& (*this)[0]== *first \&\& (*this)[1] == *(first + 1) \&\& ... + \&\& (*this)[std::distance(first, last) - 1] == *(last - 1)

+ The amount of allocated memory in the internal buffer is std::distance(first, last). + \param first The beginning of the range to be copied. + \param last The end of the range to be copied. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept and + InputIterator is a move iterator. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the std::distance(first, last)). + \sa \link operator=(const circular_buffer_space_optimized&) operator=\endlink, + \link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink, + \link assign(capacity_type, size_type, param_value_type) + assign(capacity_type, size_type, const_reference)\endlink, + assign(capacity_type, InputIterator, InputIterator) + */ + template + void assign(InputIterator first, InputIterator last) { + circular_buffer::assign(first, last); + m_capacity_ctrl = capacity_type(circular_buffer::capacity()); + } + + //! Assign a copy of the range into the space optimized circular buffer specifying the capacity. + /*! + The capacity of the circular_buffer_space_optimized will be set to the specified value and the + content of the circular_buffer_space_optimized will be removed and replaced with copies of + elements from the specified range. + \pre Valid range [first, last).
+ first and last have to meet the requirements of + InputIterator. + \post capacity() == capacity_ctrl \&\& size() \<= std::distance(first, last) \&\& + (*this)[0]== *(last - capacity) \&\& (*this)[1] == *(last - capacity + 1) \&\& ... \&\& + (*this)[capacity - 1] == *(last - 1)

+ If the number of items to be copied from the range [first, last) is greater than the + specified capacity then only elements from the range [last - capacity, last) + will be copied.

The amount of allocated memory in the internal buffer is + max[std::distance(first, last), capacity_ctrl.min_capacity()]. + \param capacity_ctrl The new capacity controller. + \param first The beginning of the range to be copied. + \param last The end of the range to be copied. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept and + InputIterator is a move iterator. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in std::distance(first, last); in + min[capacity_ctrl.%capacity(), std::distance(first, last)] if the InputIterator + is a RandomAccessIterator). + \sa \link operator=(const circular_buffer_space_optimized&) operator=\endlink, + \link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink, + \link assign(capacity_type, size_type, param_value_type) + assign(capacity_type, size_type, const_reference)\endlink, + assign(InputIterator, InputIterator) + */ + template + void assign(capacity_type capacity_ctrl, InputIterator first, InputIterator last) { + m_capacity_ctrl = capacity_ctrl; + circular_buffer::assign(capacity_ctrl, first, last); + } + + //! Swap the contents of two space-optimized circular-buffers. + /*! + \post this contains elements of cb and vice versa; the capacity and the amount of + allocated memory in the internal buffer of this equal to the capacity and the amount of + allocated memory of cb and vice versa. + \param cb The circular_buffer_space_optimized whose content will be swapped. + \throws Nothing. + \par Exception Safety + No-throw. + \par Iterator Invalidation + Invalidates all iterators of both circular_buffer_space_optimized containers. (On the other + hand the iterators still point to the same elements but within another container. If you want to rely on + this feature you have to turn the __debug_support off, + otherwise an assertion will report an error if such invalidated iterator is used.) + \par Complexity + Constant (in the size of the circular_buffer_space_optimized). + \sa swap(circular_buffer&, circular_buffer&), + swap(circular_buffer_space_optimized&, circular_buffer_space_optimized&) + + + */ + // Note link does not work right. Asked on Doxygen forum for advice 23 May 2103. + + void swap(circular_buffer_space_optimized& cb) BOOST_NOEXCEPT { + std::swap(m_capacity_ctrl, cb.m_capacity_ctrl); + circular_buffer::swap(cb); + } + + //! Insert a new element at the end of the space optimized circular buffer. + /*! + \post if capacity().%capacity() > 0 then back() == item
+ If the circular_buffer_space_optimized is full, the first element will be removed. If the + capacity is 0, nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param item The element to be inserted. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link push_front() push_front(const_reference)\endlink, pop_back(), + pop_front() + */ + void push_back(param_value_type item) { + check_low_capacity(); + circular_buffer::push_back(item); + } + + //! Insert a new element at the end of the space optimized circular buffer. + /*! + \post if capacity().%capacity() > 0 then back() == item
+ If the circular_buffer_space_optimized is full, the first element will be removed. If the + capacity is 0, nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param item The element to be inserted. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link push_front() push_front(const_reference)\endlink, pop_back(), + pop_front() + */ + void push_back(rvalue_type item) { + check_low_capacity(); + circular_buffer::push_back(boost::move(item)); + } + + //! Insert a new element at the end of the space optimized circular buffer. + /*! + \post if capacity().%capacity() > 0 then back() == item
+ If the circular_buffer_space_optimized is full, the first element will be removed. If the + capacity is 0, nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T() throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link push_front() push_front(const_reference)\endlink, pop_back(), + pop_front() + */ + void push_back() { + check_low_capacity(); + circular_buffer::push_back(); + } + + //! Insert a new element at the beginning of the space optimized circular buffer. + /*! + \post if capacity().%capacity() > 0 then front() == item
+ If the circular_buffer_space_optimized is full, the last element will be removed. If the + capacity is 0, nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param item The element to be inserted. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link push_back() push_back(const_reference)\endlink, pop_back(), + pop_front() + */ + void push_front(param_value_type item) { + check_low_capacity(); + circular_buffer::push_front(item); + } + + //! Insert a new element at the beginning of the space optimized circular buffer. + /*! + \post if capacity().%capacity() > 0 then front() == item
+ If the circular_buffer_space_optimized is full, the last element will be removed. If the + capacity is 0, nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param item The element to be inserted. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link push_back() push_back(const_reference)\endlink, pop_back(), + pop_front() + */ + void push_front(rvalue_type item) { + check_low_capacity(); + circular_buffer::push_front(boost::move(item)); + } + + //! Insert a new element at the beginning of the space optimized circular buffer. + /*! + \post if capacity().%capacity() > 0 then front() == item
+ If the circular_buffer_space_optimized is full, the last element will be removed. If the + capacity is 0, nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T() throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link push_back() push_back(const_reference)\endlink, pop_back(), + pop_front() + */ + void push_front() { + check_low_capacity(); + circular_buffer::push_front(); + } + + //! Remove the last element from the space optimized circular buffer. + /*! + \pre !empty() + \post The last element is removed from the circular_buffer_space_optimized.

+ The amount of allocated memory in the internal buffer may be predictively decreased. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa pop_front(), \link push_back() push_back(const_reference)\endlink, + \link push_front() push_front(const_reference)\endlink + */ + void pop_back() { + circular_buffer::pop_back(); + check_high_capacity(); + } + + //! Remove the first element from the space optimized circular buffer. + /*! + \pre !empty() + \post The first element is removed from the circular_buffer_space_optimized.

+ The amount of allocated memory in the internal buffer may be predictively decreased. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa pop_back(), \link push_back() push_back(const_reference)\endlink, + \link push_front() push_front(const_reference)\endlink + */ + void pop_front() { + circular_buffer::pop_front(); + check_high_capacity(); + } + + //! Insert an element at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its + end. + \post The item will be inserted at the position pos.
+ If the circular_buffer_space_optimized is full, the first element will be overwritten. If + the circular_buffer_space_optimized is full and the pos points to + begin(), then the item will not be inserted. If the capacity is 0, + nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param pos An iterator specifying the position where the item will be inserted. + \param item The element to be inserted. + \return Iterator to the inserted element or begin() if the item is not inserted. (See + the Effect.) + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator), + \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator) + */ + iterator insert(iterator pos, param_value_type item) { + size_type index = pos - begin(); + check_low_capacity(); + return circular_buffer::insert(begin() + index, item); + } + + //! Insert an element at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its + end. + \post The item will be inserted at the position pos.
+ If the circular_buffer_space_optimized is full, the first element will be overwritten. If + the circular_buffer_space_optimized is full and the pos points to + begin(), then the item will not be inserted. If the capacity is 0, + nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param pos An iterator specifying the position where the item will be inserted. + \param item The element to be inserted. + \return Iterator to the inserted element or begin() if the item is not inserted. (See + the Effect.) + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator), + \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator) + */ + iterator insert(iterator pos, rvalue_type item) { + size_type index = pos - begin(); + check_low_capacity(); + return circular_buffer::insert(begin() + index, boost::move(item)); + } + + //! Insert an element at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its + end. + \post The item will be inserted at the position pos.
+ If the circular_buffer_space_optimized is full, the first element will be overwritten. If + the circular_buffer_space_optimized is full and the pos points to + begin(), then the item will not be inserted. If the capacity is 0, + nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param pos An iterator specifying the position where the item will be inserted. + \return Iterator to the inserted element or begin() if the item is not inserted. (See + the Effect.) + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T() throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator), + \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator) + */ + iterator insert(iterator pos) { + size_type index = pos - begin(); + check_low_capacity(); + return circular_buffer::insert(begin() + index); + } + + //! Insert n copies of the item at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its + end. + \post The number of min[n, (pos - begin()) + reserve()] elements will be inserted at the position + pos.
The number of min[pos - begin(), max[0, n - reserve()]] elements will + be overwritten at the beginning of the circular_buffer_space_optimized.
(See + Example for the explanation.)

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param pos An iterator specifying the position where the items will be inserted. + \param n The number of items the to be inserted. + \param item The element whose copies will be inserted. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in min[capacity().%capacity(), size() + n]). + \par Example + Consider a circular_buffer_space_optimized with the capacity of 6 and the size of 4. Its + internal buffer may look like the one below.

+ |1|2|3|4| | |
+ p ___^

After inserting 5 elements at the position p:

+ insert(p, (size_t)5, 0);

actually only 4 elements get inserted and elements + 1 and 2 are overwritten. This is due to the fact the insert operation preserves + the capacity. After insertion the internal buffer looks like this:

|0|0|0|0|3|4|
+
For comparison if the capacity would not be preserved the internal buffer would then result in + |1|2|0|0|0|0|0|3|4|. + \sa \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + insert(iterator, InputIterator, InputIterator), + \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator) + */ + void insert(iterator pos, size_type n, param_value_type item) { + size_type index = pos - begin(); + check_low_capacity(n); + circular_buffer::insert(begin() + index, n, item); + } + + //! Insert the range [first, last) at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its + end.
Valid range [first, last) where first and last meet the + requirements of an InputIterator. + \post Elements from the range + [first + max[0, distance(first, last) - (pos - begin()) - reserve()], last) will be + inserted at the position pos.
The number of min[pos - begin(), max[0, + distance(first, last) - reserve()]] elements will be overwritten at the beginning of the + circular_buffer_space_optimized.
(See Example for the explanation.)

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param pos An iterator specifying the position where the range will be inserted. + \param first The beginning of the range to be inserted. + \param last The end of the range to be inserted. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in [size() + std::distance(first, last)]; in + min[capacity().%capacity(), size() + std::distance(first, last)] if the + InputIterator is a + RandomAccessIterator). + \par Example + Consider a circular_buffer_space_optimized with the capacity of 6 and the size of 4. Its + internal buffer may look like the one below.

+ |1|2|3|4| | |
+ p ___^

After inserting a range of elements at the position p:

+ int array[] = { 5, 6, 7, 8, 9 };
insert(p, array, array + 5);

+ actually only elements 6, 7, 8 and 9 from the + specified range get inserted and elements 1 and 2 are overwritten. This is due + to the fact the insert operation preserves the capacity. After insertion the internal buffer looks like + this:

|6|7|8|9|3|4|

For comparison if the capacity would not be preserved the + internal buffer would then result in |1|2|5|6|7|8|9|3|4|. + \sa \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, \link rinsert(iterator, param_value_type) + rinsert(iterator, value_type)\endlink, \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator) + */ + template + void insert(iterator pos, InputIterator first, InputIterator last) { + insert(pos, first, last, is_integral()); + } + + //! Insert an element before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its + end. + \post The item will be inserted before the position pos.
+ If the circular_buffer_space_optimized is full, the last element will be overwritten. If the + circular_buffer_space_optimized is full and the pos points to + end(), then the item will not be inserted. If the capacity is 0, + nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param pos An iterator specifying the position before which the item will be inserted. + \param item The element to be inserted. + \return Iterator to the inserted element or end() if the item is not inserted. (See + the Effect.) + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator), + \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + iterator rinsert(iterator pos, param_value_type item) { + size_type index = pos - begin(); + check_low_capacity(); + return circular_buffer::rinsert(begin() + index, item); + } + + //! Insert an element before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its + end. + \post The item will be inserted before the position pos.
+ If the circular_buffer_space_optimized is full, the last element will be overwritten. If the + circular_buffer_space_optimized is full and the pos points to + end(), then the item will not be inserted. If the capacity is 0, + nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param pos An iterator specifying the position before which the item will be inserted. + \param item The element to be inserted. + \return Iterator to the inserted element or end() if the item is not inserted. (See + the Effect.) + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator), + \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + iterator rinsert(iterator pos, rvalue_type item) { + size_type index = pos - begin(); + check_low_capacity(); + return circular_buffer::rinsert(begin() + index, boost::move(item)); + } + + //! Insert an element before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its + end. + \post The item will be inserted before the position pos.
+ If the circular_buffer_space_optimized is full, the last element will be overwritten. If the + circular_buffer_space_optimized is full and the pos points to + end(), then the item will not be inserted. If the capacity is 0, + nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param pos An iterator specifying the position before which the item will be inserted. + \return Iterator to the inserted element or end() if the item is not inserted. (See + the Effect.) + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T() throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator), + \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + iterator rinsert(iterator pos) { + size_type index = pos - begin(); + check_low_capacity(); + return circular_buffer::rinsert(begin() + index); + } + + //! Insert n copies of the item before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its + end. + \post The number of min[n, (end() - pos) + reserve()] elements will be inserted before the + position pos.
The number of min[end() - pos, max[0, n - reserve()]] elements + will be overwritten at the end of the circular_buffer_space_optimized.
(See + Example for the explanation.)

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param pos An iterator specifying the position where the items will be inserted. + \param n The number of items the to be inserted. + \param item The element whose copies will be inserted. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in min[capacity().%capacity(), size() + n]). + \par Example + Consider a circular_buffer_space_optimized with the capacity of 6 and the size of 4. Its + internal buffer may look like the one below.

+ |1|2|3|4| | |
+ p ___^

After inserting 5 elements before the position p:

+ rinsert(p, (size_t)5, 0);

actually only 4 elements get inserted and elements + 3 and 4 are overwritten. This is due to the fact the rinsert operation preserves + the capacity. After insertion the internal buffer looks like this:

|1|2|0|0|0|0|
+
For comparison if the capacity would not be preserved the internal buffer would then result in + |1|2|0|0|0|0|0|3|4|. + \sa \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator), + \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + void rinsert(iterator pos, size_type n, param_value_type item) { + size_type index = pos - begin(); + check_low_capacity(n); + circular_buffer::rinsert(begin() + index, n, item); + } + + //! Insert the range [first, last) before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its + end.
+ Valid range [first, last) where first and last meet the + requirements of an InputIterator. + \post Elements from the range + [first, last - max[0, distance(first, last) - (end() - pos) - reserve()]) will be inserted + before the position pos.
The number of min[end() - pos, max[0, + distance(first, last) - reserve()]] elements will be overwritten at the end of the + circular_buffer.
(See Example for the explanation.)

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param pos An iterator specifying the position where the range will be inserted. + \param first The beginning of the range to be inserted. + \param last The end of the range to be inserted. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in [size() + std::distance(first, last)]; in + min[capacity().%capacity(), size() + std::distance(first, last)] if the + InputIterator is a + RandomAccessIterator). + \par Example + Consider a circular_buffer_space_optimized with the capacity of 6 and the size of 4. Its + internal buffer may look like the one below.

+ |1|2|3|4| | |
+ p ___^

After inserting a range of elements before the position p:

+ int array[] = { 5, 6, 7, 8, 9 };
insert(p, array, array + 5);

+ actually only elements 5, 6, 7 and 8 from the + specified range get inserted and elements 3 and 4 are overwritten. This is due + to the fact the rinsert operation preserves the capacity. After insertion the internal buffer looks like + this:

|1|2|5|6|7|8|

For comparison if the capacity would not be preserved the + internal buffer would then result in |1|2|5|6|7|8|9|3|4|. + \sa \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, \link insert(iterator, param_value_type) + insert(iterator, value_type)\endlink, \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + template + void rinsert(iterator pos, InputIterator first, InputIterator last) { + rinsert(pos, first, last, is_integral()); + } + + //! Remove an element at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized (but not + an end()). + \post The element at the position pos is removed.

+ The amount of allocated memory in the internal buffer may be predictively decreased. + \param pos An iterator pointing at the element to be removed. + \return Iterator to the first element remaining beyond the removed element or end() if no such + element exists. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::operator = (const T&) throws or + nothing if T::operator = (T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa erase(iterator, iterator), rerase(iterator), + rerase(iterator, iterator), clear() + */ + iterator erase(iterator pos) { + iterator it = circular_buffer::erase(pos); + size_type index = it - begin(); + check_high_capacity(); + return begin() + index; + } + + //! Erase the range [first, last). + /*! + \pre Valid range [first, last). + \post The elements from the range [first, last) are removed. (If first == last + nothing is removed.)

+ The amount of allocated memory in the internal buffer may be predictively decreased. + \param first The beginning of the range to be removed. + \param last The end of the range to be removed. + \return Iterator to the first element remaining beyond the removed elements or end() if no such + element exists. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::operator = (const T&) throws or + nothing if T::operator = (T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa erase(iterator), rerase(iterator), rerase(iterator, iterator), + clear() + */ + iterator erase(iterator first, iterator last) { + iterator it = circular_buffer::erase(first, last); + size_type index = it - begin(); + check_high_capacity(); + return begin() + index; + } + + //! Remove an element at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized (but not + an end()).

+ The amount of allocated memory in the internal buffer may be predictively decreased. + \post The element at the position pos is removed. + \param pos An iterator pointing at the element to be removed. + \return Iterator to the first element remaining in front of the removed element or begin() if no + such element exists. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::operator = (const T&) throws or + nothing if T::operator = (T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \note Basically there is no difference between erase(iterator) and this method. It is implemented + only for consistency with the base circular_buffer. + \sa erase(iterator), erase(iterator, iterator), + rerase(iterator, iterator), clear() + */ + iterator rerase(iterator pos) { + iterator it = circular_buffer::rerase(pos); + size_type index = it - begin(); + check_high_capacity(); + return begin() + index; + } + + //! Erase the range [first, last). + /*! + \pre Valid range [first, last). + \post The elements from the range [first, last) are removed. (If first == last + nothing is removed.)

+ The amount of allocated memory in the internal buffer may be predictively decreased. + \param first The beginning of the range to be removed. + \param last The end of the range to be removed. + \return Iterator to the first element remaining in front of the removed elements or begin() if no + such element exists. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::operator = (const T&) throws or + nothing if T::operator = (T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \note Basically there is no difference between erase(iterator, iterator) and this method. It is + implemented only for consistency with the base + . + \sa erase(iterator), erase(iterator, iterator), rerase(iterator), + clear() + */ + iterator rerase(iterator first, iterator last) { + iterator it = circular_buffer::rerase(first, last); + size_type index = it - begin(); + check_high_capacity(); + return begin() + index; + } + + //! Remove all stored elements from the space optimized circular buffer. + /*! + \post size() == 0

+ The amount of allocated memory in the internal buffer may be predictively decreased. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa ~circular_buffer_space_optimized(), erase(iterator), + erase(iterator, iterator), rerase(iterator), + rerase(iterator, iterator) + */ + void clear() { erase(begin(), end()); } + +private: +// Helper methods + + /*! INTERNAL ONLY */ + void adjust_min_capacity() { + if (m_capacity_ctrl.min_capacity() > circular_buffer::capacity()) + circular_buffer::set_capacity(m_capacity_ctrl.min_capacity()); + else + check_high_capacity(); + } + + /*! INTERNAL ONLY */ + size_type ensure_reserve(size_type new_capacity, size_type buffer_size) const { + if (buffer_size + new_capacity / 5 >= new_capacity) + new_capacity *= 2; // ensure at least 20% reserve + if (new_capacity > m_capacity_ctrl) + return m_capacity_ctrl; + return new_capacity; + } + + /*! INTERNAL ONLY */ + void check_low_capacity(size_type n = 1) { + size_type new_size = size() + n; + size_type new_capacity = circular_buffer::capacity(); + if (new_size > new_capacity) { + if (new_capacity == 0) + new_capacity = 1; + for (; new_size > new_capacity; new_capacity *= 2) {} + circular_buffer::set_capacity( + ensure_reserve(new_capacity, new_size)); + } +#if BOOST_CB_ENABLE_DEBUG + this->invalidate_iterators_except(end()); +#endif + } + + /*! INTERNAL ONLY */ + void check_high_capacity() { + size_type new_capacity = circular_buffer::capacity(); + while (new_capacity / 3 >= size()) { // (new_capacity / 3) -> avoid oscillations + new_capacity /= 2; + if (new_capacity <= m_capacity_ctrl.min_capacity()) { + new_capacity = m_capacity_ctrl.min_capacity(); + break; + } + } + circular_buffer::set_capacity( + ensure_reserve(new_capacity, size())); +#if BOOST_CB_ENABLE_DEBUG + this->invalidate_iterators_except(end()); +#endif + } + + /*! INTERNAL ONLY */ + void reduce_capacity(const true_type&) { + circular_buffer::set_capacity((std::max)(m_capacity_ctrl.min_capacity(), size())); + } + + /*! INTERNAL ONLY */ + void reduce_capacity(const false_type&) {} + + /*! INTERNAL ONLY */ + static size_type init_capacity(const capacity_type& capacity_ctrl, size_type n) { + BOOST_CB_ASSERT(capacity_ctrl.capacity() >= n); // check for capacity lower than n + return (std::max)(capacity_ctrl.min_capacity(), n); + } + + /*! INTERNAL ONLY */ + template + static size_type init_capacity(const capacity_type& capacity_ctrl, IntegralType n, IntegralType, + const true_type&) { + return init_capacity(capacity_ctrl, static_cast(n)); + } + + /*! INTERNAL ONLY */ + template + static size_type init_capacity(const capacity_type& capacity_ctrl, Iterator first, Iterator last, + const false_type&) { + BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581)) + return init_capacity(capacity_ctrl, first, last, std::iterator_traits::iterator_category()); +#else + return init_capacity( + capacity_ctrl, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits::iterator_category()); +#endif + } + + /*! INTERNAL ONLY */ + template + static size_type init_capacity(const capacity_type& capacity_ctrl, InputIterator, InputIterator, + const std::input_iterator_tag&) { + return capacity_ctrl.capacity(); + } + + /*! INTERNAL ONLY */ + template + static size_type init_capacity(const capacity_type& capacity_ctrl, ForwardIterator first, ForwardIterator last, + const std::forward_iterator_tag&) { + BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range + return (std::max)(capacity_ctrl.min_capacity(), + (std::min)(capacity_ctrl.capacity(), static_cast(std::distance(first, last)))); + } + + /*! INTERNAL ONLY */ + template + void insert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) { + insert(pos, static_cast(n), static_cast(item)); + } + + /*! INTERNAL ONLY */ + template + void insert(const iterator& pos, Iterator first, Iterator last, const false_type&) { + size_type index = pos - begin(); + check_low_capacity(std::distance(first, last)); + circular_buffer::insert(begin() + index, first, last); + } + + /*! INTERNAL ONLY */ + template + void rinsert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) { + rinsert(pos, static_cast(n), static_cast(item)); + } + + /*! INTERNAL ONLY */ + template + void rinsert(const iterator& pos, Iterator first, Iterator last, const false_type&) { + size_type index = pos - begin(); + check_low_capacity(std::distance(first, last)); + circular_buffer::rinsert(begin() + index, first, last); + } +}; + +// Non-member functions + +//! Test two space optimized circular buffers for equality. +template +inline bool operator == (const circular_buffer_space_optimized& lhs, + const circular_buffer_space_optimized& rhs) { + return lhs.size() == rhs.size() && + std::equal(lhs.begin(), lhs.end(), rhs.begin()); +} + +//! Lexicographical comparison. +template +inline bool operator < (const circular_buffer_space_optimized& lhs, + const circular_buffer_space_optimized& rhs) { + return std::lexicographical_compare( + lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); +} + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) + +//! Test two space optimized circular buffers for non-equality. +template +inline bool operator != (const circular_buffer_space_optimized& lhs, + const circular_buffer_space_optimized& rhs) { + return !(lhs == rhs); +} + +//! Lexicographical comparison. +template +inline bool operator > (const circular_buffer_space_optimized& lhs, + const circular_buffer_space_optimized& rhs) { + return rhs < lhs; +} + +//! Lexicographical comparison. +template +inline bool operator <= (const circular_buffer_space_optimized& lhs, + const circular_buffer_space_optimized& rhs) { + return !(rhs < lhs); +} + +//! Lexicographical comparison. +template +inline bool operator >= (const circular_buffer_space_optimized& lhs, + const circular_buffer_space_optimized& rhs) { + return !(lhs < rhs); +} + +//! Swap the contents of two space optimized circular buffers. +template +inline void swap(circular_buffer_space_optimized& lhs, + circular_buffer_space_optimized& rhs) BOOST_NOEXCEPT { + lhs.swap(rhs); +} + +#endif // #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) + +} // namespace boost + +#endif // #if !defined(BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP) diff --git a/boost/circular_buffer_fwd.hpp b/boost/circular_buffer_fwd.hpp new file mode 100644 index 00000000..621fb953 --- /dev/null +++ b/boost/circular_buffer_fwd.hpp @@ -0,0 +1,43 @@ +// Forward declaration of the circular buffer and its adaptor. + +// Copyright (c) 2003-2008 Jan Gaspar + +// 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 www.boost.org/libs/circular_buffer for documentation. + +#if !defined(BOOST_CIRCULAR_BUFFER_FWD_HPP) +#define BOOST_CIRCULAR_BUFFER_FWD_HPP + +#if defined(_MSC_VER) + #pragma once +#endif + +#include +#if !defined(BOOST_NO_STD_ALLOCATOR) + #include +#else + #include +#endif + +namespace boost { + +#if !defined(BOOST_NO_STD_ALLOCATOR) + #define BOOST_CB_DEFAULT_ALLOCATOR(T) std::allocator +#else + #define BOOST_CB_DEFAULT_ALLOCATOR(T) BOOST_DEDUCED_TYPENAME std::vector::allocator_type +#endif + +template +class circular_buffer; + +template +class circular_buffer_space_optimized; + +#undef BOOST_CB_DEFAULT_ALLOCATOR + +} // namespace boost + +#endif // #if !defined(BOOST_CIRCULAR_BUFFER_FWD_HPP) diff --git a/boost/detail/templated_streams.hpp b/boost/detail/templated_streams.hpp new file mode 100644 index 00000000..1fa6ee35 --- /dev/null +++ b/boost/detail/templated_streams.hpp @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// boost detail/templated_streams.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_DETAIL_TEMPLATED_STREAMS_HPP +#define BOOST_DETAIL_TEMPLATED_STREAMS_HPP + +#include "boost/config.hpp" + +/////////////////////////////////////////////////////////////////////////////// +// (detail) BOOST_TEMPLATED_STREAM_* macros +// +// Provides workaround platforms without stream class templates. +// + +#if !defined(BOOST_NO_STD_LOCALE) + +#define BOOST_TEMPLATED_STREAM_TEMPLATE(E,T) \ + template < typename E , typename T > + +#define BOOST_TEMPLATED_STREAM_TEMPLATE_ALLOC(E,T,A) \ + template < typename E , typename T , typename A > + +#define BOOST_TEMPLATED_STREAM_ARGS(E,T) \ + typename E , typename T + +#define BOOST_TEMPLATED_STREAM_ARGS_ALLOC(E,T,A) \ + typename E , typename T , typename A + +#define BOOST_TEMPLATED_STREAM_COMMA , + +#define BOOST_TEMPLATED_STREAM_ELEM(E) E +#define BOOST_TEMPLATED_STREAM_TRAITS(T) T +#define BOOST_TEMPLATED_STREAM_ALLOC(A) A + +#define BOOST_TEMPLATED_STREAM(X,E,T) \ + BOOST_JOIN(std::basic_,X)< E , T > + +#define BOOST_TEMPLATED_STREAM_WITH_ALLOC(X,E,T,A) \ + BOOST_JOIN(std::basic_,X)< E , T , A > + +#else // defined(BOOST_NO_STD_LOCALE) + +#define BOOST_TEMPLATED_STREAM_TEMPLATE(E,T) /**/ + +#define BOOST_TEMPLATED_STREAM_TEMPLATE_ALLOC(E,T,A) /**/ + +#define BOOST_TEMPLATED_STREAM_ARGS(E,T) /**/ + +#define BOOST_TEMPLATED_STREAM_ARGS_ALLOC(E,T,A) /**/ + +#define BOOST_TEMPLATED_STREAM_COMMA /**/ + +#define BOOST_TEMPLATED_STREAM_ELEM(E) char +#define BOOST_TEMPLATED_STREAM_TRAITS(T) std::char_traits +#define BOOST_TEMPLATED_STREAM_ALLOC(A) std::allocator + +#define BOOST_TEMPLATED_STREAM(X,E,T) \ + std::X + +#define BOOST_TEMPLATED_STREAM_WITH_ALLOC(X,E,T,A) \ + std::X + +#endif // BOOST_NO_STD_LOCALE + +#endif // BOOST_DETAIL_TEMPLATED_STREAMS_HPP diff --git a/boost/integer/common_factor_ct.hpp b/boost/integer/common_factor_ct.hpp new file mode 100644 index 00000000..5769fa2d --- /dev/null +++ b/boost/integer/common_factor_ct.hpp @@ -0,0 +1,102 @@ +// Boost common_factor_ct.hpp header file ----------------------------------// + +// (C) Copyright Daryle Walker and Stephen Cleary 2001-2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// See https://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_INTEGER_COMMON_FACTOR_CT_HPP +#define BOOST_INTEGER_COMMON_FACTOR_CT_HPP + +#include // self include +#include // for BOOST_STATIC_CONSTANT, etc. + +namespace boost +{ +namespace integer +{ + +// Implementation details --------------------------------------------------// + +namespace detail +{ + // Build GCD with Euclid's recursive algorithm + template < static_gcd_type Value1, static_gcd_type Value2 > + struct static_gcd_helper_t + { + private: + BOOST_STATIC_CONSTANT( static_gcd_type, new_value1 = Value2 ); + BOOST_STATIC_CONSTANT( static_gcd_type, new_value2 = Value1 % Value2 ); + + #ifndef BOOST_BORLANDC + #define BOOST_DETAIL_GCD_HELPER_VAL(Value) static_cast(Value) + #else + typedef static_gcd_helper_t self_type; + #define BOOST_DETAIL_GCD_HELPER_VAL(Value) (self_type:: Value ) + #endif + + typedef static_gcd_helper_t< BOOST_DETAIL_GCD_HELPER_VAL(new_value1), + BOOST_DETAIL_GCD_HELPER_VAL(new_value2) > next_step_type; + + #undef BOOST_DETAIL_GCD_HELPER_VAL + + public: + BOOST_STATIC_CONSTANT( static_gcd_type, value = next_step_type::value ); + }; + + // Non-recursive case + template < static_gcd_type Value1 > + struct static_gcd_helper_t< Value1, 0UL > + { + BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 ); + }; + + // Build the LCM from the GCD + template < static_gcd_type Value1, static_gcd_type Value2 > + struct static_lcm_helper_t + { + typedef static_gcd_helper_t gcd_type; + + BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 / gcd_type::value + * Value2 ); + }; + + // Special case for zero-GCD values + template < > + struct static_lcm_helper_t< 0UL, 0UL > + { + BOOST_STATIC_CONSTANT( static_gcd_type, value = 0UL ); + }; + +} // namespace detail + + +// Compile-time greatest common divisor evaluator class declaration --------// + +template < static_gcd_type Value1, static_gcd_type Value2 > struct static_gcd +{ + BOOST_STATIC_CONSTANT( static_gcd_type, value = (detail::static_gcd_helper_t::value) ); +}; // boost::integer::static_gcd + +#if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) +template< static_gcd_type Value1, static_gcd_type Value2 > static_gcd_type const static_gcd< Value1, Value2 >::value; +#endif + +// Compile-time least common multiple evaluator class declaration ----------// + +template < static_gcd_type Value1, static_gcd_type Value2 > struct static_lcm +{ + BOOST_STATIC_CONSTANT( static_gcd_type, value = (detail::static_lcm_helper_t::value) ); +}; // boost::integer::static_lcm + +#if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) +template< static_gcd_type Value1, static_gcd_type Value2 > static_gcd_type const static_lcm< Value1, Value2 >::value; +#endif + +} // namespace integer +} // namespace boost + + +#endif // BOOST_INTEGER_COMMON_FACTOR_CT_HPP diff --git a/boost/integer/integer_log2.hpp b/boost/integer/integer_log2.hpp deleted file mode 100644 index 8ca236f6..00000000 --- a/boost/integer/integer_log2.hpp +++ /dev/null @@ -1,117 +0,0 @@ -// ----------------------------------------------------------- -// integer_log2.hpp -// -// Gives the integer part of the logarithm, in base 2, of a -// given number. Behavior is undefined if the argument is <= 0. -// -// Copyright (c) 2003-2004, 2008 Gennaro Prota -// Copyright (c) 2022 Andrey Semashev -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// https://www.boost.org/LICENSE_1_0.txt) -// -// ----------------------------------------------------------- - -#ifndef BOOST_INTEGER_INTEGER_LOG2_HPP -#define BOOST_INTEGER_INTEGER_LOG2_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace detail { - -// helper to find the maximum power of two -// less than p -template< unsigned int p, unsigned int n, bool = ((2u * n) < p) > -struct max_pow2_less : - public max_pow2_less< p, 2u * n > -{ -}; - -template< unsigned int p, unsigned int n > -struct max_pow2_less< p, n, false > -{ - BOOST_STATIC_CONSTANT(unsigned int, value = n); -}; - -template< typename T > -inline typename boost::disable_if< boost::is_integral< T >, int >::type integer_log2_impl(T x) -{ - unsigned int n = detail::max_pow2_less< - std::numeric_limits< T >::digits, - CHAR_BIT / 2u - >::value; - - int result = 0; - while (x != 1) - { - T t(x >> n); - if (t) - { - result += static_cast< int >(n); -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - x = static_cast< T&& >(t); -#else - x = t; -#endif - } - n >>= 1u; - } - - return result; -} - -template< typename T > -inline typename boost::enable_if< boost::is_integral< T >, int >::type integer_log2_impl(T x) -{ - // We could simply rely on numeric_limits but sometimes - // Borland tries to use numeric_limits, because - // of its usual const-related problems in argument deduction - // - gps - return static_cast< int >((sizeof(T) * CHAR_BIT - 1u) - - boost::core::countl_zero(static_cast< typename boost::make_unsigned< T >::type >(x))); -} - -#if defined(BOOST_HAS_INT128) -// We need to provide explicit overloads for __int128 because (a) boost/core/bit.hpp currently does not support it and -// (b) std::numeric_limits are not specialized for __int128 in some standard libraries. -inline int integer_log2_impl(boost::uint128_type x) -{ - const boost::uint64_t x_hi = static_cast< boost::uint64_t >(x >> 64u); - if (x_hi != 0u) - return 127 - boost::core::countl_zero(x_hi); - else - return 63 - boost::core::countl_zero(static_cast< boost::uint64_t >(x)); -} - -inline int integer_log2_impl(boost::int128_type x) -{ - return detail::integer_log2_impl(static_cast< boost::uint128_type >(x)); -} -#endif // defined(BOOST_HAS_INT128) - -} // namespace detail - - -// ------------ -// integer_log2 -// ------------ -template< typename T > -inline int integer_log2(T x) -{ - BOOST_ASSERT(x > 0); - return detail::integer_log2_impl(x); -} - -} // namespace boost - -#endif // BOOST_INTEGER_INTEGER_LOG2_HPP diff --git a/boost/integer/integer_mask.hpp b/boost/integer/integer_mask.hpp deleted file mode 100644 index 3be5035b..00000000 --- a/boost/integer/integer_mask.hpp +++ /dev/null @@ -1,134 +0,0 @@ -// Boost integer/integer_mask.hpp header file ------------------------------// - -// (C) Copyright Daryle Walker 2001. -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// https://www.boost.org/LICENSE_1_0.txt) - -// See https://www.boost.org for updates, documentation, and revision history. - -#ifndef BOOST_INTEGER_INTEGER_MASK_HPP -#define BOOST_INTEGER_INTEGER_MASK_HPP - -#include // self include - -#include // for BOOST_STATIC_CONSTANT -#include // for boost::uint_t - -#include // for UCHAR_MAX, etc. -#include // for std::size_t - -#include // for std::numeric_limits - -// -// We simply cannot include this header on gcc without getting copious warnings of the kind: -// -// boost/integer/integer_mask.hpp:93:35: warning: use of C99 long long integer constant -// -// And yet there is no other reasonable implementation, so we declare this a system header -// to suppress these warnings. -// -#if defined(__GNUC__) && (__GNUC__ >= 4) -#pragma GCC system_header -#endif - -namespace boost -{ - - -// Specified single-bit mask class declaration -----------------------------// -// (Lowest bit starts counting at 0.) - -template < std::size_t Bit > -struct high_bit_mask_t -{ - typedef typename uint_t<(Bit + 1)>::least least; - typedef typename uint_t<(Bit + 1)>::fast fast; - - BOOST_STATIC_CONSTANT( least, high_bit = (least( 1u ) << Bit) ); - BOOST_STATIC_CONSTANT( fast, high_bit_fast = (fast( 1u ) << Bit) ); - - BOOST_STATIC_CONSTANT( std::size_t, bit_position = Bit ); - -}; // boost::high_bit_mask_t - - -// Specified bit-block mask class declaration ------------------------------// -// Makes masks for the lowest N bits -// (Specializations are needed when N fills up a type.) - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:4310) // cast truncates constant value -#endif - -template < std::size_t Bits > -struct low_bits_mask_t -{ - typedef typename uint_t::least least; - typedef typename uint_t::fast fast; - - BOOST_STATIC_CONSTANT( least, sig_bits = least(~(least(~(least( 0u ))) << Bits )) ); - BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); - - BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits ); - -}; // boost::low_bits_mask_t - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#define BOOST_LOW_BITS_MASK_SPECIALIZE( Type ) \ - template < > struct low_bits_mask_t< std::numeric_limits::digits > { \ - typedef std::numeric_limits limits_type; \ - typedef uint_t::least least; \ - typedef uint_t::fast fast; \ - BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) ); \ - BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); \ - BOOST_STATIC_CONSTANT( std::size_t, bit_count = limits_type::digits ); \ - } - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:4245) // 'initializing' : conversion from 'int' to 'const boost::low_bits_mask_t<8>::least', signed/unsigned mismatch -#endif - -BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned char ); - -#if USHRT_MAX > UCHAR_MAX -BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned short ); -#endif - -#if UINT_MAX > USHRT_MAX -BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned int ); -#endif - -#if ULONG_MAX > UINT_MAX -BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned long ); -#endif - -#if defined(BOOST_HAS_LONG_LONG) - #if ((defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX)) ||\ - (defined(ULONG_LONG_MAX) && (ULONG_LONG_MAX > ULONG_MAX)) ||\ - (defined(ULONGLONG_MAX) && (ULONGLONG_MAX > ULONG_MAX)) ||\ - (defined(_ULLONG_MAX) && (_ULLONG_MAX > ULONG_MAX))) - BOOST_LOW_BITS_MASK_SPECIALIZE( boost::ulong_long_type ); - #endif -#elif defined(BOOST_HAS_MS_INT64) - #if 18446744073709551615ui64 > ULONG_MAX - BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned __int64 ); - #endif -#endif - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#undef BOOST_LOW_BITS_MASK_SPECIALIZE - - -} // namespace boost - - -#endif // BOOST_INTEGER_INTEGER_MASK_HPP diff --git a/boost/integer/static_log2.hpp b/boost/integer/static_log2.hpp deleted file mode 100644 index 325ea2c1..00000000 --- a/boost/integer/static_log2.hpp +++ /dev/null @@ -1,126 +0,0 @@ -// -------------- Boost static_log2.hpp header file ----------------------- // -// -// Copyright (C) 2001 Daryle Walker. -// Copyright (C) 2003 Vesa Karvonen. -// Copyright (C) 2003 Gennaro Prota. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// https://www.boost.org/LICENSE_1_0.txt) -// -// --------------------------------------------------- -// See https://www.boost.org/libs/integer for documentation. -// ------------------------------------------------------------------------- // - - -#ifndef BOOST_INTEGER_STATIC_LOG2_HPP -#define BOOST_INTEGER_STATIC_LOG2_HPP - -#include -#include - -namespace boost { - - namespace detail { - - namespace static_log2_impl { - - // choose_initial_n<> - // - // Recursively doubles its integer argument, until it - // becomes >= of the "width" (C99, 6.2.6.2p4) of - // static_log2_argument_type. - // - // Used to get the maximum power of two less then the width. - // - // Example: if on your platform argument_type has 48 value - // bits it yields n=32. - // - // It's easy to prove that, starting from such a value - // of n, the core algorithm works correctly for any width - // of static_log2_argument_type and that recursion always - // terminates with x = 1 and n = 0 (see the algorithm's - // invariant). - - typedef boost::static_log2_argument_type argument_type; - typedef boost::static_log2_result_type result_type; - - template - struct choose_initial_n { - - BOOST_STATIC_CONSTANT(bool, c = (argument_type(1) << n << n) != 0); - BOOST_STATIC_CONSTANT( - result_type, - value = !c*n + choose_initial_n<2*c*n>::value - ); - - }; - - template <> - struct choose_initial_n<0> { - BOOST_STATIC_CONSTANT(result_type, value = 0); - }; - - - - // start computing from n_zero - must be a power of two - const result_type n_zero = 16; - const result_type initial_n = choose_initial_n::value; - - // static_log2_impl<> - // - // * Invariant: - // 2n - // 1 <= x && x < 2 at the start of each recursion - // (see also choose_initial_n<>) - // - // * Type requirements: - // - // argument_type maybe any unsigned type with at least n_zero + 1 - // value bits. (Note: If larger types will be standardized -e.g. - // unsigned long long- then the argument_type typedef can be - // changed without affecting the rest of the code.) - // - - template - struct static_log2_impl { - - BOOST_STATIC_CONSTANT(bool, c = (x >> n) > 0); // x >= 2**n ? - BOOST_STATIC_CONSTANT( - result_type, - value = c*n + (static_log2_impl< (x>>c*n), n/2 >::value) - ); - - }; - - template <> - struct static_log2_impl<1, 0> { - BOOST_STATIC_CONSTANT(result_type, value = 0); - }; - - } - } // detail - - - - // -------------------------------------- - // static_log2 - // ---------------------------------------- - - template - struct static_log2 { - - BOOST_STATIC_CONSTANT( - static_log2_result_type, - value = detail::static_log2_impl::static_log2_impl::value - ); - - }; - - - template <> - struct static_log2<0> { }; - -} - -#endif // include guard diff --git a/boost/iostreams/chain.hpp b/boost/iostreams/chain.hpp deleted file mode 100644 index a7d7dd71..00000000 --- a/boost/iostreams/chain.hpp +++ /dev/null @@ -1,594 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_DETAIL_CHAIN_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_CHAIN_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#include -#include // advance. -#include -#include // allocator, auto_ptr or unique_ptr. -#include // logic_error, out_of_range. -#include -#include // BOOST_MSVC, template friends, -#include // BOOST_NESTED_TEMPLATE -#include -#include -#include -#include -#include -#include // pubsync. -#include -#include -#include -#include // is_filter. -#include -#include -#include -#include -#include -#include -#include -#include - -// Sometimes type_info objects must be compared by name. Borrowed from -// Boost.Python and Boost.Function. -#if defined(__GNUC__) || \ - defined(_AIX) || \ - (defined(__sgi) && defined(__host_mips)) || \ - (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC)) \ - /**/ -# include -# define BOOST_IOSTREAMS_COMPARE_TYPE_ID(X,Y) \ - (std::strcmp((X).name(),(Y).name()) == 0) -#else -# define BOOST_IOSTREAMS_COMPARE_TYPE_ID(X,Y) ((X)==(Y)) -#endif - -// Deprecated. Unused. -#define BOOST_IOSTREAMS_COMPONENT_TYPE(chain, index) \ - chain.component_type( index ) \ - /**/ - -// Deprecated. Unused. -#define BOOST_IOSTREAMS_COMPONENT(chain, index, target) \ - chain.component< target >( index ) \ - /**/ - -namespace boost { namespace iostreams { - -//--------------Definition of chain and wchain--------------------------------// - -namespace detail { - -template class chain_client; - -// -// Concept name: Chain. -// Description: Represents a chain of stream buffers which provides access -// to the first buffer in the chain and sends notifications when the -// streambufs are added to or removed from chain. -// Refines: Closable device with mode equal to typename Chain::mode. -// Models: chain, converting_chain. -// Example: -// -// class chain { -// public: -// typedef xxx chain_type; -// typedef xxx client_type; -// typedef xxx mode; -// bool is_complete() const; // Ready for i/o. -// template -// void push( const T& t, // Adds a stream buffer to -// streamsize, // chain, based on t, with -// streamsize ); // given buffer and putback -// // buffer sizes. Pass -1 to -// // request default size. -// protected: -// void register_client(client_type* client); // Associate client. -// void notify(); // Notify client. -// }; -// - -// -// Description: Represents a chain of filters with an optional device at the -// end. -// Template parameters: -// Self - A class deriving from the current instantiation of this template. -// This is an example of the Curiously Recurring Template Pattern. -// Ch - The character type. -// Tr - The character traits type. -// Alloc - The allocator type. -// Mode - A mode tag. -// -template -class chain_base { -public: - typedef Ch char_type; - BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) - typedef Alloc allocator_type; - typedef Mode mode; - struct category - : Mode, - device_tag - { }; - typedef chain_client client_type; - friend class chain_client; -private: - typedef linked_streambuf streambuf_type; - typedef std::list list_type; - typedef chain_base my_type; -protected: - chain_base() : pimpl_(new chain_impl) { } - chain_base(const chain_base& rhs): pimpl_(rhs.pimpl_) { } -public: - - // dual_use is a pseudo-mode to facilitate filter writing, - // not a genuine mode. - BOOST_STATIC_ASSERT((!is_convertible::value)); - - //----------Buffer sizing-------------------------------------------------// - - // Sets the size of the buffer created for the devices to be added to this - // chain. Does not affect the size of the buffer for devices already - // added. - void set_device_buffer_size(std::streamsize n) - { pimpl_->device_buffer_size_ = n; } - - // Sets the size of the buffer created for the filters to be added - // to this chain. Does not affect the size of the buffer for filters already - // added. - void set_filter_buffer_size(std::streamsize n) - { pimpl_->filter_buffer_size_ = n; } - - // Sets the size of the putback buffer for filters and devices to be added - // to this chain. Does not affect the size of the buffer for filters or - // devices already added. - void set_pback_size(std::streamsize n) - { pimpl_->pback_size_ = n; } - - //----------Device interface----------------------------------------------// - - std::streamsize read(char_type* s, std::streamsize n); - std::streamsize write(const char_type* s, std::streamsize n); - std::streampos seek(stream_offset off, BOOST_IOS::seekdir way); - - //----------Direct component access---------------------------------------// - - const boost::core::typeinfo& component_type(int n) const - { - if (static_cast(n) >= size()) - boost::throw_exception(std::out_of_range("bad chain offset")); - return (*boost::next(list().begin(), n))->component_type(); - } - - // Deprecated. - template - const boost::core::typeinfo& component_type() const { return component_type(N); } - - template - T* component(int n) const { return component(n, boost::type()); } - - // Deprecated. - template - T* component() const { return component(N); } - -#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310) - private: -#endif - template - T* component(int n, boost::type) const - { - if (static_cast(n) >= size()) - boost::throw_exception(std::out_of_range("bad chain offset")); - streambuf_type* link = *boost::next(list().begin(), n); - if (BOOST_IOSTREAMS_COMPARE_TYPE_ID(link->component_type(), BOOST_CORE_TYPEID(T))) - return static_cast(link->component_impl()); - else - return 0; - } -public: - - //----------Container-like interface--------------------------------------// - - typedef typename list_type::size_type size_type; - streambuf_type& front() { return *list().front(); } - BOOST_IOSTREAMS_DEFINE_PUSH(push, mode, char_type, push_impl) - void pop(); - bool empty() const { return list().empty(); } - size_type size() const { return list().size(); } - void reset(); - - //----------Additional i/o functions--------------------------------------// - - // Returns true if this chain is non-empty and its final link - // is a source or sink, i.e., if it is ready to perform i/o. - bool is_complete() const; - bool auto_close() const; - void set_auto_close(bool close); - bool sync() { return front().BOOST_IOSTREAMS_PUBSYNC() != -1; } - bool strict_sync(); -private: - template - void push_impl(const T& t, std::streamsize buffer_size = -1, - std::streamsize pback_size = -1) - { - typedef typename iostreams::category_of::type category; - typedef typename unwrap_ios::type component_type; - typedef stream_buffer< - component_type, - BOOST_IOSTREAMS_CHAR_TRAITS(char_type), - Alloc, Mode - > streambuf_t; - typedef typename list_type::iterator iterator; - BOOST_STATIC_ASSERT((is_convertible::value)); - if (is_complete()) - boost::throw_exception(std::logic_error("chain complete")); - streambuf_type* prev = !empty() ? list().back() : 0; - buffer_size = - buffer_size != -1 ? - buffer_size : - iostreams::optimal_buffer_size(t); - pback_size = - pback_size != -1 ? - pback_size : - pimpl_->pback_size_; - -#if defined(BOOST_NO_CXX11_SMART_PTR) - - std::auto_ptr - buf(new streambuf_t(t, buffer_size, pback_size)); - -#else - - std::unique_ptr - buf(new streambuf_t(t, buffer_size, pback_size)); - -#endif - - list().push_back(buf.get()); - buf.release(); - if (is_device::value) { - pimpl_->flags_ |= f_complete | f_open; - for ( iterator first = list().begin(), - last = list().end(); - first != last; - ++first ) - { - (*first)->set_needs_close(); - } - } - if (prev) prev->set_next(list().back()); - notify(); - } - - list_type& list() { return pimpl_->links_; } - const list_type& list() const { return pimpl_->links_; } - void register_client(client_type* client) { pimpl_->client_ = client; } - void notify() { if (pimpl_->client_) pimpl_->client_->notify(); } - - //----------Nested classes------------------------------------------------// - - static void close(streambuf_type* b, BOOST_IOS::openmode m) - { - if (m == BOOST_IOS::out && is_convertible::value) - b->BOOST_IOSTREAMS_PUBSYNC(); - b->close(m); - } - - static void set_next(streambuf_type* b, streambuf_type* next) - { b->set_next(next); } - - static void set_auto_close(streambuf_type* b, bool close) - { b->set_auto_close(close); } - - struct closer { - typedef streambuf_type* argument_type; - typedef void result_type; - closer(BOOST_IOS::openmode m) : mode_(m) { } - void operator() (streambuf_type* b) - { - close(b, mode_); - } - BOOST_IOS::openmode mode_; - }; - friend struct closer; - - enum flags { - f_complete = 1, - f_open = 2, - f_auto_close = 4 - }; - - struct chain_impl { - chain_impl() - : client_(0), device_buffer_size_(default_device_buffer_size), - filter_buffer_size_(default_filter_buffer_size), - pback_size_(default_pback_buffer_size), - flags_(f_auto_close) - { } - ~chain_impl() - { - try { close(); } catch (...) { } - try { reset(); } catch (...) { } - } - void close() - { - if ((flags_ & f_open) != 0) { - flags_ &= ~f_open; - stream_buffer< basic_null_device > null; - if ((flags_ & f_complete) == 0) { - null.open(basic_null_device()); - set_next(links_.back(), &null); - } - links_.front()->BOOST_IOSTREAMS_PUBSYNC(); - try { - boost::iostreams::detail::execute_foreach( - links_.rbegin(), links_.rend(), - closer(BOOST_IOS::in) - ); - } catch (...) { - try { - boost::iostreams::detail::execute_foreach( - links_.begin(), links_.end(), - closer(BOOST_IOS::out) - ); - } catch (...) { } - throw; - } - boost::iostreams::detail::execute_foreach( - links_.begin(), links_.end(), - closer(BOOST_IOS::out) - ); - } - } - void reset() - { - typedef typename list_type::iterator iterator; - for ( iterator first = links_.begin(), - last = links_.end(); - first != last; - ++first ) - { - if ( (flags_ & f_complete) == 0 || - (flags_ & f_auto_close) == 0 ) - { - set_auto_close(*first, false); - } - streambuf_type* buf = 0; - std::swap(buf, *first); - delete buf; - } - links_.clear(); - flags_ &= ~f_complete; - flags_ &= ~f_open; - } - list_type links_; - client_type* client_; - std::streamsize device_buffer_size_, - filter_buffer_size_, - pback_size_; - int flags_; - }; - friend struct chain_impl; - - //----------Member data---------------------------------------------------// - -private: - shared_ptr pimpl_; -}; - -} // End namespace detail. - -// -// Macro: BOOST_IOSTREAMS_DECL_CHAIN(name, category) -// Description: Defines a template derived from chain_base appropriate for a -// particular i/o category. The template has the following parameters: -// Ch - The character type. -// Tr - The character traits type. -// Alloc - The allocator type. -// Macro parameters: -// name_ - The name of the template to be defined. -// category_ - The i/o category of the template to be defined. -// -#define BOOST_IOSTREAMS_DECL_CHAIN(name_, default_char_) \ - template< typename Mode, typename Ch = default_char_, \ - typename Tr = BOOST_IOSTREAMS_CHAR_TRAITS(Ch), \ - typename Alloc = std::allocator > \ - class name_ : public boost::iostreams::detail::chain_base< \ - name_, \ - Ch, Tr, Alloc, Mode \ - > \ - { \ - public: \ - struct category : device_tag, Mode { }; \ - typedef Mode mode; \ - private: \ - typedef boost::iostreams::detail::chain_base< \ - name_, \ - Ch, Tr, Alloc, Mode \ - > base_type; \ - public: \ - typedef Ch char_type; \ - typedef Tr traits_type; \ - typedef typename traits_type::int_type int_type; \ - typedef typename traits_type::off_type off_type; \ - name_() { } \ - name_(const name_& rhs) : base_type(rhs) { } \ - name_& operator=(const name_& rhs) \ - { base_type::operator=(rhs); return *this; } \ - }; \ - /**/ -BOOST_IOSTREAMS_DECL_CHAIN(chain, char) -BOOST_IOSTREAMS_DECL_CHAIN(wchain, wchar_t) -#undef BOOST_IOSTREAMS_DECL_CHAIN - -//--------------Definition of chain_client------------------------------------// - -namespace detail { - -// -// Template name: chain_client -// Description: Class whose instances provide access to an underlying chain -// using an interface similar to the chains. -// Subclasses: the various stream and stream buffer templates. -// -template -class chain_client { -public: - typedef Chain chain_type; - typedef typename chain_type::char_type char_type; - typedef typename chain_type::traits_type traits_type; - typedef typename chain_type::size_type size_type; - typedef typename chain_type::mode mode; - - chain_client(chain_type* chn = 0) : chain_(chn ) { } - chain_client(chain_client* client) : chain_(client->chain_) { } - virtual ~chain_client() { } - - const boost::core::typeinfo& component_type(int n) const - { return chain_->component_type(n); } - - // Deprecated. - template - const boost::core::typeinfo& component_type() const - { return chain_->BOOST_NESTED_TEMPLATE component_type(); } - - template - T* component(int n) const - { return chain_->BOOST_NESTED_TEMPLATE component(n); } - - // Deprecated. - template - T* component() const - { return chain_->BOOST_NESTED_TEMPLATE component(); } - - bool is_complete() const { return chain_->is_complete(); } - bool auto_close() const { return chain_->auto_close(); } - void set_auto_close(bool close) { chain_->set_auto_close(close); } - bool strict_sync() { return chain_->strict_sync(); } - void set_device_buffer_size(std::streamsize n) - { chain_->set_device_buffer_size(n); } - void set_filter_buffer_size(std::streamsize n) - { chain_->set_filter_buffer_size(n); } - void set_pback_size(std::streamsize n) { chain_->set_pback_size(n); } - BOOST_IOSTREAMS_DEFINE_PUSH(push, mode, char_type, push_impl) - void pop() { chain_->pop(); } - bool empty() const { return chain_->empty(); } - size_type size() const { return chain_->size(); } - void reset() { chain_->reset(); } - - // Returns a copy of the underlying chain. - chain_type filters() { return *chain_; } - chain_type filters() const { return *chain_; } -protected: - template - void push_impl(const T& t BOOST_IOSTREAMS_PUSH_PARAMS()) - { chain_->push(t BOOST_IOSTREAMS_PUSH_ARGS()); } - chain_type& ref() { return *chain_; } - void set_chain(chain_type* c) - { chain_ = c; chain_->register_client(this); } -#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && \ - (!BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600)) - template - friend class chain_base; -#else - public: -#endif - virtual void notify() { } -private: - chain_type* chain_; -}; - -//--------------Implementation of chain_base----------------------------------// - -template -inline std::streamsize chain_base::read - (char_type* s, std::streamsize n) -{ return iostreams::read(*list().front(), s, n); } - -template -inline std::streamsize chain_base::write - (const char_type* s, std::streamsize n) -{ return iostreams::write(*list().front(), s, n); } - -template -inline std::streampos chain_base::seek - (stream_offset off, BOOST_IOS::seekdir way) -{ return iostreams::seek(*list().front(), off, way); } - -template -void chain_base::reset() -{ - using namespace std; - pimpl_->close(); - pimpl_->reset(); -} - -template -bool chain_base::is_complete() const -{ - return (pimpl_->flags_ & f_complete) != 0; -} - -template -bool chain_base::auto_close() const -{ - return (pimpl_->flags_ & f_auto_close) != 0; -} - -template -void chain_base::set_auto_close(bool close) -{ - pimpl_->flags_ = - (pimpl_->flags_ & ~f_auto_close) | - (close ? f_auto_close : 0); -} - -template -bool chain_base::strict_sync() -{ - typedef typename list_type::iterator iterator; - bool result = true; - for ( iterator first = list().begin(), - last = list().end(); - first != last; - ++first ) - { - bool s = (*first)->strict_sync(); - result = result && s; - } - return result; -} - -template -void chain_base::pop() -{ - BOOST_ASSERT(!empty()); - if (auto_close()) - pimpl_->close(); - streambuf_type* buf = 0; - std::swap(buf, list().back()); - buf->set_auto_close(false); - buf->set_next(0); - delete buf; - list().pop_back(); - pimpl_->flags_ &= ~f_complete; - if (auto_close() || list().empty()) - pimpl_->flags_ &= ~f_open; -} - -} // End namespace detail. - -} } // End namespaces iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CHAIN_HPP_INCLUDED diff --git a/boost/iostreams/code_converter.hpp b/boost/iostreams/code_converter.hpp deleted file mode 100644 index 0bac461d..00000000 --- a/boost/iostreams/code_converter.hpp +++ /dev/null @@ -1,417 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -// Contains machinery for performing code conversion. - -#ifndef BOOST_IOSTREAMS_CODE_CONVERTER_HPP_INCLUDED -#define BOOST_IOSTREAMS_CODE_CONVERTER_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#if defined(BOOST_IOSTREAMS_NO_WIDE_STREAMS) || \ - defined(BOOST_IOSTREAMS_NO_LOCALE) \ - /**/ -# error code conversion not supported on this platform -#endif - -#include // max. -#include // memcpy. -#include -#include // DEDUCED_TYPENAME, -#include -#include // default_filter_buffer_size. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // failure, openmode, int types, streamsize. -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Must come last. -#include // Borland 5.x - -namespace boost { namespace iostreams { - -struct code_conversion_error : BOOST_IOSTREAMS_FAILURE { - code_conversion_error() - : BOOST_IOSTREAMS_FAILURE("code conversion error") - { } -}; - -namespace detail { - -//--------------Definition of strncpy_if_same---------------------------------// - -// Helper template for strncpy_if_same, below. -template -struct strncpy_if_same_impl; - -template<> -struct strncpy_if_same_impl { - template - static Ch* copy(Ch* tgt, const Ch* src, std::streamsize n) - { return BOOST_IOSTREAMS_CHAR_TRAITS(Ch)::copy(tgt, src, n); } -}; - -template<> -struct strncpy_if_same_impl { - template - static Tgt* copy(Tgt* tgt, const Src*, std::streamsize) { return tgt; } -}; - -template -Tgt* strncpy_if_same(Tgt* tgt, const Src* src, std::streamsize n) -{ - typedef strncpy_if_same_impl::value> impl; - return impl::copy(tgt, src, n); -} - -//--------------Definition of conversion_buffer-------------------------------// - -// Buffer and conversion state for reading. -template -class conversion_buffer - : public buffer< - BOOST_DEDUCED_TYPENAME detail::codecvt_extern::type, - Alloc - > -{ -public: - typedef typename Codecvt::state_type state_type; - conversion_buffer() - : buffer< - BOOST_DEDUCED_TYPENAME detail::codecvt_extern::type, - Alloc - >(0) - { - reset(); - } - state_type& state() { return state_; } - void reset() - { - if (this->size()) - this->set(0, 0); - state_ = state_type(); - } -private: - state_type state_; -}; - -//--------------Definition of converter_impl----------------------------------// - -// Contains member data, open/is_open/close and buffer management functions. -template -struct code_converter_impl { - typedef typename codecvt_extern::type extern_type; - typedef typename category_of::type device_category; - typedef is_convertible can_read; - typedef is_convertible can_write; - typedef is_convertible is_bidir; - typedef typename - iostreams::select< // Disambiguation for Tru64. - is_bidir, bidirectional, - can_read, input, - can_write, output - >::type mode; - typedef typename - mpl::if_< - is_direct, - direct_adapter, - Device - >::type device_type; - typedef optional< concept_adapter > storage_type; - typedef is_convertible is_double; - typedef conversion_buffer buffer_type; - - code_converter_impl() : cvt_(), flags_(0) { } - - ~code_converter_impl() - { - try { - if (flags_ & f_open) close(); - } catch (...) { /* */ } - } - - template - void open(const T& dev, std::streamsize buffer_size) - { - if (flags_ & f_open) - boost::throw_exception(BOOST_IOSTREAMS_FAILURE("already open")); - if (buffer_size == -1) - buffer_size = default_filter_buffer_size; - std::streamsize max_length = cvt_.get().max_length(); - buffer_size = (std::max)(buffer_size, 2 * max_length); - if (can_read::value) { - buf_.first().resize(buffer_size); - buf_.first().set(0, 0); - } - if (can_write::value && !is_double::value) { - buf_.second().resize(buffer_size); - buf_.second().set(0, 0); - } - dev_.reset(concept_adapter(dev)); - flags_ = f_open; - } - - void close() - { - detail::execute_all( - detail::call_member_close(*this, BOOST_IOS::in), - detail::call_member_close(*this, BOOST_IOS::out) - ); - } - - void close(BOOST_IOS::openmode which) - { - if (which == BOOST_IOS::in && (flags_ & f_input_closed) == 0) { - flags_ |= f_input_closed; - iostreams::close(dev(), BOOST_IOS::in); - } - if (which == BOOST_IOS::out && (flags_ & f_output_closed) == 0) { - flags_ |= f_output_closed; - detail::execute_all( - detail::flush_buffer(buf_.second(), dev(), can_write::value), - detail::call_close(dev(), BOOST_IOS::out), - detail::call_reset(dev_), - detail::call_reset(buf_.first()), - detail::call_reset(buf_.second()) - ); - } - } - - bool is_open() const { return (flags_ & f_open) != 0;} - - device_type& dev() { return **dev_; } - - enum flag_type { - f_open = 1, - f_input_closed = f_open << 1, - f_output_closed = f_input_closed << 1 - }; - - codecvt_holder cvt_; - storage_type dev_; - double_object< - buffer_type, - is_double - > buf_; - int flags_; -}; - -} // End namespace detail. - -//--------------Definition of converter---------------------------------------// - -#define BOOST_IOSTREAMS_CONVERTER_PARAMS() , std::streamsize buffer_size = -1 -#define BOOST_IOSTREAMS_CONVERTER_ARGS() , buffer_size - -template -struct code_converter_base { - typedef detail::code_converter_impl< - Device, Codecvt, Alloc - > impl_type; - code_converter_base() : pimpl_(new impl_type) { } - shared_ptr pimpl_; -}; - -template< typename Device, - typename Codecvt = detail::default_codecvt, - typename Alloc = std::allocator > -class code_converter - : protected code_converter_base -{ -private: - typedef detail::code_converter_impl< - Device, Codecvt, Alloc - > impl_type; - typedef typename impl_type::device_type device_type; - typedef typename impl_type::buffer_type buffer_type; - typedef typename detail::codecvt_holder::codecvt_type codecvt_type; - typedef typename detail::codecvt_intern::type intern_type; - typedef typename detail::codecvt_extern::type extern_type; - typedef typename detail::codecvt_state::type state_type; -public: - typedef intern_type char_type; - struct category - : impl_type::mode, device_tag, closable_tag, localizable_tag - { }; - BOOST_STATIC_ASSERT(( - is_same< - extern_type, - BOOST_DEDUCED_TYPENAME char_type_of::type - >::value - )); -public: - code_converter() { } - BOOST_IOSTREAMS_FORWARD( code_converter, open_impl, Device, - BOOST_IOSTREAMS_CONVERTER_PARAMS, - BOOST_IOSTREAMS_CONVERTER_ARGS ) - - // fstream-like interface. - - bool is_open() const { return this->pimpl_->is_open(); } - void close(BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out ) - { impl().close(which); } - - // Device interface. - - std::streamsize read(char_type*, std::streamsize); - std::streamsize write(const char_type*, std::streamsize); - void imbue(const std::locale& loc) { impl().cvt_.imbue(loc); } - - // Direct device access. - - Device& operator*() { return detail::unwrap_direct(dev()); } - Device* operator->() { return &detail::unwrap_direct(dev()); } -private: - template // Used for forwarding. - void open_impl(const T& t BOOST_IOSTREAMS_CONVERTER_PARAMS()) - { - impl().open(t BOOST_IOSTREAMS_CONVERTER_ARGS()); - } - - const codecvt_type& cvt() { return impl().cvt_.get(); } - device_type& dev() { return impl().dev(); } - buffer_type& in() { return impl().buf_.first(); } - buffer_type& out() { return impl().buf_.second(); } - impl_type& impl() { return *this->pimpl_; } -}; - -//--------------Implementation of converter-----------------------------------// - -// Implementation note: if end of stream contains a partial character, -// it is ignored. -template -std::streamsize code_converter::read - (char_type* s, std::streamsize n) -{ - const extern_type* next; // Next external char. - intern_type* nint; // Next internal char. - std::streamsize total = 0; // Characters read. - int status = iostreams::char_traits::good(); - bool partial = false; - buffer_type& buf = in(); - - do { - - // Fill buffer. - if (buf.ptr() == buf.eptr() || partial) { - status = buf.fill(dev()); - if (buf.ptr() == buf.eptr()) - break; - partial = false; - } - - // Convert. - std::codecvt_base::result result = - cvt().in( buf.state(), - buf.ptr(), buf.eptr(), next, - s + total, s + n, nint ); - buf.ptr() += next - buf.ptr(); - total = static_cast(nint - s); - - switch (result) { - case std::codecvt_base::partial: - partial = true; - break; - case std::codecvt_base::ok: - break; - case std::codecvt_base::noconv: - { - std::streamsize amt = - std::min(next - buf.ptr(), n - total); - detail::strncpy_if_same(s + total, buf.ptr(), amt); - total += amt; - } - break; - case std::codecvt_base::error: - default: - buf.state() = state_type(); - boost::throw_exception(code_conversion_error()); - } - - } while (total < n && status != EOF && status != WOULD_BLOCK); - - return total == 0 && status == EOF ? -1 : total; -} - -template -std::streamsize code_converter::write - (const char_type* s, std::streamsize n) -{ - buffer_type& buf = out(); - extern_type* next; // Next external char. - const intern_type* nint; // Next internal char. - std::streamsize total = 0; // Characters written. - bool partial = false; - - while (total < n) { - - // Empty buffer. - if (buf.eptr() == buf.end() || partial) { - if (!buf.flush(dev())) - break; - partial = false; - } - - // Convert. - std::codecvt_base::result result = - cvt().out( buf.state(), - s + total, s + n, nint, - buf.eptr(), buf.end(), next ); - int progress = (int) (next - buf.eptr()); - buf.eptr() += progress; - - switch (result) { - case std::codecvt_base::partial: - partial = true; - BOOST_FALLTHROUGH; - case std::codecvt_base::ok: - total = static_cast(nint - s); - break; - case std::codecvt_base::noconv: - { - std::streamsize amt = - std::min( nint - total - s, - buf.end() - buf.eptr() ); - detail::strncpy_if_same(buf.eptr(), s + total, amt); - total += amt; - } - break; - case std::codecvt_base::error: - default: - buf.state() = state_type(); - boost::throw_exception(code_conversion_error()); - } - } - return total; -} - -//----------------------------------------------------------------------------// - -} } // End namespaces iostreams, boost. - -#include // Borland 5.x - -#endif // #ifndef BOOST_IOSTREAMS_CODE_CONVERTER_HPP_INCLUDED diff --git a/boost/iostreams/combine.hpp b/boost/iostreams/combine.hpp deleted file mode 100644 index 107122a9..00000000 --- a/boost/iostreams/combine.hpp +++ /dev/null @@ -1,260 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -// To do: add support for random-access. - -#ifndef BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED -#define BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // NO_STD_LOCALE, DEDUCED_TYPENAME. -#ifndef BOOST_NO_STD_LOCALE -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -// Must come last. -#include - -namespace boost { namespace iostreams { - -namespace detail { - -// -// Template name: combined_device. -// Description: Model of Device defined in terms of a Source/Sink pair. -// Template parameters: -// Source - A model of Source, with the same char_type and traits_type -// as Sink. -// Sink - A model of Sink, with the same char_type and traits_type -// as Source. -// -template -class combined_device { -private: - typedef typename category_of::type in_category; - typedef typename category_of::type out_category; - typedef typename char_type_of::type sink_char_type; -public: - typedef typename char_type_of::type char_type; - struct category - : bidirectional, - device_tag, - closable_tag, - localizable_tag - { }; - BOOST_STATIC_ASSERT(is_device::value); - BOOST_STATIC_ASSERT(is_device::value); - BOOST_STATIC_ASSERT((is_convertible::value)); - BOOST_STATIC_ASSERT((is_convertible::value)); - BOOST_STATIC_ASSERT((is_same::value)); - combined_device(const Source& src, const Sink& snk); - std::streamsize read(char_type* s, std::streamsize n); - std::streamsize write(const char_type* s, std::streamsize n); - void close(BOOST_IOS::openmode); - #ifndef BOOST_NO_STD_LOCALE - void imbue(const std::locale& loc); - #endif -private: - Source src_; - Sink sink_; -}; - -// -// Template name: combined_filter. -// Description: Model of Device defined in terms of a Source/Sink pair. -// Template parameters: -// InputFilter - A model of InputFilter, with the same char_type as -// OutputFilter. -// OutputFilter - A model of OutputFilter, with the same char_type as -// InputFilter. -// -template -class combined_filter { -private: - typedef typename category_of::type in_category; - typedef typename category_of::type out_category; - typedef typename char_type_of::type output_char_type; -public: - typedef typename char_type_of::type char_type; - struct category - : multichar_bidirectional_filter_tag, - closable_tag, - localizable_tag - { }; - BOOST_STATIC_ASSERT(is_filter::value); - BOOST_STATIC_ASSERT(is_filter::value); - BOOST_STATIC_ASSERT((is_convertible::value)); - BOOST_STATIC_ASSERT((is_convertible::value)); - BOOST_STATIC_ASSERT((is_same::value)); - combined_filter(const InputFilter& in, const OutputFilter& out); - - template - std::streamsize read(Source& src, char_type* s, std::streamsize n) - { return boost::iostreams::read(in_, src, s, n); } - - template - std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) - { return boost::iostreams::write(out_, snk, s, n); } - - template - void close(Sink& snk, BOOST_IOS::openmode which) - { - if (which == BOOST_IOS::in) { - if (is_convertible::value) { - iostreams::close(in_, snk, BOOST_IOS::in); - } else { - detail::close_all(in_, snk); - } - } - if (which == BOOST_IOS::out) { - if (is_convertible::value) { - iostreams::close(out_, snk, BOOST_IOS::out); - } else { - detail::close_all(out_, snk); - } - } - } - #ifndef BOOST_NO_STD_LOCALE - void imbue(const std::locale& loc); - #endif -private: - InputFilter in_; - OutputFilter out_; -}; - -template -struct combination_traits - : mpl::if_< - is_device, - combined_device< - typename wrapped_type::type, - typename wrapped_type::type - >, - combined_filter< - typename wrapped_type::type, - typename wrapped_type::type - > - > - { }; - -} // End namespace detail. - -template -struct combination : detail::combination_traits::type { - typedef typename detail::combination_traits::type base_type; - typedef typename detail::wrapped_type::type in_type; - typedef typename detail::wrapped_type::type out_type; - combination(const in_type& in, const out_type& out) - : base_type(in, out) { } -}; - -namespace detail { - -// Workaround for VC6 ETI bug. -template -struct combine_traits { - typedef combination< - BOOST_DEDUCED_TYPENAME detail::unwrapped_type::type, - BOOST_DEDUCED_TYPENAME detail::unwrapped_type::type - > type; -}; - -} // End namespace detail. - -// -// Template name: combine. -// Description: Takes a Source/Sink pair or InputFilter/OutputFilter pair and -// returns a Source or Filter which performs input using the first member -// of the pair and output using the second member of the pair. -// Template parameters: -// In - A model of Source or InputFilter, with the same char_type as Out. -// Out - A model of Sink or OutputFilter, with the same char_type as In. -// -template -typename detail::combine_traits::type -combine(const In& in, const Out& out) -{ - typedef typename detail::combine_traits::type return_type; - return return_type(in, out); -} - -//----------------------------------------------------------------------------// - -namespace detail { - -//--------------Implementation of combined_device-----------------------------// - -template -inline combined_device::combined_device - (const Source& src, const Sink& snk) - : src_(src), sink_(snk) { } - -template -inline std::streamsize -combined_device::read(char_type* s, std::streamsize n) -{ return iostreams::read(src_, s, n); } - -template -inline std::streamsize -combined_device::write(const char_type* s, std::streamsize n) -{ return iostreams::write(sink_, s, n); } - -template -inline void -combined_device::close(BOOST_IOS::openmode which) -{ - if (which == BOOST_IOS::in) - detail::close_all(src_); - if (which == BOOST_IOS::out) - detail::close_all(sink_); -} - -#ifndef BOOST_NO_STD_LOCALE - template - void combined_device::imbue(const std::locale& loc) - { - iostreams::imbue(src_, loc); - iostreams::imbue(sink_, loc); - } -#endif - -//--------------Implementation of filter_pair---------------------------------// - -template -inline combined_filter::combined_filter - (const InputFilter& in, const OutputFilter& out) : in_(in), out_(out) - { } - -#ifndef BOOST_NO_STD_LOCALE - template - void combined_filter::imbue - (const std::locale& loc) - { - iostreams::imbue(in_, loc); - iostreams::imbue(out_, loc); - } -#endif - - -} // End namespace detail. - -} } // End namespaces iostreams, boost. - -#include - -#endif // #ifndef BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED diff --git a/boost/iostreams/compose.hpp b/boost/iostreams/compose.hpp deleted file mode 100644 index fe9ae289..00000000 --- a/boost/iostreams/compose.hpp +++ /dev/null @@ -1,493 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2005-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -// Note: bidirectional streams are not supported. - -#ifndef BOOST_IOSTREAMS_COMPOSE_HPP_INCLUDED -#define BOOST_IOSTREAMS_COMPOSE_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // min. -#include // pair. -#include // DEDUCED_TYPENAME. -#include -#include -#include -#include -#include -#include -#include -#include // mode_of, is_direct. -#include -#include -#include -#include - -// Must come last. -#include // MSVC. - -namespace boost { namespace iostreams { - -namespace detail { - -template< typename First, - typename Second, - typename FirstMode = - BOOST_DEDUCED_TYPENAME mode_of::type, - typename SecondMode = - BOOST_DEDUCED_TYPENAME mode_of::type > -struct composite_mode - : select< - is_convertible, FirstMode, - is_convertible, SecondMode, - is_convertible, input, - else_, output - > - { }; - -// -// Template name: composite_device. -// Description: Provides a Device view of a Filter, Device pair. -// Template parameters: -// Filter - A model of Filter. -// Device - An indirect model of Device. -// -template< typename Filter, - typename Device, - typename Mode = - BOOST_DEDUCED_TYPENAME composite_mode::type > -class composite_device { -private: - typedef typename detail::param_type::type param_type; - typedef typename mode_of::type filter_mode; - typedef typename mode_of::type device_mode; - typedef typename - iostreams::select< // Disambiguation for Tru64. - is_direct, direct_adapter, - is_std_io, Device&, - else_, Device - >::type value_type; - BOOST_STATIC_ASSERT(is_filter::value); - BOOST_STATIC_ASSERT(is_device::value); -public: - typedef typename char_type_of::type char_type; - struct category - : Mode, - device_tag, - closable_tag, - flushable_tag, - localizable_tag, - optimally_buffered_tag - { }; - composite_device(const Filter& flt, param_type dev); - std::streamsize read(char_type* s, std::streamsize n); - std::streamsize write(const char_type* s, std::streamsize n); - std::streampos seek( stream_offset off, BOOST_IOS::seekdir way, - BOOST_IOS::openmode which = - BOOST_IOS::in | BOOST_IOS::out ); - - void close(); - void close(BOOST_IOS::openmode which); - bool flush(); - std::streamsize optimal_buffer_size() const; - - template // Avoid dependency on - void imbue(const Locale& loc) - { - iostreams::imbue(filter_, loc); - iostreams::imbue(device_, loc); - } - - Filter& first() { return filter_; } - Device& second() { return device_; } -private: - Filter filter_; - value_type device_; -}; - -// -// Template name: composite_device. -// Description: Provides a Device view of a Filter, Device pair. -// Template parameters: -// Filter - A model of Filter. -// Device - An indirect model of Device. -// -template< typename Filter1, - typename Filter2, - typename Mode = - BOOST_DEDUCED_TYPENAME composite_mode::type > -class composite_filter { -private: - typedef reference_wrapper filter_ref; - typedef typename mode_of::type first_mode; - typedef typename mode_of::type second_mode; - - // A dual-use filter cannot be composed with a read-write filter - BOOST_STATIC_ASSERT( - !(is_convertible::value) || - !(is_convertible::value) || - !(is_convertible::value) || - (is_convertible::value) - ); - BOOST_STATIC_ASSERT( - !(is_convertible::value) || - !(is_convertible::value) || - !(is_convertible::value) || - (is_convertible::value) - ); - BOOST_STATIC_ASSERT(is_filter::value); - BOOST_STATIC_ASSERT(is_filter::value); -public: - typedef typename char_type_of::type char_type; - struct category - : Mode, - filter_tag, - multichar_tag, - closable_tag, - flushable_tag, - localizable_tag, - optimally_buffered_tag - { }; - composite_filter(const Filter1& filter1, const Filter2& filter2) - : filter1_(filter1), filter2_(filter2) - { } - - template - std::streamsize read(Source& src, char_type* s, std::streamsize n) - { - composite_device cmp(boost::ref(filter2_), src); - return iostreams::read(filter1_, cmp, s, n); - } - - template - std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) - { - composite_device cmp(boost::ref(filter2_), snk); - return iostreams::write(filter1_, cmp, s, n); - } - - template - std::streampos seek( Device& dev, stream_offset off, BOOST_IOS::seekdir way, - BOOST_IOS::openmode which = - BOOST_IOS::in | BOOST_IOS::out ) - { - composite_device cmp(boost::ref(filter2_), dev); - return iostreams::seek(filter1_, cmp, off, way, which); - } - - template - void close(Device& dev) - { - BOOST_STATIC_ASSERT((!is_convertible::value)); - BOOST_STATIC_ASSERT((!is_convertible::value)); - - // Create a new device by composing the second filter2_ with dev. - composite_device cmp(boost::ref(filter2_), dev); - - // Close input sequences in reverse order and output sequences in - // forward order - if (!is_convertible::value) { - detail::execute_all( - detail::call_close(filter2_, dev, BOOST_IOS::in), - detail::call_close(filter1_, cmp, BOOST_IOS::in), - detail::call_close(filter1_, cmp, BOOST_IOS::out), - detail::call_close(filter2_, dev, BOOST_IOS::out) - ); - } else if (is_convertible::value) { - detail::execute_all( - detail::call_close(filter2_, dev, BOOST_IOS::in), - detail::call_close(filter1_, cmp, BOOST_IOS::in) - ); - } else { - detail::execute_all( - detail::call_close(filter1_, cmp, BOOST_IOS::out), - detail::call_close(filter2_, dev, BOOST_IOS::out) - ); - } - } - - template - void close(Device& dev, BOOST_IOS::openmode which) - { - BOOST_STATIC_ASSERT( - (is_convertible::value) || - (is_convertible::value) - ); - - // Create a new device by composing the second filter2_ with dev. - composite_device cmp(boost::ref(filter2_), dev); - - // Close input sequences in reverse order - if ( which == BOOST_IOS::in && - ( !is_convertible::value || - is_convertible::value ) ) - { - detail::execute_all( - detail::call_close(filter2_, dev, BOOST_IOS::in), - detail::call_close(filter1_, cmp, BOOST_IOS::in) - ); - } - - // Close output sequences in forward order - if ( which == BOOST_IOS::out && - ( !is_convertible::value || - is_convertible::value ) ) - { - detail::execute_all( - detail::call_close(filter1_, cmp, BOOST_IOS::out), - detail::call_close(filter2_, dev, BOOST_IOS::out) - ); - } - } - - template - bool flush(Device& dev) - { - composite_device cmp(filter2_, dev); - return iostreams::flush(filter1_, cmp); - } - - std::streamsize optimal_buffer_size() const - { - std::streamsize first = iostreams::optimal_buffer_size(filter1_); - std::streamsize second = iostreams::optimal_buffer_size(filter2_); - return first < second ? second : first; - } - - template // Avoid dependency on - void imbue(const Locale& loc) - { // To do: consider using RAII. - iostreams::imbue(filter1_, loc); - iostreams::imbue(filter2_, loc); - } - - Filter1& first() { return filter1_; } - Filter2& second() { return filter2_; } -private: - Filter1 filter1_; - Filter2 filter2_; -}; - -template -struct composite_traits - : mpl::if_< - is_device, - composite_device, - composite_filter - > - { }; - -} // End namespace detail. - -template -struct composite : detail::composite_traits::type { - typedef typename detail::param_type::type param_type; - typedef typename detail::composite_traits::type base; - composite(const Filter& flt, param_type dev) - : base(flt, dev) - { } -}; - -//--------------Implementation of compose-------------------------------------// - -// Note: The following workarounds are patterned after resolve.hpp. It has not -// yet been confirmed that they are necessary. - -#ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //-------------------------// -# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------// - -template -composite -compose( const Filter& filter, const FilterOrDevice& fod - BOOST_IOSTREAMS_DISABLE_IF_STREAM(FilterOrDevice) ) -{ return composite(filter, fod); } - -template -composite< Filter, std::basic_streambuf > -compose(const Filter& filter, std::basic_streambuf& sb) -{ return composite< Filter, std::basic_streambuf >(filter, sb); } - -template -composite< Filter, std::basic_istream > -compose(const Filter& filter, std::basic_istream& is) -{ return composite< Filter, std::basic_istream >(filter, is); } - -template -composite< Filter, std::basic_ostream > -compose(const Filter& filter, std::basic_ostream& os) -{ return composite< Filter, std::basic_ostream >(filter, os); } - -template -composite< Filter, std::basic_iostream > -compose(const Filter& filter, std::basic_iostream& io) -{ return composite< Filter, std::basic_iostream >(filter, io); } - -# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------// - -template -composite -compose( const Filter& filter, const FilterOrDevice& fod - BOOST_IOSTREAMS_DISABLE_IF_STREAM(FilterOrDevice) ) -{ return composite(filter, fod); } - -template -composite -compose(const Filter& filter, std::streambuf& sb) -{ return composite(filter, sb); } - -template -composite -compose(const Filter& filter, std::istream& is) -{ return composite(filter, is); } - -template -composite -compose(const Filter& filter, std::ostream& os) -{ return composite(filter, os); } - -template -composite -compose(const Filter& filter, std::iostream& io) -{ return composite(filter, io); } - -# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------// -#else // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //----------------// - -template -composite -compose(const Filter& flt, const Stream& strm, mpl::true_) -{ // Bad overload resolution. - return composite(flt, const_cast(strm)); -} - -template -composite -compose(const Filter& flt, const FilterOrDevice& fod, mpl::false_) -{ return composite(flt, fod); } - -template -composite -compose( const Filter& flt, const FilterOrDevice& fod - BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) ) -{ return compose(flt, fod, is_std_io()); } - -# if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) && \ - !defined(__GNUC__) // ---------------------------------------------------// - -template -composite -compose (const Filter& filter, FilterOrDevice& fod) -{ return composite(filter, fod); } - -# endif // Borland 5.x or GCC //--------------------------------// -#endif // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------// - -//----------------------------------------------------------------------------// - -namespace detail { - -//--------------Implementation of composite_device---------------------------// - -template -composite_device::composite_device - (const Filter& flt, param_type dev) - : filter_(flt), device_(dev) - { } - -template -inline std::streamsize composite_device::read - (char_type* s, std::streamsize n) -{ return iostreams::read(filter_, device_, s, n); } - -template -inline std::streamsize composite_device::write - (const char_type* s, std::streamsize n) -{ return iostreams::write(filter_, device_, s, n); } - -template -std::streampos composite_device::seek - (stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) -{ return iostreams::seek(filter_, device_, off, way, which); } - -template -void composite_device::close() -{ - BOOST_STATIC_ASSERT((!is_convertible::value)); - BOOST_STATIC_ASSERT( - !(is_convertible::value) || - !(is_convertible::value) || - !(is_convertible::value) - ); - - // Close input sequences in reverse order and output sequences - // in forward order - if (!is_convertible::value) { - detail::execute_all( - detail::call_close(device_, BOOST_IOS::in), - detail::call_close(filter_, device_, BOOST_IOS::in), - detail::call_close(filter_, device_, BOOST_IOS::out), - detail::call_close(device_, BOOST_IOS::out) - ); - } else if (is_convertible::value) { - detail::execute_all( - detail::call_close(device_, BOOST_IOS::in), - detail::call_close(filter_, device_, BOOST_IOS::in) - ); - } else { - detail::execute_all( - detail::call_close(filter_, device_, BOOST_IOS::out), - detail::call_close(device_, BOOST_IOS::out) - ); - } -} - -template -void composite_device::close(BOOST_IOS::openmode which) -{ - BOOST_STATIC_ASSERT((is_convertible::value)); - BOOST_STATIC_ASSERT(!(is_convertible::value)); - - // Close input sequences in reverse order - if (which == BOOST_IOS::in) { - detail::execute_all( - detail::call_close(device_, BOOST_IOS::in), - detail::call_close(filter_, device_, BOOST_IOS::in) - ); - } - - // Close output sequences in forward order - if (which == BOOST_IOS::out) { - detail::execute_all( - detail::call_close(filter_, device_, BOOST_IOS::out), - detail::call_close(device_, BOOST_IOS::out) - ); - } -} - -template -bool composite_device::flush() -{ - bool r1 = iostreams::flush(filter_, device_); - bool r2 = iostreams::flush(device_); - return r1 && r2; -} - -template -std::streamsize -composite_device::optimal_buffer_size() const -{ return iostreams::optimal_buffer_size(device_); } - -} // End namespace detail. - -} } // End namespaces iostreams, boost. - -#include - -#endif // #ifndef BOOST_IOSTREAMS_COMPOSE_HPP_INCLUDED diff --git a/boost/iostreams/copy.hpp b/boost/iostreams/copy.hpp deleted file mode 100644 index 3579a9cd..00000000 --- a/boost/iostreams/copy.hpp +++ /dev/null @@ -1,248 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -// Contains: The function template copy, which reads data from a Source -// and writes it to a Sink until the end of the sequence is reached, returning -// the number of characters transfered. - -// The implementation is complicated by the need to handle smart adapters -// and direct devices. - -#ifndef BOOST_IOSTREAMS_COPY_HPP_INCLUDED -#define BOOST_IOSTREAMS_COPY_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // Make sure ptrdiff_t is in std. -#include // copy, min. -#include // ptrdiff_t. -#include // pair. - -#include -#include -#include -#include -#include -#include -#include -#include -#include // failure, streamsize. -#include -#include -#include // read, write, close. -#include -#include -#include - -namespace boost { namespace iostreams { - -namespace detail { - - // The following four overloads of copy_impl() optimize - // copying in the case that one or both of the two devices - // models Direct (see - // http://www.boost.org/libs/iostreams/doc/index.html?path=4.1.1.4) - -// Copy from a direct source to a direct sink -template -std::streamsize copy_impl( Source& src, Sink& snk, - std::streamsize /* buffer_size */, - mpl::true_, mpl::true_ ) -{ - using namespace std; - typedef typename char_type_of::type char_type; - typedef std::pair pair_type; - pair_type p1 = iostreams::input_sequence(src); - pair_type p2 = iostreams::output_sequence(snk); - std::streamsize total = - static_cast( - (std::min)(p1.second - p1.first, p2.second - p2.first) - ); - std::copy(p1.first, p1.first + total, p2.first); - return total; -} - -// Copy from a direct source to an indirect sink -template -std::streamsize copy_impl( Source& src, Sink& snk, - std::streamsize /* buffer_size */, - mpl::true_, mpl::false_ ) -{ - using namespace std; - typedef typename char_type_of::type char_type; - typedef std::pair pair_type; - pair_type p = iostreams::input_sequence(src); - std::streamsize size, total; - for ( total = 0, size = static_cast(p.second - p.first); - total < size; ) - { - std::streamsize amt = - iostreams::write(snk, p.first + total, size - total); - total += amt; - } - return total; -} - -// Copy from an indirect source to a direct sink -template -std::streamsize copy_impl( Source& src, Sink& snk, - std::streamsize buffer_size, - mpl::false_, mpl::true_ ) -{ - typedef typename char_type_of::type char_type; - typedef std::pair pair_type; - detail::basic_buffer buf(buffer_size); - pair_type p = snk.output_sequence(); - std::streamsize total = 0; - std::ptrdiff_t capacity = p.second - p.first; - while (true) { - std::streamsize amt = - iostreams::read( - src, - buf.data(), - buffer_size < capacity - total ? - buffer_size : - static_cast(capacity - total) - ); - if (amt == -1) - break; - std::copy(buf.data(), buf.data() + amt, p.first + total); - total += amt; - } - return total; -} - -// Copy from an indirect source to an indirect sink -template -std::streamsize copy_impl( Source& src, Sink& snk, - std::streamsize buffer_size, - mpl::false_, mpl::false_ ) -{ - typedef typename char_type_of::type char_type; - detail::basic_buffer buf(buffer_size); - non_blocking_adapter nb(snk); - std::streamsize total = 0; - bool done = false; - while (!done) { - std::streamsize amt; - done = (amt = iostreams::read(src, buf.data(), buffer_size)) == -1; - if (amt != -1) { - iostreams::write(nb, buf.data(), amt); - total += amt; - } - } - return total; -} - - // The following function object is used with - // boost::iostreams::detail::execute() in the primary - // overload of copy_impl(), below - -// Function object that delegates to one of the above four -// overloads of compl_impl() -template -class copy_operation { -public: - typedef std::streamsize result_type; - copy_operation(Source& src, Sink& snk, std::streamsize buffer_size) - : src_(src), snk_(snk), buffer_size_(buffer_size) - { } - std::streamsize operator()() - { - return copy_impl( src_, snk_, buffer_size_, - is_direct(), is_direct() ); - } -private: - copy_operation& operator=(const copy_operation&); - Source& src_; - Sink& snk_; - std::streamsize buffer_size_; -}; - -// Primary overload of copy_impl. Delegates to one of the above four -// overloads of compl_impl(), depending on which of the two given -// devices, if any, models Direct (see -// http://www.boost.org/libs/iostreams/doc/index.html?path=4.1.1.4) -template -std::streamsize copy_impl(Source src, Sink snk, std::streamsize buffer_size) -{ - using namespace std; - typedef typename char_type_of::type src_char; - typedef typename char_type_of::type snk_char; - BOOST_STATIC_ASSERT((is_same::value)); - return detail::execute_all( - copy_operation(src, snk, buffer_size), - detail::call_close_all(src), - detail::call_close_all(snk) - ); -} - -} // End namespace detail. - -//------------------Definition of copy----------------------------------------// - -// Overload of copy() for the case where neither the source nor the sink is -// a standard stream or stream buffer -template -std::streamsize -copy( const Source& src, const Sink& snk, - std::streamsize buffer_size = default_device_buffer_size - BOOST_IOSTREAMS_DISABLE_IF_STREAM(Source) - BOOST_IOSTREAMS_DISABLE_IF_STREAM(Sink) ) -{ - typedef typename char_type_of::type char_type; - return detail::copy_impl( detail::resolve(src), - detail::resolve(snk), - buffer_size ); -} - -// Overload of copy() for the case where the source, but not the sink, is -// a standard stream or stream buffer -template -std::streamsize -copy( Source& src, const Sink& snk, - std::streamsize buffer_size = default_device_buffer_size - BOOST_IOSTREAMS_ENABLE_IF_STREAM(Source) - BOOST_IOSTREAMS_DISABLE_IF_STREAM(Sink) ) -{ - typedef typename char_type_of::type char_type; - return detail::copy_impl( detail::wrap(src), - detail::resolve(snk), - buffer_size ); -} - -// Overload of copy() for the case where the sink, but not the source, is -// a standard stream or stream buffer -template -std::streamsize -copy( const Source& src, Sink& snk, - std::streamsize buffer_size = default_device_buffer_size - BOOST_IOSTREAMS_DISABLE_IF_STREAM(Source) - BOOST_IOSTREAMS_ENABLE_IF_STREAM(Sink) ) -{ - typedef typename char_type_of::type char_type; - return detail::copy_impl( detail::resolve(src), - detail::wrap(snk), buffer_size ); -} - -// Overload of copy() for the case where neither the source nor the sink is -// a standard stream or stream buffer -template -std::streamsize -copy( Source& src, Sink& snk, - std::streamsize buffer_size = default_device_buffer_size - BOOST_IOSTREAMS_ENABLE_IF_STREAM(Source) - BOOST_IOSTREAMS_ENABLE_IF_STREAM(Sink) ) -{ - return detail::copy_impl(detail::wrap(src), detail::wrap(snk), buffer_size); -} - -} } // End namespaces iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_COPY_HPP_INCLUDED diff --git a/boost/iostreams/detail/absolute_path.hpp b/boost/iostreams/detail/absolute_path.hpp deleted file mode 100644 index 090958a9..00000000 --- a/boost/iostreams/detail/absolute_path.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - - * File: boost/iostreams/detail/execute.hpp - * Date: Thu Dec 06 13:21:54 MST 2007 - * Copyright: 2007-2008 CodeRage, LLC - * Author: Jonathan Turkanis - * Contact: turkanis at coderage dot com - * - * Defines the function boost::iostreams::detail::absolute_path, used for - * debug output for mapped files. - */ - -#ifndef BOOST_IOSTREAMS_DETAIL_ABSOLUTE_PATH_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_ABSOLUTE_PATH_HPP_INCLUDED - -#include -#include -#ifdef BOOST_IOSTREAMS_WINDOWS -# include -#endif -#include - -namespace boost { namespace iostreams { namespace detail { - -// Resolves the given path relative to the current working directory -inline std::string absolute_path(const std::string& path) -{ -#ifdef BOOST_IOSTREAMS_WINDOWS - return path.size() && (path[0] == '/' || path[0] == '\\') || - path.size() > 1 && std::isalpha(path[0]) && path[1] == ':' ? - path : - current_directory() + '\\' + path; -#else // #ifdef BOOST_IOSTREAMS_WINDOWS - return path.size() && (path[0] == '/') ? - path : - current_directory() + '/' + path; -#endif // #ifdef BOOST_IOSTREAMS_WINDOWS -} - -} } } // End namespaces detail, iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_ABSOLUTE_PATH_HPP_INCLUDED diff --git a/boost/iostreams/detail/access_control.hpp b/boost/iostreams/detail/access_control.hpp deleted file mode 100644 index 9c3328a2..00000000 --- a/boost/iostreams/detail/access_control.hpp +++ /dev/null @@ -1,87 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -// Contains the definition of the class template access_control, which -// allows the type of inheritance from a provided base class to be specified -// using a template parameter. - - -#ifndef BOOST_IOSTREAMS_ACCESS_CONTROL_HPP_INCLUDED -#define BOOST_IOSTREAMS_ACCESS_CONTROL_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#include -#include - -namespace boost { namespace iostreams { - -struct protected_ { }; // Represents protected inheritance. -struct public_ { }; // Represents public inheritance. - - -namespace detail { - - // Implements protected inheritance. - template - struct prot_ : protected U - { - prot_() { } - template prot_(V v) : U(v) { } - }; - - // Implements public inheritance. - template struct pub_ : public U { - pub_() { } - template pub_(V v) : U(v) { } - }; - -// -// Used to deduce the base type for the template access_control. -// -template -struct access_control_base { - typedef int bad_access_specifier; - typedef typename - iostreams::select< // Disambiguation for Tru64 - ::boost::is_same< - Access, protected_ - >, prot_, - ::boost::is_same< - Access, public_ - >, pub_, - else_, bad_access_specifier - >::type type; -}; - -} // End namespace detail. - -// -// Template name: access_control. -// Description: Allows the type of inheritance from a provided base class -// to be specified using an int template parameter. -// Template parameters: -// Base - The class from which to inherit (indirectly.) -// Access - The type of access desired. Must be one of the -// values access_base::prot or access_base::pub. -// -template< typename T, typename Access, - typename Base = // VC6 workaraound (Compiler Error C2516) - typename detail::access_control_base::type > -struct access_control : public Base { - access_control() { } - template explicit access_control(U u) : Base(u) { } -}; - -//----------------------------------------------------------------------------// - -} } // End namespaces iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_ACCESS_CONTROL_HPP_INCLUDED diff --git a/boost/iostreams/detail/adapter/device_adapter.hpp b/boost/iostreams/detail/adapter/device_adapter.hpp deleted file mode 100644 index 9dd723a0..00000000 --- a/boost/iostreams/detail/adapter/device_adapter.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Defines the class template boost::iostreams::detail::device_adapter, - * a convenience base class for device adapters. - * - * File: boost/iostreams/detail/adapter/filter_adapter.hpp - * Date: Mon Nov 26 14:35:48 MST 2007 - * - * Copyright: 2007-2008 CodeRage, LLC - * Author: Jonathan Turkanis - * Contact: turkanis at coderage dot com - * - * Distributed under the Boost Software License, Version 1.0.(See accompanying - * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) - * - * See http://www.boost.org/libs/iostreams for documentation. - */ - -#ifndef BOOST_IOSTREAMS_DETAIL_DEVICE_ADAPTER_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_DEVICE_ADAPTER_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include - -namespace boost { namespace iostreams { namespace detail { - -template -class device_adapter { -private: - typedef typename detail::value_type::type value_type; - typedef typename detail::param_type::type param_type; -public: - explicit device_adapter(param_type t) : t_(t) { } - T& component() { return t_; } - - void close() - { - detail::close_all(t_); - } - - void close(BOOST_IOS::openmode which) - { - iostreams::close(t_, which); - } - - bool flush() - { - return iostreams::flush(t_); - } - - template // Avoid dependency on - void imbue(const Locale& loc) { iostreams::imbue(t_, loc); } - - std::streamsize optimal_buffer_size() const - { return iostreams::optimal_buffer_size(t_); } -public: - value_type t_; -}; - -//----------------------------------------------------------------------------// - -} } } // End namespaces detail, iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DEVICE_ADAPTER_HPP_INCLUDED diff --git a/boost/iostreams/detail/adapter/direct_adapter.hpp b/boost/iostreams/detail/adapter/direct_adapter.hpp deleted file mode 100644 index 60fe8c27..00000000 --- a/boost/iostreams/detail/adapter/direct_adapter.hpp +++ /dev/null @@ -1,282 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_DETAIL_DIRECT_ADAPTER_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_DIRECT_ADAPTER_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // SFINAE, MSVC, put ptrdiff_t in std. -#include // copy, min. -#include // ptrdiff_t. -#include -#include -#include // forwarding. -#include // locale. -#include -#include -#include // openmode, seekdir, int types. -#include // mode_of, is_direct. -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Must come last. -#include // VC7.1 - -namespace boost { namespace iostreams { namespace detail { - -//------------------Definition of direct_adapter_base-------------------------// - -// Put all initialization in base class to faciliate forwarding. -template -class direct_adapter_base { -public: - typedef typename char_type_of::type char_type; - typedef typename mode_of::type mode_type; - struct category - : mode_type, - device_tag, - closable_tag - #ifndef BOOST_IOSTREAMS_NO_LOCALE - , localizable_tag - #endif - { }; -protected: - explicit direct_adapter_base(const Direct& d); - typedef is_convertible is_double; - struct pointers { - pointers() : beg(0), ptr(0), end(0) { } - char_type *beg, *ptr, *end; - }; - void init_input(mpl::true_); - void init_input(mpl::false_) { } - void init_output(mpl::true_); - void init_output(mpl::false_) { } - double_object ptrs_; - Direct d_; -}; - -template -class direct_adapter : private direct_adapter_base { -private: - typedef direct_adapter_base base_type; - typedef typename base_type::pointers pointers; - typedef typename base_type::is_double is_double; - using base_type::ptrs_; - using base_type::d_; -public: - typedef typename base_type::char_type char_type; - typedef typename base_type::category category; - - // Constructors - -#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1310) - direct_adapter(const Direct& d) : base_type(d) { } - direct_adapter(const direct_adapter& d) : base_type(d) { } -# define BOOST_PP_LOCAL_LIMITS (1, BOOST_IOSTREAMS_MAX_FORWARDING_ARITY) -#else - template - struct is_direct - : mpl::or_< - is_same >, - is_same - > - { }; - template - direct_adapter(const U& u) - : base_type(forward(u, is_direct())) - { } -# define BOOST_PP_LOCAL_LIMITS (2, BOOST_IOSTREAMS_MAX_FORWARDING_ARITY) -#endif - -#define BOOST_PP_LOCAL_MACRO(n) \ - template \ - direct_adapter(BOOST_PP_ENUM_BINARY_PARAMS(n, const P, &p)) \ - : base_type(Direct(BOOST_PP_ENUM_PARAMS(n, p))) \ - { } \ - /**/ -#include BOOST_PP_LOCAL_ITERATE() -#undef BOOST_PP_LOCAL_MACRO - - // Device interface. - - std::streamsize read(char_type* s, std::streamsize n); - std::streamsize write(const char_type* s, std::streamsize n); - std::streampos seek( stream_offset, BOOST_IOS::seekdir, - BOOST_IOS::openmode = BOOST_IOS::in | BOOST_IOS::out ); - void close(); - void close(BOOST_IOS::openmode which); -#ifndef BOOST_IOSTREAMS_NO_LOCALE - void imbue(const std::locale&); -#endif - - // Direct device access. - - Direct& operator*() { return d_; } - Direct* operator->() { return &d_; } -#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) -private: - template - static Direct forward(const U& u, mpl::true_) { return u; } - template - static Direct forward(const U& u, mpl::false_) { return Direct(u); } -#endif -}; - -//--------------Definition of wrap_direct and unwrap_direct-------------------// - -template -struct wrap_direct_traits - : mpl::if_< - is_direct, - direct_adapter, - Device - > - { }; - -template -typename wrap_direct_traits::type -inline wrap_direct(Device dev) -{ - typedef typename wrap_direct_traits::type type; - return type(dev); -} - -template -inline Device& unwrap_direct(Device& d) { return d; } - -template -inline Device& unwrap_direct(direct_adapter& d) { return *d; } - -//--------------Implementation of direct_adapter_base-------------------------// - -template -direct_adapter_base::direct_adapter_base(const Direct& d) : d_(d) -{ - init_input(is_convertible()); - init_output(is_convertible()); -} - -template -void direct_adapter_base::init_input(mpl::true_) -{ - std::pair seq = iostreams::input_sequence(d_); - ptrs_.first().beg = seq.first; - ptrs_.first().ptr = seq.first; - ptrs_.first().end = seq.second; -} - -template -void direct_adapter_base::init_output(mpl::true_) -{ - std::pair seq = iostreams::output_sequence(d_); - ptrs_.second().beg = seq.first; - ptrs_.second().ptr = seq.first; - ptrs_.second().end = seq.second; -} - -//--------------Implementation of direct_adapter------------------------------// - -template -inline std::streamsize direct_adapter::read - (char_type* s, std::streamsize n) -{ - using namespace std; - pointers& get = ptrs_.first(); - std::streamsize avail = - static_cast(get.end - get.ptr); - std::streamsize result = (std::min)(n, avail); - std::copy(get.ptr, get.ptr + result, s); - get.ptr += result; - return result != 0 ? result : -1; -} - -template -inline std::streamsize direct_adapter::write - (const char_type* s, std::streamsize n) -{ - using namespace std; - pointers& put = ptrs_.second(); - if (n > static_cast(put.end - put.ptr)) - boost::throw_exception(write_area_exhausted()); - std::copy(s, s + n, put.ptr); - put.ptr += n; - return n; -} - -template -inline std::streampos direct_adapter::seek - ( stream_offset off, BOOST_IOS::seekdir way, - BOOST_IOS::openmode which ) -{ - using namespace std; - pointers& get = ptrs_.first(); - pointers& put = ptrs_.second(); - if (way == BOOST_IOS::cur && get.ptr != put.ptr) - boost::throw_exception(bad_seek()); - ptrdiff_t next = 0; - if ((which & BOOST_IOS::in) || !is_double::value) { - if (way == BOOST_IOS::beg) - next = off; - else if (way == BOOST_IOS::cur) - next = get.ptr - get.beg + off; - else - next = get.end - get.beg + off; - if (next >= 0 && next <= get.end - get.beg) - get.ptr = get.beg + next; - else - boost::throw_exception(bad_seek()); - } - if ((which & BOOST_IOS::out) && is_double::value) { - if (way == BOOST_IOS::beg) - next = off; - else if (way == BOOST_IOS::cur) - next = put.ptr - put.beg + off; - else - next = put.end - put.beg + off; - if (next >= 0 && next <= put.end - put.beg) - put.ptr = put.beg + next; - else - boost::throw_exception(bad_seek()); - } - return offset_to_position(next); -} - -template -void direct_adapter::close() -{ - BOOST_STATIC_ASSERT((!is_convertible::value)); - detail::close_all(d_); -} - -template -void direct_adapter::close(BOOST_IOS::openmode which) -{ - BOOST_STATIC_ASSERT((is_convertible::value)); - boost::iostreams::close(d_, which); -} - -#ifndef BOOST_IOSTREAMS_NO_LOCALE - template - void direct_adapter::imbue(const std::locale& loc) - { boost::iostreams::imbue(d_, loc); } -#endif - -} } } // End namespaces detail, iostreams, boost. - -#include - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DIRECT_ADAPTER_HPP_INCLUDED diff --git a/boost/iostreams/detail/adapter/filter_adapter.hpp b/boost/iostreams/detail/adapter/filter_adapter.hpp deleted file mode 100644 index a2ab4925..00000000 --- a/boost/iostreams/detail/adapter/filter_adapter.hpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Defines the class template boost::iostreams::detail::filter_adapter, - * a convenience base class for filter adapters. - * - * File: boost/iostreams/detail/adapter/filter_adapter.hpp - * Date: Mon Nov 26 14:35:48 MST 2007 - * Copyright: 2007-2008 CodeRage, LLC - * Author: Jonathan Turkanis - * Contact: turkanis at coderage dot com - * - * Distributed under the Boost Software License, Version 1.0.(See accompanying - * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) - * - * See http://www.boost.org/libs/iostreams for documentation. - */ - -#ifndef BOOST_IOSTREAMS_DETAIL_FILTER_ADAPTER_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_FILTER_ADAPTER_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include - -namespace boost { namespace iostreams { namespace detail { - -template -class filter_adapter { -private: - typedef typename detail::value_type::type value_type; - typedef typename detail::param_type::type param_type; -public: - explicit filter_adapter(param_type t) : t_(t) { } - T& component() { return t_; } - - template - void close(Device& dev) - { - detail::close_all(t_, dev); - } - - template - void close(Device& dev, BOOST_IOS::openmode which) - { - iostreams::close(t_, dev, which); - } - - template - void flush(Device& dev) - { - return iostreams::flush(t_, dev); - } - - template // Avoid dependency on - void imbue(const Locale& loc) { iostreams::imbue(t_, loc); } - - std::streamsize optimal_buffer_size() const - { return iostreams::optimal_buffer_size(t_); } -public: - value_type t_; -}; - -//----------------------------------------------------------------------------// - -} } } // End namespaces detail, iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_FILTER_ADAPTER_HPP_INCLUDED diff --git a/boost/iostreams/detail/add_facet.hpp b/boost/iostreams/detail/add_facet.hpp deleted file mode 100644 index 6033d4f8..00000000 --- a/boost/iostreams/detail/add_facet.hpp +++ /dev/null @@ -1,49 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -// Borrowed from - -#ifndef BOOST_IOSTREAMS_DETAIL_ADD_FACET_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_ADD_FACET_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // BOOST_DINKUMWARE_STDLIB. -#include - -//------------------Definition of add_facet-----------------------------------// - -// Does STLport uses old Dinkumware locale? -#if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && \ - defined(_STLP_NO_OWN_IOSTREAMS) \ - /**/ -# if (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) -# define BOOST_IOSTREMS_STLPORT_WITH_OLD_DINKUMWARE -# endif -#endif - -namespace boost { namespace iostreams { namespace detail { - -template -inline std::locale add_facet(const std::locale &l, Facet * f) -{ - return - #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) || \ - defined(BOOST_IOSTREMS_STLPORT_WITH_OLD_DINKUMWARE) \ - /**/ - std::locale(std::_Addfac(l, f)); - #else - // standard compatible - std::locale(l, f); - #endif -} - -} } } // End namespaces detail, iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_ADD_FACET_HPP_INCLUDED diff --git a/boost/iostreams/detail/codecvt_helper.hpp b/boost/iostreams/detail/codecvt_helper.hpp deleted file mode 100644 index 0bd8d598..00000000 --- a/boost/iostreams/detail/codecvt_helper.hpp +++ /dev/null @@ -1,214 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -// Contains the definition of the template codecvt_helper, useful for -// defining specializations of std::codecvt where state_type != mbstate_t. -// Compensates for the fact that some standard library implementations -// do not derive the primiary codecvt template from locale::facet or -// provide the correct member types and functions. - -// Usage: -// -// // In global namespace: -// BOOST_IOSTREAMS_CODECVT_SPEC(mystate) -// -// // In user namespace: -// template -// struct mycodecvt : codecvt_helper { ... }; -// -// // Or: -// struct mycodecvt : codecvt_helper { ... }; -// -// Etc. - -#ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // Put size_t in std, BOOST_MSVC, Dinkum. -#include -#include // min. -#include // size_t. -#include // locale, codecvt_base, codecvt. -#include - -//------------------Definition of traits--------------------------------------// - -namespace boost { namespace iostreams { namespace detail { - -#if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //-----------------------// - -template -struct codecvt_intern { typedef typename T::intern_type type; }; - -template -struct codecvt_extern { typedef typename T::extern_type type; }; - -#else // #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //--------------// - -template -struct codecvt_intern { typedef typename T::from_type type; }; - -template -struct codecvt_extern { typedef typename T::to_type type; }; - -#endif // #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //-------------// - -template -struct codecvt_state { typedef typename T::state_type type; }; - -} } } // End namespaces detail, iostreams, boost. - -//------------------Definition of codecvt_impl--------------------------------// - -#if defined(BOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \ - defined(BOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) || \ - defined(BOOST_IOSTREAMS_NO_LOCALE) \ - /**/ - -namespace boost { namespace iostreams { namespace detail { - -template -struct codecvt_impl : std::locale::facet, std::codecvt_base { -public: - typedef Intern intern_type; - typedef Extern extern_type; - typedef State state_type; - - codecvt_impl(std::size_t refs = 0) : std::locale::facet(refs) { } - - std::codecvt_base::result - in( State& state, const Extern* first1, const Extern* last1, - const Extern*& next1, Intern* first2, Intern* last2, - Intern*& next2 ) const - { - return do_in(state, first1, last1, next1, first2, last2, next2); - } - - std::codecvt_base::result - out( State& state, const Intern* first1, const Intern* last1, - const Intern*& next1, Extern* first2, Extern* last2, - Extern*& next2 ) const - { - return do_out(state, first1, last1, next1, first2, last2, next2); - } - - std::codecvt_base::result - unshift(State& state, Extern* first2, Extern* last2, Extern*& next2) const - { - return do_unshift(state, first2, last2, next2); - } - - bool always_noconv() const throw() { return do_always_noconv(); } - - int max_length() const throw() { return do_max_length(); } - - int encoding() const throw() { return do_encoding(); } - - int length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State& state, - const Extern* first1, const Extern* last1, - std::size_t len2 ) const throw() - { - return do_length(state, first1, last1, len2); - } -protected: - std::codecvt_base::result - virtual do_in( State&, const Extern*, const Extern*, const Extern*&, - Intern*, Intern*, Intern*& ) const - { - return std::codecvt_base::noconv; - } - - std::codecvt_base::result - virtual do_out( State&, const Intern*, const Intern*, const Intern*&, - Extern*, Extern*, Extern*& ) const - { - return std::codecvt_base::noconv; - } - - std::codecvt_base::result - virtual do_unshift(State&, Extern*, Extern*, Extern*&) const - { - return std::codecvt_base::ok; - } - - virtual bool do_always_noconv() const throw() { return true; } - - virtual int do_max_length() const throw() { return 1; } - - virtual int do_encoding() const throw() { return 1; } - - virtual int do_length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State&, - const Extern* first1, const Extern* last1, - std::size_t len2 ) const throw() - { - return (std::min)(static_cast(last1 - first1), len2); - } -}; - -} } } // End namespaces detail, iostreams, boost. - -#endif // no primary codecvt definition, empty definition. - -//------------------Definition of BOOST_IOSTREAMS_CODECVT_SPEC----------------// - -#if defined(BOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \ - defined(BOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) \ - /**/ -# define BOOST_IOSTREAMS_CODECVT_SPEC(state) \ - namespace std { \ - template \ - class codecvt \ - : public ::boost::iostreams::detail::codecvt_impl< \ - Intern, Extern, state \ - > \ - { \ - public: \ - codecvt(std::size_t refs = 0) \ - : ::boost::iostreams::detail::codecvt_impl< \ - Intern, Extern, state \ - >(refs) \ - { } \ - static std::locale::id id; \ - }; \ - template \ - std::locale::id codecvt::id; \ - } \ - /**/ -#else -# define BOOST_IOSTREAMS_CODECVT_SPEC(state) -#endif // no primary codecvt definition, or empty definition. - -namespace boost { namespace iostreams { namespace detail { - -//------------------Definition of codecvt_helper------------------------------// - -template -struct codecvt_helper : std::codecvt { - typedef Intern intern_type; - typedef Extern extern_type; - typedef State state_type; - codecvt_helper(std::size_t refs = 0) - #if !defined(BOOST_IOSTREAMS_NO_CODECVT_CTOR_FROM_SIZE_T) - : std::codecvt(refs) - #else - : std::codecvt() - #endif - { } -#ifdef BOOST_IOSTREAMS_NO_CODECVT_MAX_LENGTH - int max_length() const throw() { return do_max_length(); } -protected: - virtual int do_max_length() const throw() { return 1; } -#endif -}; - -} } } // End namespaces detail, iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED diff --git a/boost/iostreams/detail/codecvt_holder.hpp b/boost/iostreams/detail/codecvt_holder.hpp deleted file mode 100644 index 13a93334..00000000 --- a/boost/iostreams/detail/codecvt_holder.hpp +++ /dev/null @@ -1,63 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -// Contains machinery for performing code conversion. - -#ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HOLDER_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_CODECVT_HOLDER_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // mbstate_t. -#include // codecvt, locale. -#include // HAS_MACRO_USE_FACET. -#include - -namespace boost { namespace iostreams { namespace detail { - -struct default_codecvt { - typedef wchar_t intern_type, from_type; - typedef char extern_type, to_type; - typedef std::mbstate_t state_type; -}; - -template -struct codecvt_holder { - typedef Codecvt codecvt_type; - const codecvt_type& get() const { return codecvt_; } - void imbue(const std::locale&) { } - Codecvt codecvt_; -}; - -template<> -struct codecvt_holder { - typedef std::codecvt codecvt_type; - codecvt_holder() { reset_codecvt(); } - const codecvt_type& get() const { return *codecvt_; } - void imbue(const std::locale& loc) - { - loc_ = loc; - reset_codecvt(); - } - void reset_codecvt() - { - using namespace std; - #ifndef BOOST_HAS_MACRO_USE_FACET - codecvt_ = & use_facet< codecvt_type >(loc_); - #else - codecvt_ = & _USE(loc_, codecvt_type); - #endif - } - std::locale loc_; // Prevent codecvt_ from being freed. - const codecvt_type* codecvt_; -}; - -} } } // End namespaces detail, iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HOLDER_HPP_INCLUDED diff --git a/boost/iostreams/detail/counted_array.hpp b/boost/iostreams/detail/counted_array.hpp deleted file mode 100644 index c0cd8a17..00000000 --- a/boost/iostreams/detail/counted_array.hpp +++ /dev/null @@ -1,74 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2005-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_DETAIL_COUNTED_ARRAY_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_COUNTED_ARRAY_HPP_INCLUDED - -#include // min. -#include // size_t -#include // char_traits -#include -#include -#include // streamsize. - -namespace boost { namespace iostreams { namespace detail { - -template -class counted_array_source { -public: - typedef Ch char_type; - typedef source_tag category; - counted_array_source(const Ch* buf, std::streamsize size) - : buf_(buf), ptr_(0), end_(size) - { } - std::streamsize read(Ch* s, std::streamsize n) - { - using namespace std; - streamsize result = (std::min)(n, end_ - ptr_); - char_traits::copy( - s, - buf_ + ptr_, - static_cast(result) - ); - ptr_ += result; - return result; - } - std::streamsize count() const { return ptr_; } -private: - const Ch* buf_; - std::streamsize ptr_, end_; -}; - -template -struct counted_array_sink { -public: - typedef Ch char_type; - typedef sink_tag category; - counted_array_sink(Ch* buf, std::streamsize size) - : buf_(buf), ptr_(0), end_(size) - { } - std::streamsize write(const Ch* s, std::streamsize n) - { - using namespace std; - std::streamsize result = (std::min)(n, end_ - ptr_); - char_traits::copy( - buf_ + ptr_, - s, - static_cast(result) - ); - ptr_ += result; - return result; - } - std::streamsize count() const { return ptr_; } -private: - Ch* buf_; - std::streamsize ptr_, end_; -}; - -} } } // End namespaces iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_COUNTED_ARRAY_HPP_INCLUDED diff --git a/boost/iostreams/detail/current_directory.hpp b/boost/iostreams/detail/current_directory.hpp deleted file mode 100644 index 374444c5..00000000 --- a/boost/iostreams/detail/current_directory.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - - * File: boost/iostreams/detail/execute.hpp - * Date: Thu Dec 06 13:21:54 MST 2007 - * Copyright: 2007-2008 CodeRage, LLC - * Author: Jonathan Turkanis - * Contact: turkanis at coderage dot com - * - * Defines the function boost::iostreams::detail::current_directory, used by - * boost::iostreams::detail::absolute_path. - */ - -#ifndef BOOST_IOSTREAMS_DETAIL_CURRENT_DIRECTORY_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_CURRENT_DIRECTORY_HPP_INCLUDED - -#include // make sure size_t is in std. -#include // size_t -#include -#include -#include -#include -#ifdef BOOST_IOSTREAMS_WINDOWS -# define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -# include -#else -# include // sysconf. -#endif - -// Must come last. -#include - -namespace boost { namespace iostreams { namespace detail { - -// Returns the current working directory -inline std::string current_directory() -{ -#ifdef BOOST_IOSTREAMS_WINDOWS - DWORD length; - basic_buffer buf(MAX_PATH); - while (true) { - length = ::GetCurrentDirectoryA(buf.size(), buf.data()); - if (!length) - throw_system_failure("failed determining current directory"); - if (length < static_cast(buf.size())) - break; - buf.resize(buf.size() * 2); - } - return std::string(buf.data(), length); -#else // #ifdef BOOST_IOSTREAMS_WINDOWS - basic_buffer buf(pathconf(".", _PC_PATH_MAX)); - if (!getcwd(buf.data(), static_cast(buf.size()))) - throw_system_failure("failed determining current directory"); - return std::string(buf.data()); -#endif // #ifdef BOOST_IOSTREAMS_WINDOWS -} - -} } } // End namespaces detail, iostreams, boost. - -#include - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CURRENT_DIRECTORY_HPP_INCLUDED diff --git a/boost/iostreams/detail/fstream.hpp b/boost/iostreams/detail/fstream.hpp deleted file mode 100644 index 848258d9..00000000 --- a/boost/iostreams/detail/fstream.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_DETAIL_FSTREAM_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_FSTREAM_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES -# include -#else -# include -#endif - -#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES -# define BOOST_IOSTREAMS_BASIC_IFSTREAM(Ch, Tr) std::basic_ifstream -# define BOOST_IOSTREAMS_BASIC_OFSTREAM(Ch, Tr) std::basic_ofstream -# define BOOST_IOSTREAMS_BASIC_FSTREAM(Ch, Tr) std::basic_fstream -# define BOOST_IOSTREAMS_BASIC_FILEBUF(Ch) std::basic_filebuf -#else -# define BOOST_IOSTREAMS_BASIC_IFSTREAM(Ch, Tr) std::ifstream -# define BOOST_IOSTREAMS_BASIC_OFSTREAM(Ch, Tr) std::ofstream -# define BOOST_IOSTREAMS_BASIC_FILEBUF(Ch) std::filebuf -#endif - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_FSTREAM_HPP_INCLUDED diff --git a/boost/iostreams/detail/newline.hpp b/boost/iostreams/detail/newline.hpp deleted file mode 100644 index d6fceb04..00000000 --- a/boost/iostreams/detail/newline.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2005-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_DETAIL_NEWLINE_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_NEWLINE_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -namespace boost { namespace iostreams { namespace detail { - -template -struct newline; - -template<> -struct newline { - BOOST_STATIC_CONSTANT(char, value = '\n'); -}; - -template<> -struct newline { - BOOST_STATIC_CONSTANT(wchar_t, value = L'\n'); -}; - -} } } // End namespaces detaill, iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_NEWLINE_HPP_INCLUDED diff --git a/boost/iostreams/detail/param_type.hpp b/boost/iostreams/detail/param_type.hpp deleted file mode 100644 index 3a994934..00000000 --- a/boost/iostreams/detail/param_type.hpp +++ /dev/null @@ -1,27 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_DETAIL_PARAM_TYPE_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_PARAM_TYPE_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#include - -namespace boost { namespace iostreams { namespace detail { - -template -struct param_type { - typedef typename mpl::if_, T&, const T&>::type type; -}; - -} } } // End namespaces detail, iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_PARAM_TYPE_HPP_INCLUDED //-----------// diff --git a/boost/iostreams/detail/restrict_impl.hpp b/boost/iostreams/detail/restrict_impl.hpp deleted file mode 100644 index 7f09c244..00000000 --- a/boost/iostreams/detail/restrict_impl.hpp +++ /dev/null @@ -1,483 +0,0 @@ -/* - * Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - - * File: boost/iostreams/detail/restrict_impl.hpp - * Date: Sun Jan 06 12:57:30 MST 2008 - * Copyright: 2007-2008 CodeRage, LLC - * Author: Jonathan Turkanis - * Contact: turkanis at coderage dot com - * - * If included with the macro BOOST_IOSTREAMS_RESTRICT undefined, defines the - * class template boost::iostreams::restriction. If included with the macro - * BOOST_IOSTREAMS_RESTRICT defined as an identifier, defines the overloaded - * function template boost::iostreams::BOOST_IOSTREAMS_RESTRICT, and object - * generator for boost::iostreams::restriction. - * - * This design allows and - * to share an implementation. - */ - -#if !defined(BOOST_IOSTREAMS_RESTRICT_IMPL_HPP_INCLUDED) && \ - !defined(BOOST_IOSTREAMS_RESTRICT) -# define BOOST_IOSTREAMS_RESTRICT_IMPL_HPP_INCLUDED - -//------------------Implementation of restriction-----------------------------// - -# include // min. -# include // pair. -# include // intmax_t. -# include // DEDUCED_TYPENAME. -# include -# include -# include -# include -# include -# include -# include -# include // failure. -# include -# include -# include -# include // mode_of, is_direct. -# include -# include -# include -# include - -# include - -namespace boost { namespace iostreams { - -namespace detail { - -// -// Template name: restricted_indirect_device. -// Description: Provides an restricted view of an indirect Device. -// Template parameters: -// Device - An indirect model of Device that models either Source or -// SeekableDevice. -// -template -class restricted_indirect_device : public device_adapter { -private: - typedef typename detail::param_type::type param_type; -public: - typedef typename char_type_of::type char_type; - typedef typename mode_of::type mode; - BOOST_STATIC_ASSERT(!(is_convertible::value)); - struct category - : mode, - device_tag, - closable_tag, - flushable_tag, - localizable_tag, - optimally_buffered_tag - { }; - restricted_indirect_device( param_type dev, stream_offset off, - stream_offset len = -1 ); - std::streamsize read(char_type* s, std::streamsize n); - std::streamsize write(const char_type* s, std::streamsize n); - std::streampos seek(stream_offset off, BOOST_IOS::seekdir way); -private: - stream_offset beg_, pos_, end_; -}; - -// -// Template name: restricted_direct_device. -// Description: Provides an restricted view of a Direct Device. -// Template parameters: -// Device - A model of Direct and Device. -// -template -class restricted_direct_device : public device_adapter { -public: - typedef typename char_type_of::type char_type; - typedef std::pair pair_type; - typedef typename mode_of::type mode; - BOOST_STATIC_ASSERT(!(is_convertible::value)); - struct category - : mode_of::type, - device_tag, - direct_tag, - closable_tag, - localizable_tag - { }; - restricted_direct_device( const Device& dev, stream_offset off, - stream_offset len = -1 ); - pair_type input_sequence(); - pair_type output_sequence(); -private: - pair_type sequence(mpl::true_); - pair_type sequence(mpl::false_); - char_type *beg_, *end_; -}; - -// -// Template name: restricted_filter. -// Description: Provides an restricted view of a Filter. -// Template parameters: -// Filter - An indirect model of Filter. -// -template -class restricted_filter : public filter_adapter { -public: - typedef typename char_type_of::type char_type; - typedef typename mode_of::type mode; - BOOST_STATIC_ASSERT(!(is_convertible::value)); - struct category - : mode, - filter_tag, - multichar_tag, - closable_tag, - localizable_tag, - optimally_buffered_tag - { }; - restricted_filter( const Filter& flt, stream_offset off, - stream_offset len = -1 ); - - template - std::streamsize read(Source& src, char_type* s, std::streamsize n) - { - using namespace std; - if (!open_) - open(src, BOOST_IOS::in); - std::streamsize amt = - end_ != -1 ? - (std::min) (n, static_cast(end_ - pos_)) : - n; - std::streamsize result = - iostreams::read(this->component(), src, s, amt); - if (result != -1) - pos_ += result; - return result; - } - - template - std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) - { - if (!open_) - open(snk, BOOST_IOS::out); - if (end_ != -1 && pos_ + n >= end_) { - if(pos_ < end_) - pos_ += iostreams::write(this->component(), - snk, s, end_ - pos_); - boost::throw_exception(bad_write()); - } - std::streamsize result = - iostreams::write(this->component(), snk, s, n); - pos_ += result; - return result; - } - - template - std::streampos seek(Device& dev, stream_offset off, BOOST_IOS::seekdir way) - { - stream_offset next; - if (way == BOOST_IOS::beg) { - next = beg_ + off; - } else if (way == BOOST_IOS::cur) { - next = pos_ + off; - } else if (end_ != -1) { - next = end_ + off; - } else { - // Restriction is half-open; seek relative to the actual end. - pos_ = this->component().seek(dev, off, BOOST_IOS::end); - if (pos_ < beg_) - boost::throw_exception(bad_seek()); - return offset_to_position(pos_ - beg_); - } - if (next < beg_ || (end_ != -1 && next >= end_)) - boost::throw_exception(bad_seek()); - pos_ = this->component().seek(dev, next, BOOST_IOS::cur); - return offset_to_position(pos_ - beg_); - } - - template - void close(Device& dev) - { - open_ = false; - detail::close_all(this->component(), dev); - } - - template - void close(Device& dev, BOOST_IOS::openmode which) - { - open_ = false; - iostreams::close(this->component(), dev, which); - } -private: - template - void open(Device& dev, BOOST_IOS::openmode which) - { - typedef typename is_convertible::type is_dual_use; - open_ = true; - which = is_dual_use() ? which : (BOOST_IOS::in | BOOST_IOS::out); - iostreams::skip(this->component(), dev, beg_, which); - } - - stream_offset beg_, pos_, end_; - bool open_; -}; - -template -struct restriction_traits - : iostreams::select< // Disambiguation for Tru64. - is_filter, restricted_filter, - is_direct, restricted_direct_device, - else_, restricted_indirect_device - > - { }; - -} // End namespace detail. - -template -struct restriction : public detail::restriction_traits::type { - typedef typename detail::param_type::type param_type; - typedef typename detail::restriction_traits::type base_type; - restriction(param_type t, stream_offset off, stream_offset len = -1) - : base_type(t, off, len) - { } -}; - -namespace detail { - -//--------------Implementation of restricted_indirect_device------------------// - -template -restricted_indirect_device::restricted_indirect_device - (param_type dev, stream_offset off, stream_offset len) - : device_adapter(dev), beg_(off), pos_(off), - end_(len != -1 ? off + len : -1) -{ - if (len < -1 || off < 0) - boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad offset")); - iostreams::skip(this->component(), off); -} - -template -inline std::streamsize restricted_indirect_device::read - (char_type* s, std::streamsize n) -{ - using namespace std; - std::streamsize amt = - end_ != -1 ? - (std::min) (n, static_cast(end_ - pos_)) : - n; - std::streamsize result = iostreams::read(this->component(), s, amt); - if (result != -1) - pos_ += result; - return result; -} - -template -inline std::streamsize restricted_indirect_device::write - (const char_type* s, std::streamsize n) -{ - if (end_ != -1 && pos_ + n >= end_) { - if(pos_ < end_) - pos_ += iostreams::write(this->component(), s, end_ - pos_); - boost::throw_exception(bad_write()); - } - std::streamsize result = iostreams::write(this->component(), s, n); - pos_ += result; - return result; -} - -template -std::streampos restricted_indirect_device::seek - (stream_offset off, BOOST_IOS::seekdir way) -{ - stream_offset next; - if (way == BOOST_IOS::beg) { - next = beg_ + off; - } else if (way == BOOST_IOS::cur) { - next = pos_ + off; - } else if (end_ != -1) { - next = end_ + off; - } else { - // Restriction is half-open; seek relative to the actual end. - pos_ = iostreams::seek(this->component(), off, BOOST_IOS::end); - if (pos_ < beg_) - boost::throw_exception(bad_seek()); - return offset_to_position(pos_ - beg_); - } - if (next < beg_ || (end_ != -1 && next > end_)) - boost::throw_exception(bad_seek()); - pos_ = iostreams::seek(this->component(), next - pos_, BOOST_IOS::cur); - return offset_to_position(pos_ - beg_); -} - -//--------------Implementation of restricted_direct_device--------------------// - -template -restricted_direct_device::restricted_direct_device - (const Device& dev, stream_offset off, stream_offset len) - : device_adapter(dev), beg_(0), end_(0) -{ - std::pair seq = - sequence(is_convertible()); - if ( off < 0 || len < -1 || - (len != -1 && off + len > seq.second - seq.first) ) - { - boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad offset")); - } - beg_ = seq.first + off; - end_ = len != -1 ? - seq.first + off + len : - seq.second; -} - -template -typename restricted_direct_device::pair_type -restricted_direct_device::input_sequence() -{ - BOOST_STATIC_ASSERT((is_convertible::value)); - return std::make_pair(beg_, end_); -} - -template -typename restricted_direct_device::pair_type -restricted_direct_device::output_sequence() -{ - BOOST_STATIC_ASSERT((is_convertible::value)); - return std::make_pair(beg_, end_); -} - -template -typename restricted_direct_device::pair_type -restricted_direct_device::sequence(mpl::true_) -{ return iostreams::input_sequence(this->component()); } - -template -typename restricted_direct_device::pair_type -restricted_direct_device::sequence(mpl::false_) -{ return iostreams::output_sequence(this->component()); } - -//--------------Implementation of restricted_filter---------------------------// - -template -restricted_filter::restricted_filter - (const Filter& flt, stream_offset off, stream_offset len) - : filter_adapter(flt), beg_(off), - pos_(off), end_(len != -1 ? off + len : -1), open_(false) -{ - if (len < -1 || off < 0) - boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad offset")); -} - -} // End namespace detail. - -} } // End namespaces iostreams, boost. - -#elif defined(BOOST_IOSTREAMS_RESTRICT) - -namespace boost { namespace iostreams { - -//--------------Implementation of restrict/slice------------------------------// - -// Note: The following workarounds are patterned after resolve.hpp. It has not -// yet been confirmed that they are necessary. - -# ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //------------------------// -# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //------------------------------// - -template -restriction -BOOST_IOSTREAMS_RESTRICT( const T& t, stream_offset off, stream_offset len = -1 - BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) ) -{ return restriction(t, off, len); } - -template -restriction< std::basic_streambuf > -BOOST_IOSTREAMS_RESTRICT( std::basic_streambuf& sb, stream_offset off, - stream_offset len = -1 ) -{ return restriction< std::basic_streambuf >(sb, off, len); } - -template -restriction< std::basic_istream > -BOOST_IOSTREAMS_RESTRICT - (std::basic_istream& is, stream_offset off, stream_offset len = -1) -{ return restriction< std::basic_istream >(is, off, len); } - -template -restriction< std::basic_ostream > -BOOST_IOSTREAMS_RESTRICT - (std::basic_ostream& os, stream_offset off, stream_offset len = -1) -{ return restriction< std::basic_ostream >(os, off, len); } - -template -restriction< std::basic_iostream > -BOOST_IOSTREAMS_RESTRICT - (std::basic_iostream& io, stream_offset off, stream_offset len = -1) -{ return restriction< std::basic_iostream >(io, off, len); } - -# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------// - -template -restriction -BOOST_IOSTREAMS_RESTRICT( const T& t, stream_offset off, stream_offset len = -1 - BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) ) -{ return restriction(t, off, len); } - -restriction -BOOST_IOSTREAMS_RESTRICT - (std::streambuf& sb, stream_offset off, stream_offset len = -1) -{ return restriction(sb, off, len); } - -restriction -BOOST_IOSTREAMS_RESTRICT - (std::istream& is, stream_offset off, stream_offset len = -1) -{ return restriction(is, off, len); } - -restriction -BOOST_IOSTREAMS_RESTRICT - (std::ostream& os, stream_offset off, stream_offset len = -1) -{ return restriction(os, off, len); } - -restriction -BOOST_IOSTREAMS_RESTRICT - (std::iostream& io, stream_offset off, stream_offset len = -1) -{ return restriction(io, off, len); } - -# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------// -# else // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------// - -template -restriction -BOOST_IOSTREAMS_RESTRICT - (const T& t, stream_offset off, stream_offset len, mpl::true_) -{ // Bad overload resolution. - return restriction(const_cast(t, off, len)); -} - -template -restriction -BOOST_IOSTREAMS_RESTRICT - (const T& t, stream_offset off, stream_offset len, mpl::false_) -{ return restriction(t, off, len); } - -template -restriction -BOOST_IOSTREAMS_RESTRICT( const T& t, stream_offset off, stream_offset len = -1 - BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) ) -{ return BOOST_IOSTREAMS_RESTRICT(t, off, len, is_std_io()); } - -# if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) && \ - !defined(__GNUC__) // ---------------------------------------------------// - -template -restriction -BOOST_IOSTREAMS_RESTRICT(T& t, stream_offset off, stream_offset len = -1) -{ return restriction(t, off, len); } - -# endif // Borland 5.x or GCC //-------------------------------// -# endif // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //--------------// - -} } // End namespaces iostreams, boost. - -# include - -#endif // #if !defined(BOOST_IOSTREAMS_RESTRICT_IMPL_HPP_INCLUDED) ... diff --git a/boost/iostreams/detail/streambuf/chainbuf.hpp b/boost/iostreams/detail/streambuf/chainbuf.hpp deleted file mode 100644 index c3714fe0..00000000 --- a/boost/iostreams/detail/streambuf/chainbuf.hpp +++ /dev/null @@ -1,113 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_DETAIL_CHAINBUF_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_CHAINBUF_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // BOOST_MSVC, template friends. -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace iostreams { namespace detail { - -//--------------Definition of chainbuf----------------------------------------// - -// -// Template name: chainbuf. -// Description: Stream buffer which operates by delegating to the first -// linked_streambuf in a chain. -// Template parameters: -// Chain - The chain type. -// -template -class chainbuf - : public BOOST_IOSTREAMS_BASIC_STREAMBUF( - typename Chain::char_type, - typename Chain::traits_type - ), - public access_control, - private noncopyable -{ -private: - typedef access_control, Access> client_type; -public: - typedef typename Chain::char_type char_type; - BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(typename Chain::traits_type) -protected: - typedef linked_streambuf delegate_type; - chainbuf() { client_type::set_chain(&chain_); } - int_type underflow() - { sentry t(this); return translate(delegate().underflow()); } - int_type pbackfail(int_type c) - { sentry t(this); return translate(delegate().pbackfail(c)); } - std::streamsize xsgetn(char_type* s, std::streamsize n) - { sentry t(this); return delegate().xsgetn(s, n); } - int_type overflow(int_type c) - { sentry t(this); return translate(delegate().overflow(c)); } - std::streamsize xsputn(const char_type* s, std::streamsize n) - { sentry t(this); return delegate().xsputn(s, n); } - int sync() { sentry t(this); return delegate().sync(); } - pos_type seekoff( off_type off, BOOST_IOS::seekdir way, - BOOST_IOS::openmode which = - BOOST_IOS::in | BOOST_IOS::out ) - { sentry t(this); return delegate().seekoff(off, way, which); } - pos_type seekpos( pos_type sp, - BOOST_IOS::openmode which = - BOOST_IOS::in | BOOST_IOS::out ) - { sentry t(this); return delegate().seekpos(sp, which); } -protected: - typedef BOOST_IOSTREAMS_BASIC_STREAMBUF( - typename Chain::char_type, - typename Chain::traits_type - ) base_type; -private: - - // Translate from std int_type to chain's int_type. - typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) std_traits; - typedef typename Chain::traits_type chain_traits; - static typename chain_traits::int_type - translate(typename std_traits::int_type c) - { return translate_int_type(c); } - - delegate_type& delegate() - { return static_cast(chain_.front()); } - void get_pointers() - { - this->setg(delegate().eback(), delegate().gptr(), delegate().egptr()); - this->setp(delegate().pbase(), delegate().epptr()); - this->pbump((int) (delegate().pptr() - delegate().pbase())); - } - void set_pointers() - { - delegate().setg(this->eback(), this->gptr(), this->egptr()); - delegate().setp(this->pbase(), this->epptr()); - delegate().pbump((int) (this->pptr() - this->pbase())); - } - struct sentry { - sentry(chainbuf* buf) : buf_(buf) - { buf_->set_pointers(); } - ~sentry() { buf_->get_pointers(); } - chainbuf* buf_; - }; - friend struct sentry; - Chain chain_; -}; - -} } } // End namespaces detail, iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CHAINBUF_HPP_INCLUDED diff --git a/boost/iostreams/detail/translate_int_type.hpp b/boost/iostreams/detail/translate_int_type.hpp deleted file mode 100644 index ae48a2c4..00000000 --- a/boost/iostreams/detail/translate_int_type.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_DETAIL_TRANSLATE_INT_TYPE_HPP_INCLUDED -#define BOOST_IOSTREAMS_DETAIL_TRANSLATE_INT_TYPE_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include - -namespace boost { namespace iostreams { namespace detail { - -template -struct translate_int_type_impl; - -// -// Template name: translate_char. -// Description: Translates a character or an end-of-file indicator from the -// int_type of one character traits type to the int_type of another. -// -template -typename TargetTr::int_type -translate_int_type(typename SourceTr::int_type c) -{ - typedef translate_int_type_impl::value> impl; - return impl::template inner::translate(c); -} - -//----------------------------------------------------------------------------// - -template<> -struct translate_int_type_impl { - template - struct inner { - static typename TargetTr::int_type - translate(typename SourceTr::int_type c) { return c; } - }; -}; - -template<> -struct translate_int_type_impl { - template - struct inner { - static typename TargetTr::int_type - translate(typename SourceTr::int_type c) - { - return SourceTr::eq_int_type(SourceTr::eof()) ? - TargetTr::eof() : - TargetTr::to_int_type(SourceTr::to_char_type(c)); - } - }; -}; - -} } } // End namespaces detail, iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_DETAIL_TRANSLATE_INT_TYPE_HPP_INCLUDED diff --git a/boost/iostreams/device/file.hpp b/boost/iostreams/device/file.hpp deleted file mode 100644 index 3eb03016..00000000 --- a/boost/iostreams/device/file.hpp +++ /dev/null @@ -1,191 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_FILE_HPP_INCLUDED -#define BOOST_IOSTREAMS_FILE_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#ifndef BOOST_IOSTREAMS_NO_LOCALE -# include -#endif -#include // pathnames, char_traits. -#include -#include // openmode, seekdir, int types. -#include -#include // seek. -#include - -// Must come last. -#include // MSVC. - -namespace boost { namespace iostreams { - -template -class basic_file { -public: - typedef Ch char_type; - struct category - : public seekable_device_tag, - public closable_tag, - public localizable_tag, - public flushable_tag - { }; - basic_file( const std::string& path, - BOOST_IOS::openmode mode = - BOOST_IOS::in | BOOST_IOS::out, - BOOST_IOS::openmode base_mode = - BOOST_IOS::in | BOOST_IOS::out ); - std::streamsize read(char_type* s, std::streamsize n); - bool putback(char_type c); - std::streamsize write(const char_type* s, std::streamsize n); - std::streampos seek( stream_offset off, BOOST_IOS::seekdir way, - BOOST_IOS::openmode which = - BOOST_IOS::in | BOOST_IOS::out ); - void open( const std::string& path, - BOOST_IOS::openmode mode = - BOOST_IOS::in | BOOST_IOS::out, - BOOST_IOS::openmode base_mode = - BOOST_IOS::in | BOOST_IOS::out ); - bool is_open() const; - void close(); - bool flush(); -#ifndef BOOST_IOSTREAMS_NO_LOCALE - void imbue(const std::locale& loc) { pimpl_->file_.pubimbue(loc); } -#endif -private: - struct impl { - impl(const std::string& path, BOOST_IOS::openmode mode) - { file_.open(path.c_str(), mode); } - ~impl() { if (file_.is_open()) file_.close(); } - BOOST_IOSTREAMS_BASIC_FILEBUF(Ch) file_; - }; - shared_ptr pimpl_; -}; - -typedef basic_file file; -typedef basic_file wfile; - -template -struct basic_file_source : private basic_file { - typedef Ch char_type; - struct category - : input_seekable, - device_tag, - closable_tag - { }; - using basic_file::read; - using basic_file::putback; - using basic_file::seek; - using basic_file::is_open; - using basic_file::close; - basic_file_source( const std::string& path, - BOOST_IOS::openmode mode = - BOOST_IOS::in ) - : basic_file(path, mode & ~BOOST_IOS::out, BOOST_IOS::in) - { } - void open( const std::string& path, - BOOST_IOS::openmode mode = BOOST_IOS::in ) - { - basic_file::open(path, mode & ~BOOST_IOS::out, BOOST_IOS::in); - } -}; - -typedef basic_file_source file_source; -typedef basic_file_source wfile_source; - -template -struct basic_file_sink : private basic_file { - typedef Ch char_type; - struct category - : output_seekable, - device_tag, - closable_tag, - flushable_tag - { }; - using basic_file::write; - using basic_file::seek; - using basic_file::is_open; - using basic_file::close; - using basic_file::flush; - basic_file_sink( const std::string& path, - BOOST_IOS::openmode mode = BOOST_IOS::out ) - : basic_file(path, mode & ~BOOST_IOS::in, BOOST_IOS::out) - { } - void open( const std::string& path, - BOOST_IOS::openmode mode = BOOST_IOS::out ) - { - basic_file::open(path, mode & ~BOOST_IOS::in, BOOST_IOS::out); - } -}; - -typedef basic_file_sink file_sink; -typedef basic_file_sink wfile_sink; - -//------------------Implementation of basic_file------------------------------// - -template -basic_file::basic_file - ( const std::string& path, BOOST_IOS::openmode mode, - BOOST_IOS::openmode base_mode ) -{ - open(path, mode, base_mode); -} - -template -inline std::streamsize basic_file::read - (char_type* s, std::streamsize n) -{ - std::streamsize result = pimpl_->file_.sgetn(s, n); - return result != 0 ? result : -1; -} - -template -inline bool basic_file::putback(char_type c) -{ - return !!pimpl_->file_.sputbackc(c); -} - -template -inline std::streamsize basic_file::write - (const char_type* s, std::streamsize n) -{ return pimpl_->file_.sputn(s, n); } - -template -std::streampos basic_file::seek - ( stream_offset off, BOOST_IOS::seekdir way, - BOOST_IOS::openmode ) -{ return iostreams::seek(pimpl_->file_, off, way); } - -template -void basic_file::open - ( const std::string& path, BOOST_IOS::openmode mode, - BOOST_IOS::openmode base_mode ) -{ - pimpl_.reset(new impl(path, mode | base_mode)); -} - -template -bool basic_file::is_open() const { return pimpl_->file_.is_open(); } - -template -void basic_file::close() { pimpl_->file_.close(); } - -template -bool basic_file::flush() -{ return pimpl_->file_.BOOST_IOSTREAMS_PUBSYNC() == 0; } - -//----------------------------------------------------------------------------// - -} } // End namespaces iostreams, boost. - -#include // MSVC - -#endif // #ifndef BOOST_IOSTREAMS_FILE_HPP_INCLUDED diff --git a/boost/iostreams/filter/aggregate.hpp b/boost/iostreams/filter/aggregate.hpp deleted file mode 100644 index a645a75a..00000000 --- a/boost/iostreams/filter/aggregate.hpp +++ /dev/null @@ -1,168 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED -#define BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // copy, min. -#include -#include // back_inserter -#include -#include // default_device_buffer_size -#include -#include -#include // openmode, streamsize. -#include -#include // check_eof -#include -#include -#include - -// Must come last. -#include // MSVC. - -namespace boost { namespace iostreams { - -// -// Template name: aggregate_filter. -// Template parameters: -// Ch - The character type. -// Alloc - The allocator type. -// Description: Utility for defining DualUseFilters which filter an -// entire stream at once. To use, override the protected virtual -// member do_filter. -// Note: This filter should not be copied while it is in use. -// -template > -class aggregate_filter { -public: - typedef Ch char_type; - struct category - : dual_use, - filter_tag, - multichar_tag, - closable_tag - { }; - aggregate_filter() : ptr_(0), state_(0) { } - virtual ~aggregate_filter() { } - - template - std::streamsize read(Source& src, char_type* s, std::streamsize n) - { - using namespace std; - BOOST_ASSERT(!(state_ & f_write)); - state_ |= f_read; - if (!(state_ & f_eof)) - do_read(src); - std::streamsize amt = - (std::min)(n, static_cast(data_.size() - ptr_)); - if (amt) { - BOOST_IOSTREAMS_CHAR_TRAITS(char_type)::copy(s, &data_[ptr_], amt); - ptr_ += amt; - } - return detail::check_eof(amt); - } - - template - std::streamsize write(Sink&, const char_type* s, std::streamsize n) - { - BOOST_ASSERT(!(state_ & f_read)); - state_ |= f_write; - data_.insert(data_.end(), s, s + n); - return n; - } - - template - void close(Sink& sink, BOOST_IOS::openmode which) - { - if ((state_ & f_read) != 0 && which == BOOST_IOS::in) - close_impl(); - if ((state_ & f_write) != 0 && which == BOOST_IOS::out) { - try { - vector_type filtered; - do_filter(data_, filtered); - do_write( - sink, &filtered[0], - static_cast(filtered.size()) - ); - } catch (...) { - close_impl(); - throw; - } - close_impl(); - } - } - -protected: - typedef std::vector vector_type; - typedef typename vector_type::size_type size_type; -private: - virtual void do_filter(const vector_type& src, vector_type& dest) = 0; - virtual void do_close() { } - - template - void do_read(Source& src) - { - using std::streamsize; - vector_type data; - while (true) { - const std::streamsize size = default_device_buffer_size; - Ch buf[size]; - std::streamsize amt; - if ((amt = boost::iostreams::read(src, buf, size)) == -1) - break; - data.insert(data.end(), buf, buf + amt); - } - do_filter(data, data_); - state_ |= f_eof; - } - - template - void do_write(Sink& sink, const char_type* s, std::streamsize n) - { - typedef typename iostreams::category_of::type category; - typedef is_convertible can_write; - do_write(sink, s, n, can_write()); - } - - template - void do_write(Sink& sink, const char_type* s, std::streamsize n, mpl::true_) - { iostreams::write(sink, s, n); } - - template - void do_write(Sink&, const char_type*, std::streamsize, mpl::false_) { } - - void close_impl() - { - data_.clear(); - ptr_ = 0; - state_ = 0; - do_close(); - } - - enum flag_type { - f_read = 1, - f_write = f_read << 1, - f_eof = f_write << 1 - }; - - // Note: typically will not be copied while vector contains data. - vector_type data_; - size_type ptr_; - int state_; -}; -BOOST_IOSTREAMS_PIPABLE(aggregate_filter, 1) - -} } // End namespaces iostreams, boost. - -#include // MSVC. - -#endif // #ifndef BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/counter.hpp b/boost/iostreams/filter/counter.hpp deleted file mode 100644 index 8cf775e7..00000000 --- a/boost/iostreams/filter/counter.hpp +++ /dev/null @@ -1,82 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2005-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_COUNTER_HPP_INCLUDED -#define BOOST_IOSTREAMS_COUNTER_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // count. -#include -#include -#include -#include - -// Must come last. -#include // VC7.1 C4244. - -namespace boost { namespace iostreams { - -// -// Template name: basic_counter. -// Template parameters: -// Ch - The character type. -// Description: Filter which counts lines and characters. -// -template -class basic_counter { -public: - typedef Ch char_type; - struct category - : dual_use, - filter_tag, - multichar_tag, - optimally_buffered_tag - { }; - explicit basic_counter(int first_line = 0, int first_char = 0) - : lines_(first_line), chars_(first_char) - { } - int lines() const { return lines_; } - int characters() const { return chars_; } - std::streamsize optimal_buffer_size() const { return 0; } - - template - std::streamsize read(Source& src, char_type* s, std::streamsize n) - { - std::streamsize result = iostreams::read(src, s, n); - if (result == -1) - return -1; - lines_ += std::count(s, s + result, char_traits::newline()); - chars_ += result; - return result; - } - - template - std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) - { - std::streamsize result = iostreams::write(snk, s, n); - lines_ += std::count(s, s + result, char_traits::newline()); - chars_ += result; - return result; - } -private: - int lines_; - int chars_; -}; -BOOST_IOSTREAMS_PIPABLE(basic_counter, 1) - - -typedef basic_counter counter; -typedef basic_counter wcounter; - -} } // End namespaces iostreams, boost. - -#include - -#endif // #ifndef BOOST_IOSTREAMS_COUNTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/grep.hpp b/boost/iostreams/filter/grep.hpp deleted file mode 100644 index b3030973..00000000 --- a/boost/iostreams/filter/grep.hpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - - * File: boost/iostreams/filter/grep.hpp - * Date: Mon May 26 17:48:45 MDT 2008 - * Copyright: 2008 CodeRage, LLC - * Author: Jonathan Turkanis - * Contact: turkanis at coderage dot com - * - * Defines the class template basic_grep_filter and its specializations - * grep_filter and wgrep_filter. - */ - -#ifndef BOOST_IOSTREAMS_GREP_FILTER_HPP_INCLUDED -#define BOOST_IOSTREAMS_GREP_FILTER_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include - -#include // allocator. -#include -#include -#include -#include - -namespace boost { namespace iostreams { - -namespace grep { - -const int invert = 1; -const int whole_line = invert << 1; - -} // End namespace grep. - -template< typename Ch, - typename Tr = regex_traits, - typename Alloc = std::allocator > -class basic_grep_filter : public basic_line_filter { -private: - typedef basic_line_filter base_type; -public: - typedef typename base_type::char_type char_type; - typedef typename base_type::category category; - typedef char_traits traits_type; - typedef typename base_type::string_type string_type; - typedef basic_regex regex_type; - typedef regex_constants::match_flag_type match_flag_type; - basic_grep_filter( const regex_type& re, - match_flag_type match_flags = - regex_constants::match_default, - int options = 0 ); - int count() const { return count_; } - - template - void close(Sink& snk, BOOST_IOS::openmode which) - { - base_type::close(snk, which); - options_ &= ~f_initialized; - } -private: - virtual string_type do_filter(const string_type& line) - { - if ((options_ & f_initialized) == 0) { - options_ |= f_initialized; - count_ = 0; - } - bool matches = (options_ & grep::whole_line) ? - regex_match(line, re_, match_flags_) : - regex_search(line, re_, match_flags_); - if (options_ & grep::invert) - matches = !matches; - if (matches) - ++count_; - return matches ? line + traits_type::newline() : string_type(); - } - - // Private flags bitwise OR'd with constants from namespace grep - enum flags_ { - f_initialized = 65536 - }; - - regex_type re_; - match_flag_type match_flags_; - int options_; - int count_; -}; -BOOST_IOSTREAMS_PIPABLE(basic_grep_filter, 3) - -typedef basic_grep_filter grep_filter; -typedef basic_grep_filter wgrep_filter; - -//------------------Implementation of basic_grep_filter-----------------------// - -template -basic_grep_filter::basic_grep_filter - (const regex_type& re, match_flag_type match_flags, int options) - : base_type(true), re_(re), match_flags_(match_flags), - options_(options), count_(0) - { } - -} } // End namespaces iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/line.hpp b/boost/iostreams/filter/line.hpp deleted file mode 100644 index 2c66f0ed..00000000 --- a/boost/iostreams/filter/line.hpp +++ /dev/null @@ -1,221 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2005-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_LINE_FILTER_HPP_INCLUDED -#define BOOST_IOSTREAMS_LINE_FILTER_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // min. -#include -#include // allocator. -#include -#include // BOOST_STATIC_CONSTANT. -#include -#include -#include // openmode, streamsize. -#include // check_eof -#include -#include - -// Must come last. -#include // VC7.1 C4244. - -namespace boost { namespace iostreams { - -// -// Template name: line_filter. -// Template parameters: -// Ch - The character type. -// Alloc - The allocator type. -// Description: Filter which processes data one line at a time. -// -template< typename Ch, - typename Alloc = std::allocator > -class basic_line_filter { -private: - typedef typename std::basic_string::traits_type string_traits; -public: - typedef Ch char_type; - typedef char_traits traits_type; - typedef std::basic_string< - Ch, - string_traits, - Alloc - > string_type; - struct category - : dual_use, - filter_tag, - multichar_tag, - closable_tag - { }; -protected: - basic_line_filter(bool suppress_newlines = false) - : pos_(string_type::npos), - flags_(suppress_newlines ? f_suppress : 0) - { } -public: - virtual ~basic_line_filter() { } - - template - std::streamsize read(Source& src, char_type* s, std::streamsize n) - { - using namespace std; - BOOST_ASSERT(!(flags_ & f_write)); - flags_ |= f_read; - - // Handle unfinished business. - std::streamsize result = 0; - if (!cur_line_.empty() && (result = read_line(s, n)) == n) - return n; - - typename traits_type::int_type status = traits_type::good(); - while (result < n && !traits_type::is_eof(status)) { - - // Call next_line() to retrieve a line of filtered text, and - // read_line() to copy it into buffer s. - if (traits_type::would_block(status = next_line(src))) - return result; - result += read_line(s + result, n - result); - } - - return detail::check_eof(result); - } - - template - std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) - { - using namespace std; - BOOST_ASSERT(!(flags_ & f_read)); - flags_ |= f_write; - - // Handle unfinished business. - if (pos_ != string_type::npos && !write_line(snk)) - return 0; - - const char_type *cur = s, *next; - while (true) { - - // Search for the next full line in [cur, s + n), filter it - // and write it to snk. - typename string_type::size_type rest = n - (cur - s); - if ((next = traits_type::find(cur, rest, traits_type::newline()))) { - cur_line_.append(cur, next - cur); - cur = next + 1; - if (!write_line(snk)) - return static_cast(cur - s); - } else { - cur_line_.append(cur, rest); - return n; - } - } - } - - template - void close(Sink& snk, BOOST_IOS::openmode which) - { - if ((flags_ & f_read) && which == BOOST_IOS::in) - close_impl(); - - if ((flags_ & f_write) && which == BOOST_IOS::out) { - try { - if (!cur_line_.empty()) - write_line(snk); - } catch (...) { - try { - close_impl(); - } catch (...) { } - throw; - } - close_impl(); - } - } -private: - virtual string_type do_filter(const string_type& line) = 0; - - // Copies filtered characters fron the current line into - // the given buffer. - std::streamsize read_line(char_type* s, std::streamsize n) - { - using namespace std; - std::streamsize result = - (std::min) (n, static_cast(cur_line_.size())); - traits_type::copy(s, cur_line_.data(), result); - cur_line_.erase(0, result); - return result; - } - - // Attempts to retrieve a line of text from the given source; returns - // an int_type as a good/eof/would_block status code. - template - typename traits_type::int_type next_line(Source& src) - { - using namespace std; - typename traits_type::int_type c; - while ( traits_type::is_good(c = iostreams::get(src)) && - c != traits_type::newline() ) - { - cur_line_ += traits_type::to_int_type(c); - } - if (!traits_type::would_block(c)) { - if (!cur_line_.empty() || c == traits_type::newline()) - cur_line_ = do_filter(cur_line_); - if (c == traits_type::newline() && (flags_ & f_suppress) == 0) - cur_line_ += c; - } - return c; // status indicator. - } - - // Filters the current line and attemps to write it to the given sink. - // Returns true for success. - template - bool write_line(Sink& snk) - { - string_type line = do_filter(cur_line_); - if ((flags_ & f_suppress) == 0) - line += traits_type::newline(); - std::streamsize amt = static_cast(line.size()); - bool result = iostreams::write_if(snk, line.data(), amt) == amt; - if (result) - clear(); - return result; - } - - void close_impl() - { - clear(); - flags_ &= f_suppress; - } - - void clear() - { - cur_line_.erase(); - pos_ = string_type::npos; - } - - enum flag_type { - f_read = 1, - f_write = f_read << 1, - f_suppress = f_write << 1 - }; - - string_type cur_line_; - typename string_type::size_type pos_; - int flags_; -}; -BOOST_IOSTREAMS_PIPABLE(basic_line_filter, 2) - -typedef basic_line_filter line_filter; -typedef basic_line_filter wline_filter; - -} } // End namespaces iostreams, boost. - -#include - -#endif // #ifndef BOOST_IOSTREAMS_LINE_FILTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/newline.hpp b/boost/iostreams/filter/newline.hpp deleted file mode 100644 index 88c4afe2..00000000 --- a/boost/iostreams/filter/newline.hpp +++ /dev/null @@ -1,443 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -// NOTE: I hope to replace the current implementation with a much simpler -// one. - -#ifndef BOOST_IOSTREAMS_NEWLINE_FILTER_HPP_INCLUDED -#define BOOST_IOSTREAMS_NEWLINE_FILTER_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#include -#include // logic_error. -#include // BOOST_STATIC_CONSTANT. -#include -#include -#include // BOOST_IOSTREAMS_FAILURE -#include // get -#include // put -#include -#include -#include -#include -#include - -// Must come last. -#include - -#define BOOST_IOSTREAMS_ASSERT_UNREACHABLE(val) \ - (BOOST_ASSERT("unreachable code" == 0), val) \ - /**/ - -namespace boost { namespace iostreams { - -namespace newline { - -const char CR = 0x0D; -const char LF = 0x0A; - - // Flags for configuring newline_filter. - -// Exactly one of the following three flags must be present. - -const int posix = 1; // Use CR as line separator. -const int mac = 2; // Use LF as line separator. -const int dos = 4; // Use CRLF as line separator. -const int mixed = 8; // Mixed line endings. -const int final_newline = 16; -const int platform_mask = posix | dos | mac; - -} // End namespace newline. - -namespace detail { - -class newline_base { -public: - bool is_posix() const - { - return !is_mixed() && (flags_ & newline::posix) != 0; - } - bool is_dos() const - { - return !is_mixed() && (flags_ & newline::dos) != 0; - } - bool is_mac() const - { - return !is_mixed() && (flags_ & newline::mac) != 0; - } - bool is_mixed_posix() const { return (flags_ & newline::posix) != 0; } - bool is_mixed_dos() const { return (flags_ & newline::dos) != 0; } - bool is_mixed_mac() const { return (flags_ & newline::mac) != 0; } - bool is_mixed() const - { - int platform = - (flags_ & newline::posix) != 0 ? - newline::posix : - (flags_ & newline::dos) != 0 ? - newline::dos : - (flags_ & newline::mac) != 0 ? - newline::mac : - 0; - return (flags_ & ~platform & newline::platform_mask) != 0; - } - bool has_final_newline() const - { - return (flags_ & newline::final_newline) != 0; - } -protected: - newline_base(int flags) : flags_(flags) { } - int flags_; -}; - -} // End namespace detail. - -class newline_error - : public BOOST_IOSTREAMS_FAILURE, public detail::newline_base -{ -private: - friend class newline_checker; - newline_error(int flags) - : BOOST_IOSTREAMS_FAILURE("bad line endings"), - detail::newline_base(flags) - { } -}; - -class newline_filter { -public: - typedef char char_type; - struct category - : dual_use, - filter_tag, - closable_tag - { }; - - explicit newline_filter(int target) : flags_(target) - { - if ( target != iostreams::newline::posix && - target != iostreams::newline::dos && - target != iostreams::newline::mac ) - { - boost::throw_exception(std::logic_error("bad flags")); - } - } - - template - int get(Source& src) - { - using iostreams::newline::CR; - using iostreams::newline::LF; - - BOOST_ASSERT((flags_ & f_write) == 0); - flags_ |= f_read; - - if (flags_ & (f_has_LF | f_has_EOF)) { - if (flags_ & f_has_LF) - return newline(); - else - return EOF; - } - - int c = - (flags_ & f_has_CR) == 0 ? - iostreams::get(src) : - CR; - - if (c == WOULD_BLOCK ) - return WOULD_BLOCK; - - if (c == CR) { - flags_ |= f_has_CR; - - int d = iostreams::get(src); - if (d == WOULD_BLOCK) - return WOULD_BLOCK; - - if (d == LF) { - flags_ &= ~f_has_CR; - return newline(); - } - - if (d == EOF) { - flags_ |= f_has_EOF; - } else { - iostreams::putback(src, d); - } - - flags_ &= ~f_has_CR; - return newline(); - } - - if (c == LF) - return newline(); - - return c; - } - - template - bool put(Sink& dest, char c) - { - using iostreams::newline::CR; - using iostreams::newline::LF; - - BOOST_ASSERT((flags_ & f_read) == 0); - flags_ |= f_write; - - if ((flags_ & f_has_LF) != 0) - return c == LF ? - newline(dest) : - newline(dest) && this->put(dest, c); - - if (c == LF) - return newline(dest); - - if ((flags_ & f_has_CR) != 0) - return newline(dest) ? - this->put(dest, c) : - false; - - if (c == CR) { - flags_ |= f_has_CR; - return true; - } - - return iostreams::put(dest, c); - } - - template - void close(Sink& dest, BOOST_IOS::openmode) - { - if ((flags_ & f_write) != 0 && (flags_ & f_has_CR) != 0) - newline_if_sink(dest); - flags_ &= ~f_has_LF; // Restore original flags. - } -private: - - // Returns the appropriate element of a newline sequence. - int newline() - { - using iostreams::newline::CR; - using iostreams::newline::LF; - - switch (flags_ & iostreams::newline::platform_mask) { - case iostreams::newline::posix: - return LF; - case iostreams::newline::mac: - return CR; - case iostreams::newline::dos: - if (flags_ & f_has_LF) { - flags_ &= ~f_has_LF; - return LF; - } else { - flags_ |= f_has_LF; - return CR; - } - } - return BOOST_IOSTREAMS_ASSERT_UNREACHABLE(0); - } - - // Writes a newline sequence. - template - bool newline(Sink& dest) - { - using iostreams::newline::CR; - using iostreams::newline::LF; - - bool success = false; - switch (flags_ & iostreams::newline::platform_mask) { - case iostreams::newline::posix: - success = boost::iostreams::put(dest, LF); - break; - case iostreams::newline::mac: - success = boost::iostreams::put(dest, CR); - break; - case iostreams::newline::dos: - if ((flags_ & f_has_LF) != 0) { - success = boost::iostreams::put(dest, LF); - if (success) - flags_ &= ~f_has_LF; - } else if (boost::iostreams::put(dest, CR)) { - success = boost::iostreams::put(dest, LF); - if (!success) - flags_ |= f_has_LF; - } - break; - } - if (success) - flags_ &= ~f_has_CR; - return success; - } - - // Writes a newline sequence if the given device is a Sink. - template - void newline_if_sink(Device& dest) - { - typedef typename iostreams::category_of::type category; - newline_if_sink(dest, is_convertible()); - } - - template - void newline_if_sink(Sink& dest, mpl::true_) { newline(dest); } - - template - void newline_if_sink(Source&, mpl::false_) { } - - enum flags { - f_has_LF = 32768, - f_has_CR = f_has_LF << 1, - f_has_newline = f_has_CR << 1, - f_has_EOF = f_has_newline << 1, - f_read = f_has_EOF << 1, - f_write = f_read << 1 - }; - int flags_; -}; -BOOST_IOSTREAMS_PIPABLE(newline_filter, 0) - -class newline_checker : public detail::newline_base { -public: - typedef char char_type; - struct category - : dual_use_filter_tag, - closable_tag - { }; - explicit newline_checker(int target = newline::mixed) - : detail::newline_base(0), target_(target), open_(false) - { } - template - int get(Source& src) - { - using newline::CR; - using newline::LF; - - if (!open_) { - open_ = true; - source() = 0; - } - - int c; - if ((c = iostreams::get(src)) == WOULD_BLOCK) - return WOULD_BLOCK; - - // Update source flags. - if (c != EOF) - source() &= ~f_line_complete; - if ((source() & f_has_CR) != 0) { - if (c == LF) { - source() |= newline::dos; - source() |= f_line_complete; - } else { - source() |= newline::mac; - if (c == EOF) - source() |= f_line_complete; - } - } else if (c == LF) { - source() |= newline::posix; - source() |= f_line_complete; - } - source() = (source() & ~f_has_CR) | (c == CR ? f_has_CR : 0); - - // Check for errors. - if ( c == EOF && - (target_ & newline::final_newline) != 0 && - (source() & f_line_complete) == 0 ) - { - fail(); - } - if ( (target_ & newline::platform_mask) != 0 && - (source() & ~target_ & newline::platform_mask) != 0 ) - { - fail(); - } - - return c; - } - - template - bool put(Sink& dest, int c) - { - using iostreams::newline::CR; - using iostreams::newline::LF; - - if (!open_) { - open_ = true; - source() = 0; - } - - if (!iostreams::put(dest, c)) - return false; - - // Update source flags. - source() &= ~f_line_complete; - if ((source() & f_has_CR) != 0) { - if (c == LF) { - source() |= newline::dos; - source() |= f_line_complete; - } else { - source() |= newline::mac; - } - } else if (c == LF) { - source() |= newline::posix; - source() |= f_line_complete; - } - source() = (source() & ~f_has_CR) | (c == CR ? f_has_CR : 0); - - // Check for errors. - if ( (target_ & newline::platform_mask) != 0 && - (source() & ~target_ & newline::platform_mask) != 0 ) - { - fail(); - } - - return true; - } - - template - void close(Sink&, BOOST_IOS::openmode) - { - using iostreams::newline::final_newline; - - // Update final_newline flag. - if ( (source() & f_has_CR) != 0 || - (source() & f_line_complete) != 0 ) - { - source() |= final_newline; - } - - // Clear non-sticky flags. - source() &= ~(f_has_CR | f_line_complete); - - // Check for errors. - if ( (target_ & final_newline) != 0 && - (source() & final_newline) == 0 ) - { - fail(); - } - } -private: - void fail() { boost::throw_exception(newline_error(source())); } - int& source() { return flags_; } - int source() const { return flags_; } - - enum flags { - f_has_CR = 32768, - f_line_complete = f_has_CR << 1 - }; - - int target_; // Represents expected input. - bool open_; -}; -BOOST_IOSTREAMS_PIPABLE(newline_checker, 0) - -} } // End namespaces iostreams, boost. - -#include - -#endif // #ifndef BOOST_IOSTREAMS_NEWLINE_FILTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/regex.hpp b/boost/iostreams/filter/regex.hpp deleted file mode 100644 index e943553c..00000000 --- a/boost/iostreams/filter/regex.hpp +++ /dev/null @@ -1,98 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED -#define BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // allocator. -#include -#include -#include -#include - -namespace boost { namespace iostreams { - -template< typename Ch, - typename Tr = regex_traits, - typename Alloc = std::allocator > -class basic_regex_filter : public aggregate_filter { -private: - typedef aggregate_filter base_type; -public: - typedef typename base_type::char_type char_type; - typedef typename base_type::category category; - typedef std::basic_string string_type; - typedef basic_regex regex_type; - typedef regex_constants::match_flag_type flag_type; - typedef match_results match_type; - typedef function1 formatter; - - basic_regex_filter( const regex_type& re, - const formatter& replace, - flag_type flags = regex_constants::match_default ) - : re_(re), replace_(replace), flags_(flags) { } - basic_regex_filter( const regex_type& re, - const string_type& fmt, - flag_type flags = regex_constants::match_default, - flag_type fmt_flags = regex_constants::format_default ) - : re_(re), replace_(simple_formatter(fmt, fmt_flags)), flags_(flags) { } - basic_regex_filter( const regex_type& re, - const char_type* fmt, - flag_type flags = regex_constants::match_default, - flag_type fmt_flags = regex_constants::format_default ) - : re_(re), replace_(simple_formatter(fmt, fmt_flags)), flags_(flags) { } -private: - typedef typename base_type::vector_type vector_type; - void do_filter(const vector_type& src, vector_type& dest) - { - typedef regex_iterator iterator; - if (src.empty()) - return; - iterator first(&src[0], &src[0] + src.size(), re_, flags_); - iterator last; - const Ch* suffix = 0; - for (; first != last; ++first) { - dest.insert( dest.end(), - first->prefix().first, - first->prefix().second ); - string_type replacement = replace_(*first); - dest.insert( dest.end(), - replacement.begin(), - replacement.end() ); - suffix = first->suffix().first; - } - if (suffix) { - dest.insert(dest.end(), suffix, &src[0] + src.size()); - } else { - dest.insert(dest.end(), &src[0], &src[0] + src.size()); - } - } - struct simple_formatter { - simple_formatter(const string_type& fmt, flag_type fmt_flags) - : fmt_(fmt), fmt_flags_(fmt_flags) { } - string_type operator() (const match_type& match) const - { return match.format(fmt_, fmt_flags_); } - string_type fmt_; - flag_type fmt_flags_; - }; - regex_type re_; - formatter replace_; - flag_type flags_; -}; -BOOST_IOSTREAMS_PIPABLE(basic_regex_filter, 3) - -typedef basic_regex_filter regex_filter; -typedef basic_regex_filter wregex_filter; - - -} } // End namespaces iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/stdio.hpp b/boost/iostreams/filter/stdio.hpp deleted file mode 100644 index 5ad921b2..00000000 --- a/boost/iostreams/filter/stdio.hpp +++ /dev/null @@ -1,84 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2005-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -// Based on the work of Christopher Diggins. - -#ifndef BOOST_IOSTREAMS_STDIO_FILTER_HPP_INCLUDED -#define BOOST_IOSTREAMS_STDIO_FILTER_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#include // allocator. -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace iostreams { - -namespace detail { - -} // End namespace detail. - -template > -class basic_stdio_filter : public aggregate_filter { -private: - typedef aggregate_filter base_type; -public: - typedef typename base_type::char_type char_type; - typedef typename base_type::category category; - typedef typename base_type::vector_type vector_type; -private: - static std::istream& standard_input(char*) { return std::cin; } - static std::ostream& standard_output(char*) { return std::cout; } -#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS - static std::wistream& standard_input(wchar_t*) { return std::wcin; } - static std::wostream& standard_output(wchar_t*) { return std::wcout; } -#endif // BOOST_IOSTREAMS_NO_WIDE_STREAMS - - struct scoped_redirector { // Thanks to Maxim Egorushkin. - typedef BOOST_IOSTREAMS_CHAR_TRAITS(Ch) traits_type; - typedef BOOST_IOSTREAMS_BASIC_IOS(Ch, traits_type) ios_type; - typedef BOOST_IOSTREAMS_BASIC_STREAMBUF(Ch, traits_type) streambuf_type; - scoped_redirector( ios_type& ios, - streambuf_type* newbuf ) - : ios_(ios), old_(ios.rdbuf(newbuf)) - { } - ~scoped_redirector() { ios_.rdbuf(old_); } - scoped_redirector& operator=(const scoped_redirector&); - ios_type& ios_; - streambuf_type* old_; - }; - - virtual void do_filter() = 0; - virtual void do_filter(const vector_type& src, vector_type& dest) - { - stream_buffer< basic_array_source > - srcbuf(&src[0], &src[0] + src.size()); - stream_buffer< back_insert_device > - destbuf(iostreams::back_inserter(dest)); - scoped_redirector redirect_input(standard_input((Ch*)0), &srcbuf); - scoped_redirector redirect_output(standard_output((Ch*)0), &destbuf); - do_filter(); - } -}; -BOOST_IOSTREAMS_PIPABLE(basic_stdio_filter, 2) - -typedef basic_stdio_filter stdio_filter; -typedef basic_stdio_filter wstdio_wfilter; - -} } // End namespaces iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_STDIO_FILTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/test.hpp b/boost/iostreams/filter/test.hpp deleted file mode 100644 index c5039c84..00000000 --- a/boost/iostreams/filter/test.hpp +++ /dev/null @@ -1,319 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2005-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_FILTER_TEST_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // BOOST_MSVC,put size_t in std. -#include -#include // min. -#include // size_t. -#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) || \ - BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \ - /**/ -# include // rand. -#endif -#include // memcpy, strlen. -#include -#include -#include -#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) && \ - !BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \ - /**/ -# include -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef memcpy -#undef rand -#undef strlen - -#if defined(BOOST_NO_STDC_NAMESPACE) && !defined(__LIBCOMO__) -namespace std { - using ::memcpy; - using ::strlen; - #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) || \ - BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \ - /**/ - using ::rand; - #endif -} -#endif - -namespace boost { namespace iostreams { - -BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_string, std::basic_string, 3) - -const std::streamsize default_increment = 5; - -#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) && \ - !BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \ - /**/ - std::streamsize rand(std::streamsize inc) - { - static rand48 random_gen; - static uniform_smallint random_dist(0, static_cast(inc)); - return random_dist(random_gen); - } -#else - std::streamsize rand(std::streamsize inc) - { - return (std::rand() * inc + 1) / RAND_MAX; - } -#endif - -class non_blocking_source { -public: - typedef char char_type; - struct category - : source_tag, - peekable_tag - { }; - explicit non_blocking_source( const std::string& data, - std::streamsize inc = default_increment ) - : data_(data), inc_(inc), pos_(0) - { } - std::streamsize read(char* s, std::streamsize n) - { - using namespace std; - if (pos_ == static_cast(data_.size())) - return -1; - streamsize avail = - (std::min) (n, static_cast(data_.size() - pos_)); - streamsize amt = (std::min) (rand(inc_), avail); - if (amt) - memcpy(s, data_.c_str() + pos_, static_cast(amt)); - pos_ += amt; - return amt; - } - - bool putback(char c) - { - if (pos_ > 0) { - data_[static_cast(--pos_)] = c; - return true; - } - return false; - } -private: - std::string data_; - std::streamsize inc_, pos_; -}; - -class non_blocking_sink : public sink { -public: - non_blocking_sink( std::string& dest, - std::streamsize inc = default_increment ) - : dest_(dest), inc_(inc) - { } - std::streamsize write(const char* s, std::streamsize n) - { - std::streamsize amt = (std::min) (rand(inc_), n); - dest_.insert(dest_.end(), s, s + amt); - return amt; - } -private: - non_blocking_sink& operator=(const non_blocking_sink&); - std::string& dest_; - std::streamsize inc_; -}; - -//--------------Definition of test_input_filter-------------------------------// - -template -bool test_input_filter( Filter filter, - const std::string& input, - const std::string& output, - mpl::true_ ) -{ - for ( int inc = default_increment; - inc < default_increment * 40; - inc += default_increment ) - { - non_blocking_source src(input, inc); - std::string dest; - iostreams::copy(compose(filter, src), iostreams::back_inserter(dest)); - if (dest != output) - return false; - } - return true; -} - -template -bool test_input_filter( Filter filter, - const Source1& input, - const Source2& output, - mpl::false_ ) -{ - std::string in; - std::string out; - iostreams::copy(input, iostreams::back_inserter(in)); - iostreams::copy(output, iostreams::back_inserter(out)); - return test_input_filter(filter, in, out); -} - -template -bool test_input_filter( Filter filter, - const Source1& input, - const Source2& output ) -{ - // Use tag dispatch to compensate for bad overload resolution. - return test_input_filter( filter, input, output, - is_string() ); -} - -//--------------Definition of test_output_filter------------------------------// - -template -bool test_output_filter( Filter filter, - const std::string& input, - const std::string& output, - mpl::true_ ) -{ - for ( int inc = default_increment; - inc < default_increment * 40; - inc += default_increment ) - { - array_source src(input.data(), input.data() + input.size()); - std::string dest; - iostreams::copy(src, compose(filter, non_blocking_sink(dest, inc))); - if (dest != output ) - return false; - } - return true; -} - -template -bool test_output_filter( Filter filter, - const Source1& input, - const Source2& output, - mpl::false_ ) -{ - std::string in; - std::string out; - iostreams::copy(input, iostreams::back_inserter(in)); - iostreams::copy(output, iostreams::back_inserter(out)); - return test_output_filter(filter, in, out); -} - -template -bool test_output_filter( Filter filter, - const Source1& input, - const Source2& output ) -{ - // Use tag dispatch to compensate for bad overload resolution. - return test_output_filter( filter, input, output, - is_string() ); -} - -//--------------Definition of test_filter_pair--------------------------------// - -template -bool test_filter_pair( OutputFilter out, - InputFilter in, - const std::string& data, - mpl::true_ ) -{ - for ( int inc = default_increment; - inc <= default_increment * 40; - inc += default_increment ) - { - { - array_source src(data.data(), data.data() + data.size()); - std::string temp; - std::string dest; - iostreams::copy(src, compose(out, non_blocking_sink(temp, inc))); - iostreams::copy( - compose(in, non_blocking_source(temp, inc)), - iostreams::back_inserter(dest) - ); - if (dest != data) - return false; - } - { - array_source src(data.data(), data.data() + data.size()); - std::string temp; - std::string dest; - iostreams::copy(src, compose(out, non_blocking_sink(temp, inc))); - // truncate the file, this should not loop, it may throw - // std::ios_base::failure, which we swallow. - try { - temp.resize(temp.size() / 2); - iostreams::copy( - compose(in, non_blocking_source(temp, inc)), - iostreams::back_inserter(dest) - ); - } catch(std::ios_base::failure&) {} - } - { - array_source src(data.data(), data.data() + data.size()); - std::string temp; - std::string dest; - iostreams::copy(compose(out, src), non_blocking_sink(temp, inc)); - iostreams::copy( - non_blocking_source(temp, inc), - compose(in, iostreams::back_inserter(dest)) - ); - if (dest != data) - return false; - } - { - array_source src(data.data(), data.data() + data.size()); - std::string temp; - std::string dest; - iostreams::copy(compose(out, src), non_blocking_sink(temp, inc)); - // truncate the file, this should not loop, it may throw - // std::ios_base::failure, which we swallow. - try { - temp.resize(temp.size() / 2); - iostreams::copy( - non_blocking_source(temp, inc), - compose(in, iostreams::back_inserter(dest)) - ); - } catch(std::ios_base::failure&) {} - } - } - return true; -} - -template -bool test_filter_pair( OutputFilter out, - InputFilter in, - const Source& data, - mpl::false_ ) -{ - std::string str; - iostreams::copy(data, iostreams::back_inserter(str)); - return test_filter_pair(out, in, str); -} - -template -bool test_filter_pair( OutputFilter out, - InputFilter in, - const Source& data ) -{ - // Use tag dispatch to compensate for bad overload resolution. - return test_filter_pair(out, in, data, is_string()); -} - -} } // End namespaces iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_FILTER_TEST_HPP_INCLUDED diff --git a/boost/iostreams/filtering_stream.hpp b/boost/iostreams/filtering_stream.hpp deleted file mode 100644 index 8621ef96..00000000 --- a/boost/iostreams/filtering_stream.hpp +++ /dev/null @@ -1,187 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2004-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_FILTER_STREAM_HPP_INCLUDED -#define BOOST_IOSTREAMS_FILTER_STREAM_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // allocator. -#include -#include -#include // standard streams. -#include -#include -#include // pubsync. -#include -#include -#include -#include -#include - -// Must come last. -#include // MSVC. - -namespace boost { namespace iostreams { - -//--------------Definition of filtered_istream--------------------------------// - -namespace detail { - -template -struct filtering_stream_traits { - typedef typename - iostreams::select< // Disambiguation for Tru64 - mpl::and_< - is_convertible, - is_convertible - >, - BOOST_IOSTREAMS_BASIC_IOSTREAM(Ch, Tr), - is_convertible, - BOOST_IOSTREAMS_BASIC_ISTREAM(Ch, Tr), - else_, - BOOST_IOSTREAMS_BASIC_OSTREAM(Ch, Tr) - >::type stream_type; - typedef typename - iostreams::select< // Dismbiguation required for Tru64. - mpl::and_< - is_convertible, - is_convertible - >, - iostream_tag, - is_convertible, - istream_tag, - else_, - ostream_tag - >::type stream_tag; -}; - -#if defined(BOOST_MSVC) && (BOOST_MSVC == 1700) -# pragma warning(push) -// https://connect.microsoft.com/VisualStudio/feedback/details/733720/ -# pragma warning(disable: 4250) -#endif - -template -class filtering_stream_base - : public access_control< - boost::iostreams::detail::chain_client, - Access - >, - public filtering_stream_traits< - typename Chain::mode, - typename Chain::char_type, - typename Chain::traits_type - >::stream_type -{ -public: - typedef Chain chain_type; - typedef access_control< - boost::iostreams::detail::chain_client, - Access - > client_type; -protected: - typedef typename - filtering_stream_traits< - typename Chain::mode, - typename Chain::char_type, - typename Chain::traits_type - >::stream_type stream_type; - filtering_stream_base() : stream_type(0) { this->set_chain(&chain_); } -private: - void notify() { this->rdbuf(chain_.empty() ? 0 : &chain_.front()); } - Chain chain_; -}; - -#if defined(BOOST_MSVC) && (BOOST_MSVC == 1700) -# pragma warning(pop) -#endif - -} // End namespace detail. - -// -// Macro: BOOST_IOSTREAMS_DEFINE_FILTER_STREAM(name_, chain_type_, default_char_) -// Description: Defines a template derived from std::basic_streambuf which uses -// a chain to perform i/o. The template has the following parameters: -// Mode - the i/o mode. -// Ch - The character type. -// Tr - The character traits type. -// Alloc - The allocator type. -// Access - Indicates accessibility of the chain interface; must be either -// public_ or protected_; defaults to public_. -// Macro parameters: -// name_ - The name of the template to be defined. -// chain_type_ - The name of the chain template. -// default_char_ - The default value for the char template parameter. -// -#define BOOST_IOSTREAMS_DEFINE_FILTER_STREAM(name_, chain_type_, default_char_) \ - template< typename Mode, \ - typename Ch = default_char_, \ - typename Tr = BOOST_IOSTREAMS_CHAR_TRAITS(Ch), \ - typename Alloc = std::allocator, \ - typename Access = public_ > \ - class name_ \ - : public boost::iostreams::detail::filtering_stream_base< \ - chain_type_, Access \ - > \ - { \ - public: \ - typedef Ch char_type; \ - struct category \ - : Mode, \ - closable_tag, \ - detail::filtering_stream_traits::stream_tag \ - { }; \ - BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) \ - typedef Mode mode; \ - typedef chain_type_ chain_type; \ - name_() { } \ - BOOST_IOSTREAMS_DEFINE_PUSH_CONSTRUCTOR(name_, mode, Ch, push_impl) \ - ~name_() { \ - if (this->is_complete()) \ - this->rdbuf()->BOOST_IOSTREAMS_PUBSYNC(); \ - } \ - private: \ - typedef access_control< \ - boost::iostreams::detail::chain_client< \ - chain_type_ \ - >, \ - Access \ - > client_type; \ - template \ - void push_impl(const T& t BOOST_IOSTREAMS_PUSH_PARAMS()) \ - { client_type::push(t BOOST_IOSTREAMS_PUSH_ARGS()); } \ - }; \ - /**/ - -#if defined(BOOST_MSVC) && (BOOST_MSVC == 1700) -# pragma warning(push) -// https://connect.microsoft.com/VisualStudio/feedback/details/733720/ -# pragma warning(disable: 4250) -#endif - -BOOST_IOSTREAMS_DEFINE_FILTER_STREAM(filtering_stream, boost::iostreams::chain, char) -BOOST_IOSTREAMS_DEFINE_FILTER_STREAM(wfiltering_stream, boost::iostreams::chain, wchar_t) - -#if defined(BOOST_MSVC) && (BOOST_MSVC == 1700) -# pragma warning(pop) -#endif - -typedef filtering_stream filtering_istream; -typedef filtering_stream filtering_ostream; -typedef wfiltering_stream filtering_wistream; -typedef wfiltering_stream filtering_wostream; - -//----------------------------------------------------------------------------// - -} } // End namespace iostreams, boost - -#include // MSVC - -#endif // #ifndef BOOST_IOSTREAMS_FILTER_STREAM_HPP_INCLUDED diff --git a/boost/iostreams/filtering_streambuf.hpp b/boost/iostreams/filtering_streambuf.hpp deleted file mode 100644 index affe4a71..00000000 --- a/boost/iostreams/filtering_streambuf.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_FILTERING_STREAMBUF_HPP_INCLUDED -#define BOOST_IOSTREAMS_FILTERING_STREAMBUF_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#include // allocator. -#include -#include -#include -#include -#include // pubsync. -#include -#include - -namespace boost { namespace iostreams { - -// -// Macro: BOOST_IOSTREAMS_DEFINE_FILTERBUF(name_, chain_type_, default_char_) -// Description: Defines a template derived from std::basic_streambuf which uses -// a chain to perform i/o. The template has the following parameters: -// Ch - The character type. -// Tr - The character traits type. -// Alloc - The allocator type. -// Access - Indicates accessibility of the chain interface; must be either -// public_ or protected_; defaults to public_. -// -#define BOOST_IOSTREAMS_DEFINE_FILTER_STREAMBUF(name_, chain_type_, default_char_) \ - template< typename Mode, \ - typename Ch = default_char_, \ - typename Tr = BOOST_IOSTREAMS_CHAR_TRAITS(Ch), \ - typename Alloc = std::allocator, \ - typename Access = public_ > \ - class name_ : public boost::iostreams::detail::chainbuf< \ - chain_type_, Mode, Access \ - > \ - { \ - public: \ - typedef Ch char_type; \ - struct category \ - : Mode, closable_tag, streambuf_tag \ - { }; \ - BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) \ - typedef Mode mode; \ - typedef chain_type_ chain_type; \ - name_() { } \ - BOOST_IOSTREAMS_DEFINE_PUSH_CONSTRUCTOR(name_, mode, Ch, push_impl) \ - ~name_() { if (this->is_complete()) this->BOOST_IOSTREAMS_PUBSYNC(); } \ - }; \ - /**/ -BOOST_IOSTREAMS_DEFINE_FILTER_STREAMBUF(filtering_streambuf, boost::iostreams::chain, char) -BOOST_IOSTREAMS_DEFINE_FILTER_STREAMBUF(filtering_wstreambuf, boost::iostreams::chain, wchar_t) - -typedef filtering_streambuf filtering_istreambuf; -typedef filtering_streambuf filtering_ostreambuf; -typedef filtering_wstreambuf filtering_wistreambuf; -typedef filtering_wstreambuf filtering_wostreambuf; - -} } // End namespaces iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_FILTERING_STREAMBUF_HPP_INCLUDED diff --git a/boost/iostreams/invert.hpp b/boost/iostreams/invert.hpp deleted file mode 100644 index d4a17bf7..00000000 --- a/boost/iostreams/invert.hpp +++ /dev/null @@ -1,167 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_INVERT_HPP_INCLUDED -#define BOOST_IOSTREAMS_INVERT_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include // copy, min. -#include -#include // BOOST_DEDUCED_TYPENAME. -#include // default_filter_buffer_size. -#include -#include -#include -#include -#include -#include -#include -#include // clear_flags, call_reset -#include -#include -#include -#include - -// Must come last. -#include // MSVC. - -namespace boost { namespace iostreams { - -// -// Template name: inverse. -// Template parameters: -// Filter - A model of InputFilter or OutputFilter. -// Description: Generates an InputFilter from an OutputFilter or -// vice versa. -// -template -class inverse { -private: - BOOST_STATIC_ASSERT(is_filter::value); - typedef typename category_of::type base_category; - typedef reference_wrapper filter_ref; -public: - typedef typename char_type_of::type char_type; - typedef typename int_type_of::type int_type; - typedef char_traits traits_type; - typedef typename - mpl::if_< - is_convertible< - base_category, - input - >, - output, - input - >::type mode; - struct category - : mode, - filter_tag, - multichar_tag, - closable_tag - { }; - explicit inverse( const Filter& filter, - std::streamsize buffer_size = - default_filter_buffer_size) - : pimpl_(new impl(filter, buffer_size)) - { } - - template - std::streamsize read(Source& src, char_type* s, std::streamsize n) - { - typedef detail::counted_array_sink array_sink; - typedef composite filtered_array_sink; - - BOOST_ASSERT((flags() & f_write) == 0); - if (flags() == 0) { - flags() = f_read; - buf().set(0, 0); - } - - filtered_array_sink snk(filter(), array_sink(s, n)); - int_type status; - for ( status = traits_type::good(); - snk.second().count() < n && status == traits_type::good(); ) - { - status = buf().fill(src); - buf().flush(snk); - } - return snk.second().count() == 0 && - status == traits_type::eof() - ? - -1 - : - snk.second().count(); - } - - template - std::streamsize write(Sink& dest, const char_type* s, std::streamsize n) - { - typedef detail::counted_array_source array_source; - typedef composite filtered_array_source; - - BOOST_ASSERT((flags() & f_read) == 0); - if (flags() == 0) { - flags() = f_write; - buf().set(0, 0); - } - - filtered_array_source src(filter(), array_source(s, n)); - for (bool good = true; src.second().count() < n && good; ) { - buf().fill(src); - good = buf().flush(dest); - } - return src.second().count(); - } - - template - void close(Device& dev) - { - detail::execute_all( - detail::flush_buffer(buf(), dev, (flags() & f_write) != 0), - detail::call_close_all(pimpl_->filter_, dev), - detail::clear_flags(flags()) - ); - } -private: - filter_ref filter() { return boost::ref(pimpl_->filter_); } - detail::buffer& buf() { return pimpl_->buf_; } - int& flags() { return pimpl_->flags_; } - - enum flags_ { - f_read = 1, f_write = 2 - }; - - struct impl { - impl(const Filter& filter, std::streamsize n) - : filter_(filter), buf_(n), flags_(0) - { buf_.set(0, 0); } - Filter filter_; - detail::buffer buf_; - int flags_; - }; - shared_ptr pimpl_; -}; - -// -// Template name: invert. -// Template parameters: -// Filter - A model of InputFilter or OutputFilter. -// Description: Returns an instance of an appropriate specialization of inverse. -// -template -inverse invert(const Filter& f) { return inverse(f); } - -//----------------------------------------------------------------------------// - -} } // End namespaces iostreams, boost. - -#include // MSVC. - -#endif // #ifndef BOOST_IOSTREAMS_INVERT_HPP_INCLUDED diff --git a/boost/iostreams/restrict.hpp b/boost/iostreams/restrict.hpp deleted file mode 100644 index e17eb8c9..00000000 --- a/boost/iostreams/restrict.hpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - * - * File: boost/iostreams/detail/restrict.hpp - * Date: Sun Jan 06 12:57:30 MST 2008 - * Copyright: 2008 CodeRage, LLC - 2004-2007 Jonathan Turkanis - * Author: Jonathan Turkanis - * Contact: turkanis at coderage dot com - * - * Defines the class template boost::iostreams::restriction and the - * overloaded function template boost::iostreams::restrict - */ - -#ifndef BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED -#define BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED - -#include -#define BOOST_IOSTREAMS_RESTRICT restrict -#include -#undef BOOST_IOSTREAMS_RESTRICT - -#endif // #ifndef BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED diff --git a/boost/iostreams/skip.hpp b/boost/iostreams/skip.hpp deleted file mode 100644 index eb097dd7..00000000 --- a/boost/iostreams/skip.hpp +++ /dev/null @@ -1,112 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2003-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -// To do: handle bidirection streams and output-seekable components. - -#ifndef BOOST_IOSTREAMS_SKIP_HPP_INCLUDED -#define BOOST_IOSTREAMS_SKIP_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#include // failure. -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace iostreams { - -namespace detail { - -template -void skip(Device& dev, stream_offset off, mpl::true_) -{ iostreams::seek(dev, off, BOOST_IOS::cur); } - -template -void skip(Device& dev, stream_offset off, mpl::false_) -{ // gcc 2.95 needs namespace qualification for char_traits. - typedef typename char_type_of::type char_type; - typedef iostreams::char_traits traits_type; - for (stream_offset z = 0; z < off; ) { - typename traits_type::int_type c; - if (traits_type::is_eof(c = iostreams::get(dev))) - boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad skip offset")); - if (!traits_type::would_block(c)) - ++z; - } -} - -template -void skip( Filter& flt, Device& dev, stream_offset off, - BOOST_IOS::openmode which, mpl::true_ ) -{ boost::iostreams::seek(flt, dev, off, BOOST_IOS::cur, which); } - -template -void skip( Filter& flt, Device& dev, stream_offset off, - BOOST_IOS::openmode, mpl::false_ ) -{ - typedef typename char_type_of::type char_type; - char_type c; - for (stream_offset z = 0; z < off; ) { - std::streamsize amt; - if ((amt = iostreams::read(flt, dev, &c, 1)) == -1) - boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad skip offset")); - if (amt == 1) - ++z; - } -} - -} // End namespace detail. - -template -void skip(Device& dev, stream_offset off) -{ - typedef typename mode_of::type mode; - typedef mpl::or_< - is_convertible, - is_convertible - > can_seek; - BOOST_STATIC_ASSERT( - (can_seek::value || is_convertible::value) - ); - detail::skip(dev, off, can_seek()); -} - -template -void skip( Filter& flt, Device& dev, stream_offset off, - BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out ) -{ - typedef typename mode_of::type filter_mode; - typedef typename mode_of::type device_mode; - typedef mpl::or_< - mpl::and_< - is_convertible, - is_convertible - >, - mpl::and_< - is_convertible, - is_convertible - > - > can_seek; - BOOST_STATIC_ASSERT( - ( can_seek::value || - (is_convertible::value && - is_convertible::value) ) - ); - detail::skip(flt, dev, off, which, can_seek()); -} - -} } // End namespaces iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_SKIP_HPP_INCLUDED //------------------------// diff --git a/boost/iostreams/slice.hpp b/boost/iostreams/slice.hpp deleted file mode 100644 index 820a316f..00000000 --- a/boost/iostreams/slice.hpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - * - * File: boost/iostreams/detail/restrict.hpp - * Date: Sun Jan 06 12:57:30 MST 2008 - * Copyright: 2008 CodeRage, LLC - 2004-2007 Jonathan Turkanis - * Author: Jonathan Turkanis - * Contact: turkanis at coderage dot com - * - * Defines the class template boost::iostreams::restriction and the - * overloaded function template boost::iostreams::slice. - * - * This header is provided for platforms on which "restrict" is a keyword. - */ - -#ifndef BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED -#define BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED - -#include -#define BOOST_IOSTREAMS_RESTRICT slice -#include -#undef BOOST_IOSTREAMS_RESTRICT - -#endif // #ifndef BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED diff --git a/boost/iostreams/tee.hpp b/boost/iostreams/tee.hpp deleted file mode 100644 index 6df85e9b..00000000 --- a/boost/iostreams/tee.hpp +++ /dev/null @@ -1,232 +0,0 @@ -// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) -// (C) Copyright 2005-2007 Jonathan Turkanis -// Distributed under the Boost Software License, Version 1.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/iostreams for documentation. - -#ifndef BOOST_IOSTREAMS_TEE_HPP_INCLUDED -#define BOOST_IOSTREAMS_TEE_HPP_INCLUDED - -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#include // BOOST_DEDUCE_TYPENAME. -#include -#include -#include -#include -#include -#include // call_close_all -#include -#include -#include -#include -#include -#include - -namespace boost { namespace iostreams { - -// -// Template name: tee_filter. -// Template parameters: -// Device - A blocking Sink. -// -template -class tee_filter : public detail::filter_adapter { -public: - typedef typename detail::param_type::type param_type; - typedef typename char_type_of::type char_type; - struct category - : dual_use_filter_tag, - multichar_tag, - closable_tag, - flushable_tag, - localizable_tag, - optimally_buffered_tag - { }; - - BOOST_STATIC_ASSERT(is_device::value); - BOOST_STATIC_ASSERT(( - is_convertible< // Using mode_of causes failures on VC6-7.0. - BOOST_DEDUCED_TYPENAME iostreams::category_of::type, output - >::value - )); - - explicit tee_filter(param_type dev) - : detail::filter_adapter(dev) - { } - - template - std::streamsize read(Source& src, char_type* s, std::streamsize n) - { - std::streamsize result = iostreams::read(src, s, n); - if (result != -1) { - std::streamsize result2 = iostreams::write(this->component(), s, result); - (void) result2; // Suppress 'unused variable' warning. - BOOST_ASSERT(result == result2); - } - return result; - } - - template - std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) - { - std::streamsize result = iostreams::write(snk, s, n); - std::streamsize result2 = iostreams::write(this->component(), s, result); - (void) result2; // Suppress 'unused variable' warning. - BOOST_ASSERT(result == result2); - return result; - } - - template - void close(Next&, BOOST_IOS::openmode) - { - detail::close_all(this->component()); - } - - template - bool flush(Sink& snk) - { - bool r1 = iostreams::flush(snk); - bool r2 = iostreams::flush(this->component()); - return r1 && r2; - } -}; -BOOST_IOSTREAMS_PIPABLE(tee_filter, 1) - -// -// Template name: tee_device. -// Template parameters: -// Device - A blocking Device. -// Sink - A blocking Sink. -// -template -class tee_device { -public: - typedef typename detail::param_type::type device_param; - typedef typename detail::param_type::type sink_param; - typedef typename detail::value_type::type device_value; - typedef typename detail::value_type::type sink_value; - typedef typename char_type_of::type char_type; - typedef typename - mpl::if_< - is_convertible< - BOOST_DEDUCED_TYPENAME - iostreams::category_of::type, - output - >, - output, - input - >::type mode; - BOOST_STATIC_ASSERT(is_device::value); - BOOST_STATIC_ASSERT(is_device::value); - BOOST_STATIC_ASSERT(( - is_same< - char_type, - BOOST_DEDUCED_TYPENAME char_type_of::type - >::value - )); - BOOST_STATIC_ASSERT(( - is_convertible< - BOOST_DEDUCED_TYPENAME iostreams::category_of::type, - output - >::value - )); - struct category - : mode, - device_tag, - closable_tag, - flushable_tag, - localizable_tag, - optimally_buffered_tag - { }; - tee_device(device_param device, sink_param sink) - : dev_(device), sink_(sink) - { } - std::streamsize read(char_type* s, std::streamsize n) - { - BOOST_STATIC_ASSERT(( - is_convertible< - BOOST_DEDUCED_TYPENAME iostreams::category_of::type, input - >::value - )); - std::streamsize result1 = iostreams::read(dev_, s, n); - if (result1 != -1) { - std::streamsize result2 = iostreams::write(sink_, s, result1); - (void) result1; // Suppress 'unused variable' warning. - (void) result2; - BOOST_ASSERT(result1 == result2); - } - return result1; - } - std::streamsize write(const char_type* s, std::streamsize n) - { - BOOST_STATIC_ASSERT(( - is_convertible< - BOOST_DEDUCED_TYPENAME iostreams::category_of::type, output - >::value - )); - std::streamsize result1 = iostreams::write(dev_, s, n); - std::streamsize result2 = iostreams::write(sink_, s, n); - (void) result1; // Suppress 'unused variable' warning. - (void) result2; - BOOST_ASSERT(result1 == n && result2 == n); - return n; - } - void close() - { - detail::execute_all( detail::call_close_all(dev_), - detail::call_close_all(sink_) ); - } - bool flush() - { - bool r1 = iostreams::flush(dev_); - bool r2 = iostreams::flush(sink_); - return r1 && r2; - } - template - void imbue(const Locale& loc) - { - iostreams::imbue(dev_, loc); - iostreams::imbue(sink_, loc); - } - std::streamsize optimal_buffer_size() const - { - return (std::max) ( iostreams::optimal_buffer_size(dev_), - iostreams::optimal_buffer_size(sink_) ); - } -private: - device_value dev_; - sink_value sink_; -}; - -template -tee_filter tee(Sink& snk) -{ return tee_filter(snk); } - -template -tee_filter tee(const Sink& snk) -{ return tee_filter(snk); } - -template -tee_device tee(Device& dev, Sink& sink) -{ return tee_device(dev, sink); } - -template -tee_device tee(const Device& dev, Sink& sink) -{ return tee_device(dev, sink); } - -template -tee_device tee(Device& dev, const Sink& sink) -{ return tee_device(dev, sink); } - -template -tee_device tee(const Device& dev, const Sink& sink) -{ return tee_device(dev, sink); } - -} } // End namespaces iostreams, boost. - -#endif // #ifndef BOOST_IOSTREAMS_TEE_HPP_INCLUDED diff --git a/boost/mpl/O1_size.hpp b/boost/mpl/O1_size.hpp new file mode 100644 index 00000000..98bd3a74 --- /dev/null +++ b/boost/mpl/O1_size.hpp @@ -0,0 +1,40 @@ + +#ifndef BOOST_MPL_O1_SIZE_HPP_INCLUDED +#define BOOST_MPL_O1_SIZE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +// returns sequence size if it's an O(1) operation; otherwise returns -1 +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + > +struct O1_size + : O1_size_impl< typename sequence_tag::type > + ::template apply< Sequence > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1, O1_size, (Sequence)) +}; + +BOOST_MPL_AUX_NA_SPEC(1, O1_size) + +}} + +#endif // BOOST_MPL_O1_SIZE_HPP_INCLUDED diff --git a/boost/mpl/O1_size_fwd.hpp b/boost/mpl/O1_size_fwd.hpp new file mode 100644 index 00000000..c84a7a56 --- /dev/null +++ b/boost/mpl/O1_size_fwd.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_O1_SIZE_FWD_HPP_INCLUDED +#define BOOST_MPL_O1_SIZE_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +namespace boost { namespace mpl { + +template< typename Tag > struct O1_size_impl; +template< typename Sequence > struct O1_size; + +}} + +#endif // BOOST_MPL_O1_SIZE_FWD_HPP_INCLUDED diff --git a/boost/mpl/advance.hpp b/boost/mpl/advance.hpp new file mode 100644 index 00000000..1af60041 --- /dev/null +++ b/boost/mpl/advance.hpp @@ -0,0 +1,76 @@ + +#ifndef BOOST_MPL_ADVANCE_HPP_INCLUDED +#define BOOST_MPL_ADVANCE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +// default implementation for forward/bidirectional iterators +template< typename Tag > +struct advance_impl +{ + template< typename Iterator, typename N > struct apply + { + typedef typename less< N,long_<0> >::type backward_; + typedef typename if_< backward_, negate, N >::type offset_; + + typedef typename if_< + backward_ + , aux::advance_backward< BOOST_MPL_AUX_VALUE_WKND(offset_)::value > + , aux::advance_forward< BOOST_MPL_AUX_VALUE_WKND(offset_)::value > + >::type f_; + + typedef typename apply_wrap1::type type; + }; +}; + + +template< + typename BOOST_MPL_AUX_NA_PARAM(Iterator) + , typename BOOST_MPL_AUX_NA_PARAM(N) + > +struct advance + : advance_impl< typename tag::type > + ::template apply +{ +}; + +template< + typename Iterator + , BOOST_MPL_AUX_NTTP_DECL(long, N) + > +struct advance_c + : advance_impl< typename tag::type > + ::template apply > +{ +}; + +BOOST_MPL_AUX_NA_SPEC(2, advance) + +}} + +#endif // BOOST_MPL_ADVANCE_HPP_INCLUDED diff --git a/boost/mpl/advance_fwd.hpp b/boost/mpl/advance_fwd.hpp new file mode 100644 index 00000000..80384101 --- /dev/null +++ b/boost/mpl/advance_fwd.hpp @@ -0,0 +1,28 @@ + +#ifndef BOOST_MPL_ADVANCE_FWD_HPP_INCLUDED +#define BOOST_MPL_ADVANCE_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include + +namespace boost { namespace mpl { + +BOOST_MPL_AUX_COMMON_NAME_WKND(advance) + +template< typename Tag > struct advance_impl; +template< typename Iterator, typename N > struct advance; + +}} + +#endif // BOOST_MPL_ADVANCE_FWD_HPP_INCLUDED diff --git a/boost/mpl/aux_/O1_size_impl.hpp b/boost/mpl/aux_/O1_size_impl.hpp new file mode 100644 index 00000000..3bcbd0f7 --- /dev/null +++ b/boost/mpl/aux_/O1_size_impl.hpp @@ -0,0 +1,87 @@ + +#ifndef BOOST_MPL_O1_SIZE_IMPL_HPP_INCLUDED +#define BOOST_MPL_O1_SIZE_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +// default implementation - returns 'Sequence::size' if sequence has a 'size' +// member, and -1 otherwise; conrete sequences might override it by +// specializing either the 'O1_size_impl' or the primary 'O1_size' template + +# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) \ + && !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) + +namespace aux { +template< typename Sequence > struct O1_size_impl + : Sequence::size +{ +}; +} + +template< typename Tag > +struct O1_size_impl +{ + template< typename Sequence > struct apply +#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) + : if_< + aux::has_size + , aux::O1_size_impl + , long_<-1> + >::type + { +#else + { + typedef typename if_< + aux::has_size + , aux::O1_size_impl + , long_<-1> + >::type type; + + BOOST_STATIC_CONSTANT(long, value = + (if_< + aux::has_size + , aux::O1_size_impl + , long_<-1> + >::type::value) + ); +#endif + }; +}; + +# else // BOOST_MSVC + +template< typename Tag > +struct O1_size_impl +{ + template< typename Sequence > struct apply + : long_<-1> + { + }; +}; + +# endif + +}} + +#endif // BOOST_MPL_O1_SIZE_IMPL_HPP_INCLUDED diff --git a/boost/mpl/aux_/advance_backward.hpp b/boost/mpl/aux_/advance_backward.hpp new file mode 100644 index 00000000..df567932 --- /dev/null +++ b/boost/mpl/aux_/advance_backward.hpp @@ -0,0 +1,128 @@ + +#if !defined(BOOST_PP_IS_ITERATING) + +///// header body + +#ifndef BOOST_MPL_AUX778076_ADVANCE_BACKWARD_HPP_INCLUDED +#define BOOST_MPL_AUX778076_ADVANCE_BACKWARD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +# include +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER advance_backward.hpp +# include + +#else + +# include +# include +# include + +# include +# include +# include + +namespace boost { namespace mpl { namespace aux { + +// forward declaration +template< BOOST_MPL_AUX_NTTP_DECL(long, N) > struct advance_backward; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(0, BOOST_MPL_LIMIT_UNROLLING, )) +# include BOOST_PP_ITERATE() + +// implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING +template< BOOST_MPL_AUX_NTTP_DECL(long, N) > +struct advance_backward +{ + template< typename Iterator > struct apply + { + typedef typename apply_wrap1< + advance_backward + , Iterator + >::type chunk_result_; + + typedef typename apply_wrap1< + advance_backward<( + (N - BOOST_MPL_LIMIT_UNROLLING) < 0 + ? 0 + : N - BOOST_MPL_LIMIT_UNROLLING + )> + , chunk_result_ + >::type type; + }; +}; + +}}} + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#endif // BOOST_MPL_AUX778076_ADVANCE_BACKWARD_HPP_INCLUDED + +///// iteration, depth == 1 + +// For gcc 4.4 compatability, we must include the +// BOOST_PP_ITERATION_DEPTH test inside an #else clause. +#else // BOOST_PP_IS_ITERATING +#if BOOST_PP_ITERATION_DEPTH() == 1 +#define i_ BOOST_PP_FRAME_ITERATION(1) + +template<> +struct advance_backward< BOOST_PP_FRAME_ITERATION(1) > +{ + template< typename Iterator > struct apply + { + typedef Iterator iter0; + +#if i_ > 0 +# define BOOST_PP_ITERATION_PARAMS_2 \ + (3,(1, BOOST_PP_FRAME_ITERATION(1), )) +# include BOOST_PP_ITERATE() +#endif + + typedef BOOST_PP_CAT(iter,BOOST_PP_FRAME_ITERATION(1)) type; + }; + +#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) + /// ETI workaround + template<> struct apply + { + typedef int type; + }; +#endif +}; + +#undef i_ + +///// iteration, depth == 2 + +#elif BOOST_PP_ITERATION_DEPTH() == 2 + +# define AUX778076_ITER_0 BOOST_PP_CAT(iter,BOOST_PP_DEC(BOOST_PP_FRAME_ITERATION(2))) +# define AUX778076_ITER_1 BOOST_PP_CAT(iter,BOOST_PP_FRAME_ITERATION(2)) + + typedef typename prior::type AUX778076_ITER_1; + +# undef AUX778076_ITER_1 +# undef AUX778076_ITER_0 + +#endif // BOOST_PP_ITERATION_DEPTH() +#endif // BOOST_PP_IS_ITERATING diff --git a/boost/mpl/aux_/advance_forward.hpp b/boost/mpl/aux_/advance_forward.hpp new file mode 100644 index 00000000..62b0101c --- /dev/null +++ b/boost/mpl/aux_/advance_forward.hpp @@ -0,0 +1,127 @@ + +#if !defined(BOOST_PP_IS_ITERATING) + +///// header body + +#ifndef BOOST_MPL_AUX_ADVANCE_FORWARD_HPP_INCLUDED +#define BOOST_MPL_AUX_ADVANCE_FORWARD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +# include +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER advance_forward.hpp +# include + +#else + +# include +# include +# include + +# include +# include +# include + +namespace boost { namespace mpl { namespace aux { + +// forward declaration +template< BOOST_MPL_AUX_NTTP_DECL(long, N) > struct advance_forward; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(0, BOOST_MPL_LIMIT_UNROLLING, )) +# include BOOST_PP_ITERATE() + +// implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING +template< BOOST_MPL_AUX_NTTP_DECL(long, N) > +struct advance_forward +{ + template< typename Iterator > struct apply + { + typedef typename apply_wrap1< + advance_forward + , Iterator + >::type chunk_result_; + + typedef typename apply_wrap1< + advance_forward<( + (N - BOOST_MPL_LIMIT_UNROLLING) < 0 + ? 0 + : N - BOOST_MPL_LIMIT_UNROLLING + )> + , chunk_result_ + >::type type; + }; +}; + +}}} + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#endif // BOOST_MPL_AUX_ADVANCE_FORWARD_HPP_INCLUDED + +///// iteration, depth == 1 + +// For gcc 4.4 compatability, we must include the +// BOOST_PP_ITERATION_DEPTH test inside an #else clause. +#else // BOOST_PP_IS_ITERATING +#if BOOST_PP_ITERATION_DEPTH() == 1 +#define i_ BOOST_PP_FRAME_ITERATION(1) + +template<> +struct advance_forward< BOOST_PP_FRAME_ITERATION(1) > +{ + template< typename Iterator > struct apply + { + typedef Iterator iter0; + +#if i_ > 0 +# define BOOST_PP_ITERATION_PARAMS_2 \ + (3,(1, i_, )) +# include BOOST_PP_ITERATE() +#endif + typedef BOOST_PP_CAT(iter,i_) type; + }; + +#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) + /// ETI workaround + template<> struct apply + { + typedef int type; + }; +#endif +}; + +#undef i_ + +///// iteration, depth == 2 + +#elif BOOST_PP_ITERATION_DEPTH() == 2 + +# define AUX778076_ITER_0 BOOST_PP_CAT(iter,BOOST_PP_DEC(BOOST_PP_FRAME_ITERATION(2))) +# define AUX778076_ITER_1 BOOST_PP_CAT(iter,BOOST_PP_FRAME_ITERATION(2)) + + typedef typename next::type AUX778076_ITER_1; + +# undef AUX778076_ITER_1 +# undef AUX778076_ITER_0 + +#endif // BOOST_PP_ITERATION_DEPTH() +#endif // BOOST_PP_IS_ITERATING diff --git a/boost/mpl/aux_/begin_end_impl.hpp b/boost/mpl/aux_/begin_end_impl.hpp new file mode 100644 index 00000000..58b70dd1 --- /dev/null +++ b/boost/mpl/aux_/begin_end_impl.hpp @@ -0,0 +1,101 @@ + +#ifndef BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + + +namespace aux { + +template< typename Sequence > +struct begin_type +{ + typedef typename Sequence::begin type; +}; +template< typename Sequence > +struct end_type +{ + typedef typename Sequence::end type; +}; + +} + +// default implementation; conrete sequences might override it by +// specializing either the 'begin_impl/end_impl' or the primary +// 'begin/end' templates + +template< typename Tag > +struct begin_impl +{ + template< typename Sequence > struct apply + { + typedef typename eval_if, + aux::begin_type, void_>::type type; + }; +}; + +template< typename Tag > +struct end_impl +{ + template< typename Sequence > struct apply + { + typedef typename eval_if, + aux::end_type, void_>::type type; + }; +}; + +// specialize 'begin_trait/end_trait' for two pre-defined tags + +# define AUX778076_IMPL_SPEC(name, tag, result) \ +template<> \ +struct name##_impl \ +{ \ + template< typename Sequence > struct apply \ + { \ + typedef result type; \ + }; \ +}; \ +/**/ + +// a sequence with nested 'begin/end' typedefs; just query them +AUX778076_IMPL_SPEC(begin, nested_begin_end_tag, typename Sequence::begin) +AUX778076_IMPL_SPEC(end, nested_begin_end_tag, typename Sequence::end) + +// if a type 'T' does not contain 'begin/end' or 'tag' members +// and doesn't specialize either 'begin/end' or 'begin_impl/end_impl' +// templates, then we end up here +AUX778076_IMPL_SPEC(begin, non_sequence_tag, void_) +AUX778076_IMPL_SPEC(end, non_sequence_tag, void_) +AUX778076_IMPL_SPEC(begin, na, void_) +AUX778076_IMPL_SPEC(end, na, void_) + +# undef AUX778076_IMPL_SPEC + + +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(1,begin_impl) +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(1,end_impl) + +}} + +#endif // BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED diff --git a/boost/mpl/aux_/clear_impl.hpp b/boost/mpl/aux_/clear_impl.hpp new file mode 100644 index 00000000..20b270c0 --- /dev/null +++ b/boost/mpl/aux_/clear_impl.hpp @@ -0,0 +1,35 @@ + +#ifndef BOOST_MPL_AUX_CLEAR_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_CLEAR_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include + +namespace boost { namespace mpl { + +// no default implementation; the definition is needed to make MSVC happy + +template< typename Tag > +struct clear_impl +{ + template< typename Sequence > struct apply; +}; + +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1, clear_impl) + +}} + +#endif // BOOST_MPL_AUX_CLEAR_IMPL_HPP_INCLUDED diff --git a/boost/mpl/aux_/empty_impl.hpp b/boost/mpl/aux_/empty_impl.hpp new file mode 100644 index 00000000..cfe55ae2 --- /dev/null +++ b/boost/mpl/aux_/empty_impl.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_MPL_AUX_EMPTY_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_EMPTY_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include + +namespace boost { namespace mpl { + +// default implementation; conrete sequences might override it by +// specializing either the 'empty_impl' or the primary 'empty' template + +template< typename Tag > +struct empty_impl +{ + template< typename Sequence > struct apply + : is_same< + typename begin::type + , typename end::type + > + { + }; +}; + +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1,empty_impl) + +}} + +#endif // BOOST_MPL_AUX_EMPTY_IMPL_HPP_INCLUDED diff --git a/boost/mpl/aux_/find_if_pred.hpp b/boost/mpl/aux_/find_if_pred.hpp new file mode 100644 index 00000000..c07d89d6 --- /dev/null +++ b/boost/mpl/aux_/find_if_pred.hpp @@ -0,0 +1,31 @@ + +#ifndef BOOST_MPL_AUX_FIND_IF_PRED_HPP_INCLUDED +#define BOOST_MPL_AUX_FIND_IF_PRED_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// Copyright Eric Friedman 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) +// +// See http://www.boost.org/libs/mpl for documentation. + +#include +#include + +namespace boost { namespace mpl { namespace aux { + +template< typename Predicate > +struct find_if_pred +{ + template< typename Iterator > + struct apply + { + typedef not_< aux::iter_apply1 > type; + }; +}; + +}}} + +#endif // BOOST_MPL_AUX_FIND_IF_PRED_HPP_INCLUDED diff --git a/boost/mpl/aux_/fold_impl.hpp b/boost/mpl/aux_/fold_impl.hpp new file mode 100644 index 00000000..97c88c5b --- /dev/null +++ b/boost/mpl/aux_/fold_impl.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_MPL_AUX_FOLD_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_FOLD_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +# include +# include +# include +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +# include +# include +# endif +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER fold_impl.hpp +# include + +#else + +# define AUX778076_FOLD_IMPL_OP(iter) typename deref::type +# define AUX778076_FOLD_IMPL_NAME_PREFIX fold +# include + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#endif // BOOST_MPL_AUX_FOLD_IMPL_HPP_INCLUDED diff --git a/boost/mpl/aux_/fold_impl_body.hpp b/boost/mpl/aux_/fold_impl_body.hpp new file mode 100644 index 00000000..c5e16601 --- /dev/null +++ b/boost/mpl/aux_/fold_impl_body.hpp @@ -0,0 +1,365 @@ + +// NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION + +#if !defined(BOOST_PP_IS_ITERATING) + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +# include +# include +# include +# include +# include +# include + +# include +# include +# include + +// local macros, #undef-ined at the end of the header + +# define AUX778076_ITER_FOLD_STEP(unused, i, unused2) \ + typedef typename apply2< \ + ForwardOp \ + , BOOST_PP_CAT(state,i) \ + , AUX778076_FOLD_IMPL_OP(BOOST_PP_CAT(iter,i)) \ + >::type BOOST_PP_CAT(state,BOOST_PP_INC(i)); \ + typedef typename mpl::next::type \ + BOOST_PP_CAT(iter,BOOST_PP_INC(i)); \ + /**/ + +# define AUX778076_FOLD_IMPL_NAME \ + BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_impl) \ + /**/ + +# define AUX778076_FOLD_CHUNK_NAME \ + BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_chunk) \ + /**/ + +namespace boost { namespace mpl { namespace aux { + +/// forward declaration +template< + BOOST_MPL_AUX_NTTP_DECL(int, N) + , typename First + , typename Last + , typename State + , typename ForwardOp + > +struct AUX778076_FOLD_IMPL_NAME; + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +# if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(0, BOOST_MPL_LIMIT_UNROLLING, )) +# include BOOST_PP_ITERATE() + +// implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING +template< + BOOST_MPL_AUX_NTTP_DECL(int, N) + , typename First + , typename Last + , typename State + , typename ForwardOp + > +struct AUX778076_FOLD_IMPL_NAME +{ + typedef AUX778076_FOLD_IMPL_NAME< + BOOST_MPL_LIMIT_UNROLLING + , First + , Last + , State + , ForwardOp + > chunk_; + + typedef AUX778076_FOLD_IMPL_NAME< + ( (N - BOOST_MPL_LIMIT_UNROLLING) < 0 ? 0 : N - BOOST_MPL_LIMIT_UNROLLING ) + , typename chunk_::iterator + , Last + , typename chunk_::state + , ForwardOp + > res_; + + typedef typename res_::state state; + typedef typename res_::iterator iterator; +}; + +// fallback implementation for sequences of unknown size +template< + typename First + , typename Last + , typename State + , typename ForwardOp + > +struct AUX778076_FOLD_IMPL_NAME<-1,First,Last,State,ForwardOp> + : AUX778076_FOLD_IMPL_NAME< + -1 + , typename mpl::next::type + , Last + , typename apply2::type + , ForwardOp + > +{ +}; + +template< + typename Last + , typename State + , typename ForwardOp + > +struct AUX778076_FOLD_IMPL_NAME<-1,Last,Last,State,ForwardOp> +{ + typedef State state; + typedef Last iterator; +}; + +# else // BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) + +// Borland have some serious problems with the unrolled version, so +// we always use a basic implementation +template< + BOOST_MPL_AUX_NTTP_DECL(int, N) + , typename First + , typename Last + , typename State + , typename ForwardOp + > +struct AUX778076_FOLD_IMPL_NAME +{ + typedef AUX778076_FOLD_IMPL_NAME< + -1 + , typename mpl::next::type + , Last + , typename apply2::type + , ForwardOp + > res_; + + typedef typename res_::state state; + typedef typename res_::iterator iterator; + typedef state type; +}; + +template< + BOOST_MPL_AUX_NTTP_DECL(int, N) + , typename Last + , typename State + , typename ForwardOp + > +struct AUX778076_FOLD_IMPL_NAME +{ + typedef State state; + typedef Last iterator; + typedef state type; +}; + +# endif // BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) + +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +template< BOOST_MPL_AUX_NTTP_DECL(int, N) > +struct AUX778076_FOLD_CHUNK_NAME; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(0, BOOST_MPL_LIMIT_UNROLLING, )) +# include BOOST_PP_ITERATE() + +// implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING +template< BOOST_MPL_AUX_NTTP_DECL(int, N) > +struct AUX778076_FOLD_CHUNK_NAME +{ + template< + typename First + , typename Last + , typename State + , typename ForwardOp + > + struct result_ + { + typedef AUX778076_FOLD_IMPL_NAME< + BOOST_MPL_LIMIT_UNROLLING + , First + , Last + , State + , ForwardOp + > chunk_; + + typedef AUX778076_FOLD_IMPL_NAME< + ( (N - BOOST_MPL_LIMIT_UNROLLING) < 0 ? 0 : N - BOOST_MPL_LIMIT_UNROLLING ) + , typename chunk_::iterator + , Last + , typename chunk_::state + , ForwardOp + > res_; + + typedef typename res_::state state; + typedef typename res_::iterator iterator; + }; +}; + +// fallback implementation for sequences of unknown size +template< + typename First + , typename Last + , typename State + , typename ForwardOp + > +struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step); + +template< + typename Last + , typename State + > +struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_null_step) +{ + typedef Last iterator; + typedef State state; +}; + +template<> +struct AUX778076_FOLD_CHUNK_NAME<-1> +{ + template< + typename First + , typename Last + , typename State + , typename ForwardOp + > + struct result_ + { + typedef typename if_< + typename is_same::type + , BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_null_step) + , BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step) + >::type res_; + + typedef typename res_::state state; + typedef typename res_::iterator iterator; + }; + +#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) + /// ETI workaround + template<> struct result_ + { + typedef int state; + typedef int iterator; + }; +#endif +}; + +template< + typename First + , typename Last + , typename State + , typename ForwardOp + > +struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step) +{ + // can't inherit here - it breaks MSVC 7.0 + typedef AUX778076_FOLD_CHUNK_NAME<-1>::template result_< + typename mpl::next::type + , Last + , typename apply2::type + , ForwardOp + > chunk_; + + typedef typename chunk_::state state; + typedef typename chunk_::iterator iterator; +}; + +template< + BOOST_MPL_AUX_NTTP_DECL(int, N) + , typename First + , typename Last + , typename State + , typename ForwardOp + > +struct AUX778076_FOLD_IMPL_NAME + : AUX778076_FOLD_CHUNK_NAME + ::template result_ +{ +}; + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +}}} + +# undef AUX778076_FOLD_IMPL_NAME +# undef AUX778076_FOLD_CHUNK_NAME +# undef AUX778076_ITER_FOLD_STEP + +#undef AUX778076_FOLD_IMPL_OP +#undef AUX778076_FOLD_IMPL_NAME_PREFIX + +///// iteration + +#else + +# define n_ BOOST_PP_FRAME_ITERATION(1) + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template< + typename First + , typename Last + , typename State + , typename ForwardOp + > +struct AUX778076_FOLD_IMPL_NAME +{ + typedef First iter0; + typedef State state0; + + BOOST_MPL_PP_REPEAT(n_, AUX778076_ITER_FOLD_STEP, unused) + + typedef BOOST_PP_CAT(state,n_) state; + typedef BOOST_PP_CAT(iter,n_) iterator; +}; + +#else + +template<> struct AUX778076_FOLD_CHUNK_NAME +{ + template< + typename First + , typename Last + , typename State + , typename ForwardOp + > + struct result_ + { + typedef First iter0; + typedef State state0; + + BOOST_MPL_PP_REPEAT(n_, AUX778076_ITER_FOLD_STEP, unused) + + typedef BOOST_PP_CAT(state,n_) state; + typedef BOOST_PP_CAT(iter,n_) iterator; + }; + +#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) + /// ETI workaround + template<> struct result_ + { + typedef int state; + typedef int iterator; + }; +#endif +}; + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +# undef n_ + +#endif // BOOST_PP_IS_ITERATING diff --git a/boost/mpl/aux_/front_impl.hpp b/boost/mpl/aux_/front_impl.hpp new file mode 100644 index 00000000..9493c1c4 --- /dev/null +++ b/boost/mpl/aux_/front_impl.hpp @@ -0,0 +1,41 @@ + +#ifndef BOOST_MPL_AUX_FRONT_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_FRONT_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include + +namespace boost { namespace mpl { + +// default implementation; conrete sequences might override it by +// specializing either the 'front_impl' or the primary 'front' template + +template< typename Tag > +struct front_impl +{ + template< typename Sequence > struct apply + { + typedef typename begin::type iter_; + typedef typename deref::type type; + }; +}; + +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1,front_impl) + +}} + +#endif // BOOST_MPL_AUX_FRONT_IMPL_HPP_INCLUDED diff --git a/boost/mpl/aux_/has_begin.hpp b/boost/mpl/aux_/has_begin.hpp new file mode 100644 index 00000000..4ee415cb --- /dev/null +++ b/boost/mpl/aux_/has_begin.hpp @@ -0,0 +1,23 @@ + +#ifndef BOOST_MPL_AUX_HAS_BEGIN_HPP_INCLUDED +#define BOOST_MPL_AUX_HAS_BEGIN_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2002-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include + +namespace boost { namespace mpl { namespace aux { +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_begin, begin, true) +}}} + +#endif // BOOST_MPL_AUX_HAS_BEGIN_HPP_INCLUDED diff --git a/boost/mpl/aux_/has_size.hpp b/boost/mpl/aux_/has_size.hpp new file mode 100644 index 00000000..ff29913f --- /dev/null +++ b/boost/mpl/aux_/has_size.hpp @@ -0,0 +1,23 @@ + +#ifndef BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED +#define BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2002-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include + +namespace boost { namespace mpl { namespace aux { +BOOST_MPL_HAS_XXX_TRAIT_DEF(size) +}}} + +#endif // BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED diff --git a/boost/mpl/aux_/insert_impl.hpp b/boost/mpl/aux_/insert_impl.hpp new file mode 100644 index 00000000..03a304b5 --- /dev/null +++ b/boost/mpl/aux_/insert_impl.hpp @@ -0,0 +1,68 @@ + +#ifndef BOOST_MPL_INSERT_IMPL_HPP_INCLUDED +#define BOOST_MPL_INSERT_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +// default implementation; conrete sequences might override it by +// specializing either the 'insert_impl' or the primary 'insert' template + +template< typename Tag > +struct insert_impl +{ + template< + typename Sequence + , typename Pos + , typename T + > + struct apply + { + typedef iterator_range< + typename begin::type + , Pos + > first_half_; + + typedef iterator_range< + Pos + , typename end::type + > second_half_; + + typedef typename reverse_fold< + second_half_ + , typename clear::type + , push_front<_,_> + >::type half_sequence_; + + typedef typename reverse_fold< + first_half_ + , typename push_front::type + , push_front<_,_> + >::type type; + }; +}; + +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(3,insert_impl) + +}} + +#endif // BOOST_MPL_INSERT_IMPL_HPP_INCLUDED diff --git a/boost/mpl/aux_/insert_range_impl.hpp b/boost/mpl/aux_/insert_range_impl.hpp new file mode 100644 index 00000000..fa433156 --- /dev/null +++ b/boost/mpl/aux_/insert_range_impl.hpp @@ -0,0 +1,80 @@ + +#ifndef BOOST_MPL_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { namespace mpl { + +// default implementation; conrete sequences might override it by +// specializing either the 'insert_range_impl' or the primary +// 'insert_range' template + + +template< typename Tag > +struct insert_range_impl +{ + template< + typename Sequence + , typename Pos + , typename Range + > + struct apply +#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) + : reverse_fold< + joint_view< + iterator_range::type,Pos> + , joint_view< + Range + , iterator_range::type> + > + > + , typename clear::type + , insert<_1, begin<_1>, _2> + > + { +#else + { + typedef typename reverse_fold< + joint_view< + iterator_range::type,Pos> + , joint_view< + Range + , iterator_range::type> + > + > + , typename clear::type + , insert<_1, begin<_1>, _2> + >::type type; +#endif + }; +}; + +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(3,insert_range_impl) + +}} + +#endif // BOOST_MPL_AUX_INSERT_RANGE_IMPL_HPP_INCLUDED diff --git a/boost/mpl/aux_/inserter_algorithm.hpp b/boost/mpl/aux_/inserter_algorithm.hpp new file mode 100644 index 00000000..20ae8161 --- /dev/null +++ b/boost/mpl/aux_/inserter_algorithm.hpp @@ -0,0 +1,159 @@ + +#ifndef BOOST_MPL_AUX_INSERTER_ALGORITHM_HPP_INCLUDED +#define BOOST_MPL_AUX_INSERTER_ALGORITHM_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +# define BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF(arity, name) \ +BOOST_MPL_AUX_COMMON_NAME_WKND(name) \ +template< \ + BOOST_MPL_PP_DEFAULT_PARAMS(arity, typename P, na) \ + > \ +struct name \ + : aux::name##_impl \ +{ \ +}; \ +\ +template< \ + BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), typename P) \ + > \ +struct name< BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P),na > \ + : if_< has_push_back< typename clear::type> \ + , aux::name##_impl< \ + BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \ + , back_inserter< typename clear::type > \ + > \ + , aux::reverse_##name##_impl< \ + BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \ + , front_inserter< typename clear::type > \ + > \ + >::type \ +{ \ +}; \ +\ +template< \ + BOOST_MPL_PP_DEFAULT_PARAMS(arity, typename P, na) \ + > \ +struct reverse_##name \ + : aux::reverse_##name##_impl \ +{ \ +}; \ +\ +template< \ + BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), typename P) \ + > \ +struct reverse_##name< BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P),na > \ + : if_< has_push_back \ + , aux::reverse_##name##_impl< \ + BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \ + , back_inserter< typename clear::type > \ + > \ + , aux::name##_impl< \ + BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \ + , front_inserter< typename clear::type > \ + > \ + >::type \ +{ \ +}; \ +BOOST_MPL_AUX_NA_SPEC(arity, name) \ +BOOST_MPL_AUX_NA_SPEC(arity, reverse_##name) \ +/**/ + +#else + +# define BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF(arity, name) \ +BOOST_MPL_AUX_COMMON_NAME_WKND(name) \ +template< \ + BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), typename P) \ + > \ +struct def_##name##_impl \ + : if_< has_push_back \ + , aux::name##_impl< \ + BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \ + , back_inserter< typename clear::type > \ + > \ + , aux::reverse_##name##_impl< \ + BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \ + , front_inserter< typename clear::type > \ + > \ + >::type \ +{ \ +}; \ +\ +template< \ + BOOST_MPL_PP_DEFAULT_PARAMS(arity, typename P, na) \ + > \ +struct name \ +{ \ + typedef typename eval_if< \ + is_na \ + , def_##name##_impl \ + , aux::name##_impl \ + >::type type; \ +}; \ +\ +template< \ + BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), typename P) \ + > \ +struct def_reverse_##name##_impl \ + : if_< has_push_back \ + , aux::reverse_##name##_impl< \ + BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \ + , back_inserter< typename clear::type > \ + > \ + , aux::name##_impl< \ + BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \ + , front_inserter< typename clear::type > \ + > \ + >::type \ +{ \ +}; \ +template< \ + BOOST_MPL_PP_DEFAULT_PARAMS(arity, typename P, na) \ + > \ +struct reverse_##name \ +{ \ + typedef typename eval_if< \ + is_na \ + , def_reverse_##name##_impl \ + , aux::reverse_##name##_impl \ + >::type type; \ +}; \ +BOOST_MPL_AUX_NA_SPEC(arity, name) \ +BOOST_MPL_AUX_NA_SPEC(arity, reverse_##name) \ +/**/ + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +#endif // BOOST_MPL_AUX_INSERTER_ALGORITHM_HPP_INCLUDED diff --git a/boost/mpl/aux_/iter_apply.hpp b/boost/mpl/aux_/iter_apply.hpp new file mode 100644 index 00000000..41dfdfad --- /dev/null +++ b/boost/mpl/aux_/iter_apply.hpp @@ -0,0 +1,47 @@ + +#ifndef BOOST_MPL_ITER_APPLY_HPP_INCLUDED +#define BOOST_MPL_ITER_APPLY_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2002-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include + +namespace boost { namespace mpl { namespace aux { + +template< + typename F + , typename Iterator + > +struct iter_apply1 + : apply1< F,typename deref::type > +{ +}; + +template< + typename F + , typename Iterator1 + , typename Iterator2 + > +struct iter_apply2 + : apply2< + F + , typename deref::type + , typename deref::type + > +{ +}; + +}}} + +#endif // BOOST_MPL_ITER_APPLY_HPP_INCLUDED diff --git a/boost/mpl/aux_/iter_fold_if_impl.hpp b/boost/mpl/aux_/iter_fold_if_impl.hpp new file mode 100644 index 00000000..6372e83d --- /dev/null +++ b/boost/mpl/aux_/iter_fold_if_impl.hpp @@ -0,0 +1,210 @@ + +#ifndef BOOST_MPL_AUX_ITER_FOLD_IF_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_ITER_FOLD_IF_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2001-2004 +// Copyright David Abrahams 2001-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) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +# include +# include +# include +# include +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER iter_fold_if_impl.hpp +# include + +#else + +# include +# include +# include +# include +# include +# include + +namespace boost { namespace mpl { namespace aux { + +template< typename Iterator, typename State > +struct iter_fold_if_null_step +{ + typedef State state; + typedef Iterator iterator; +}; + +template< bool > +struct iter_fold_if_step_impl +{ + template< + typename Iterator + , typename State + , typename StateOp + , typename IteratorOp + > + struct result_ + { + typedef typename apply2::type state; + typedef typename IteratorOp::type iterator; + }; +}; + +template<> +struct iter_fold_if_step_impl +{ + template< + typename Iterator + , typename State + , typename StateOp + , typename IteratorOp + > + struct result_ + { + typedef State state; + typedef Iterator iterator; + }; +}; + +// agurt, 25/jun/02: MSVC 6.5 workaround, had to get rid of inheritance +// here and in 'iter_fold_if_backward_step', because sometimes it interfered +// with the "early template instantiation bug" in _really_ ugly ways +template< + typename Iterator + , typename State + , typename ForwardOp + , typename Predicate + > +struct iter_fold_if_forward_step +{ + typedef typename apply2::type not_last; + typedef typename iter_fold_if_step_impl< + BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value + >::template result_< Iterator,State,ForwardOp,mpl::next > impl_; + + typedef typename impl_::state state; + typedef typename impl_::iterator iterator; +}; + +template< + typename Iterator + , typename State + , typename BackwardOp + , typename Predicate + > +struct iter_fold_if_backward_step +{ + typedef typename apply2::type not_last; + typedef typename iter_fold_if_step_impl< + BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value + >::template result_< Iterator,State,BackwardOp,identity > impl_; + + typedef typename impl_::state state; + typedef typename impl_::iterator iterator; +}; + + +// local macros, #undef-ined at the end of the header + +# define AUX_ITER_FOLD_FORWARD_STEP(unused, i, unused2) \ + typedef iter_fold_if_forward_step< \ + typename BOOST_PP_CAT(forward_step,i)::iterator \ + , typename BOOST_PP_CAT(forward_step,i)::state \ + , ForwardOp \ + , ForwardPredicate \ + > BOOST_PP_CAT(forward_step, BOOST_PP_INC(i)); \ + /**/ + +# define AUX_ITER_FOLD_BACKWARD_STEP_FUNC(i) \ + typedef iter_fold_if_backward_step< \ + typename BOOST_PP_CAT(forward_step,BOOST_PP_DEC(i))::iterator \ + , typename BOOST_PP_CAT(backward_step,i)::state \ + , BackwardOp \ + , BackwardPredicate \ + > BOOST_PP_CAT(backward_step,BOOST_PP_DEC(i)); \ + /**/ + +# define AUX_ITER_FOLD_BACKWARD_STEP(unused, i, unused2) \ + AUX_ITER_FOLD_BACKWARD_STEP_FUNC( \ + BOOST_PP_SUB_D(1,BOOST_MPL_LIMIT_UNROLLING,i) \ + ) \ + /**/ + +# define AUX_LAST_FORWARD_STEP \ + BOOST_PP_CAT(forward_step, BOOST_MPL_LIMIT_UNROLLING) \ + /**/ + +# define AUX_LAST_BACKWARD_STEP \ + BOOST_PP_CAT(backward_step, BOOST_MPL_LIMIT_UNROLLING) \ + /**/ + +template< + typename Iterator + , typename State + , typename ForwardOp + , typename ForwardPredicate + , typename BackwardOp + , typename BackwardPredicate + > +struct iter_fold_if_impl +{ + private: + typedef iter_fold_if_null_step forward_step0; + BOOST_PP_REPEAT( + BOOST_MPL_LIMIT_UNROLLING + , AUX_ITER_FOLD_FORWARD_STEP + , unused + ) + + typedef typename if_< + typename AUX_LAST_FORWARD_STEP::not_last + , iter_fold_if_impl< + typename AUX_LAST_FORWARD_STEP::iterator + , typename AUX_LAST_FORWARD_STEP::state + , ForwardOp + , ForwardPredicate + , BackwardOp + , BackwardPredicate + > + , iter_fold_if_null_step< + typename AUX_LAST_FORWARD_STEP::iterator + , typename AUX_LAST_FORWARD_STEP::state + > + >::type AUX_LAST_BACKWARD_STEP; + + BOOST_PP_REPEAT( + BOOST_MPL_LIMIT_UNROLLING + , AUX_ITER_FOLD_BACKWARD_STEP + , unused + ) + + public: + typedef typename backward_step0::state state; + typedef typename AUX_LAST_BACKWARD_STEP::iterator iterator; +}; + +# undef AUX_LAST_BACKWARD_STEP +# undef AUX_LAST_FORWARD_STEP +# undef AUX_ITER_FOLD_BACKWARD_STEP +# undef AUX_ITER_FOLD_BACKWARD_STEP_FUNC +# undef AUX_ITER_FOLD_FORWARD_STEP + +}}} + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#endif // BOOST_MPL_AUX_ITER_FOLD_IF_IMPL_HPP_INCLUDED diff --git a/boost/mpl/aux_/iter_fold_impl.hpp b/boost/mpl/aux_/iter_fold_impl.hpp new file mode 100644 index 00000000..b4d2922f --- /dev/null +++ b/boost/mpl/aux_/iter_fold_impl.hpp @@ -0,0 +1,42 @@ + +#ifndef BOOST_MPL_AUX_ITER_FOLD_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_ITER_FOLD_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +# include +# include +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +# include +# include +# endif +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER iter_fold_impl.hpp +# include + +#else + +# define AUX778076_FOLD_IMPL_OP(iter) iter +# define AUX778076_FOLD_IMPL_NAME_PREFIX iter_fold +# include + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#endif // BOOST_MPL_AUX_ITER_FOLD_IMPL_HPP_INCLUDED diff --git a/boost/mpl/aux_/iter_push_front.hpp b/boost/mpl/aux_/iter_push_front.hpp new file mode 100644 index 00000000..35ccc4df --- /dev/null +++ b/boost/mpl/aux_/iter_push_front.hpp @@ -0,0 +1,36 @@ + +#ifndef BOOST_MPL_ITER_PUSH_FRONT_HPP_INCLUDED +#define BOOST_MPL_ITER_PUSH_FRONT_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2002-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include + +namespace boost { namespace mpl { namespace aux { + +template< + typename Sequence + , typename Iterator + > +struct iter_push_front +{ + typedef typename push_front< + Sequence + , typename deref::type + >::type type; +}; + +}}} + +#endif // BOOST_MPL_ITER_PUSH_FRONT_HPP_INCLUDED diff --git a/boost/mpl/aux_/joint_iter.hpp b/boost/mpl/aux_/joint_iter.hpp new file mode 100644 index 00000000..277580ee --- /dev/null +++ b/boost/mpl/aux_/joint_iter.hpp @@ -0,0 +1,120 @@ + +#ifndef BOOST_MPL_AUX_JOINT_ITER_HPP_INCLUDED +#define BOOST_MPL_AUX_JOINT_ITER_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +# include +#endif + +namespace boost { namespace mpl { + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template< + typename Iterator1 + , typename LastIterator1 + , typename Iterator2 + > +struct joint_iter +{ + typedef Iterator1 base; + typedef forward_iterator_tag category; +}; + +template< + typename LastIterator1 + , typename Iterator2 + > +struct joint_iter +{ + typedef Iterator2 base; + typedef forward_iterator_tag category; +}; + + +template< typename I1, typename L1, typename I2 > +struct deref< joint_iter > +{ + typedef typename joint_iter::base base_; + typedef typename deref::type type; +}; + +template< typename I1, typename L1, typename I2 > +struct next< joint_iter > +{ + typedef joint_iter< typename mpl::next::type,L1,I2 > type; +}; + +template< typename L1, typename I2 > +struct next< joint_iter > +{ + typedef joint_iter< L1,L1,typename mpl::next::type > type; +}; + +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +template< + typename Iterator1 + , typename LastIterator1 + , typename Iterator2 + > +struct joint_iter; + +template< bool > struct joint_iter_impl +{ + template< typename I1, typename L1, typename I2 > struct result_ + { + typedef I1 base; + typedef forward_iterator_tag category; + typedef joint_iter< typename mpl::next::type,L1,I2 > next; + typedef typename deref::type type; + }; +}; + +template<> struct joint_iter_impl +{ + template< typename I1, typename L1, typename I2 > struct result_ + { + typedef I2 base; + typedef forward_iterator_tag category; + typedef joint_iter< L1,L1,typename mpl::next::type > next; + typedef typename deref::type type; + }; +}; + +template< + typename Iterator1 + , typename LastIterator1 + , typename Iterator2 + > +struct joint_iter + : joint_iter_impl< is_same::value > + ::template result_ +{ +}; + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(3, joint_iter) + +}} + +#endif // BOOST_MPL_AUX_JOINT_ITER_HPP_INCLUDED diff --git a/boost/mpl/aux_/lambda_spec.hpp b/boost/mpl/aux_/lambda_spec.hpp new file mode 100644 index 00000000..6ffacc0a --- /dev/null +++ b/boost/mpl/aux_/lambda_spec.hpp @@ -0,0 +1,49 @@ + +#ifndef BOOST_MPL_AUX_LAMBDA_SPEC_HPP_INCLUDED +#define BOOST_MPL_AUX_LAMBDA_SPEC_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2001-2007 +// +// Distributed under the Boost Software License, Version 1.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 +#include +#include +#include +#include +#include + +#if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) + +# define BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(i, name) \ +template< \ + BOOST_MPL_PP_PARAMS(i, typename T) \ + , typename Tag \ + > \ +struct lambda< \ + name< BOOST_MPL_PP_PARAMS(i, T) > \ + , Tag \ + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(int_) \ + > \ +{ \ + typedef false_ is_le; \ + typedef name< BOOST_MPL_PP_PARAMS(i, T) > result_; \ + typedef result_ type; \ +}; \ +/**/ + +#else + +# define BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(i, name) /**/ + +#endif + +#endif // BOOST_MPL_AUX_LAMBDA_SPEC_HPP_INCLUDED diff --git a/boost/mpl/aux_/msvc_type.hpp b/boost/mpl/aux_/msvc_type.hpp new file mode 100644 index 00000000..bea244f3 --- /dev/null +++ b/boost/mpl/aux_/msvc_type.hpp @@ -0,0 +1,62 @@ + +#ifndef BOOST_MPL_AUX_MSVC_TYPE_HPP_INCLUDED +#define BOOST_MPL_AUX_MSVC_TYPE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2001-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include + +namespace boost { namespace mpl { namespace aux { + +#if defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG) + +template< bool > struct msvc_type_impl +{ + template< typename T > struct result_ + { + typedef typename T::type type; + }; +}; + +template<> struct msvc_type_impl +{ + template< typename T > struct result_ + { + typedef result_ type; + }; +}; + +template< typename T > struct msvc_type + : msvc_type_impl< is_msvc_eti_arg::value > + ::template result_ +{ +}; + +#else // BOOST_MPL_CFG_MSVC_70_ETI_BUG + +template< typename T > struct msvc_type +{ + typedef typename T::type type; +}; + +template<> struct msvc_type +{ + typedef int type; +}; + +#endif + +}}} + +#endif // BOOST_MPL_AUX_MSVC_TYPE_HPP_INCLUDED diff --git a/boost/mpl/aux_/push_back_impl.hpp b/boost/mpl/aux_/push_back_impl.hpp new file mode 100644 index 00000000..27e7a604 --- /dev/null +++ b/boost/mpl/aux_/push_back_impl.hpp @@ -0,0 +1,70 @@ + +#ifndef BOOST_MPL_AUX_PUSH_BACK_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_PUSH_BACK_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-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/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { namespace mpl { + +struct has_push_back_arg {}; + +// agurt 05/feb/04: no default implementation; the stub definition is needed +// to enable the default 'has_push_back' implementation below +template< typename Tag > +struct push_back_impl +{ + template< typename Sequence, typename T > struct apply + { + // should be instantiated only in the context of 'has_push_back_impl'; + // if you've got an assert here, you are requesting a 'push_back' + // specialization that doesn't exist. + BOOST_MPL_ASSERT_MSG( + ( boost::is_same< T, has_push_back_arg >::value ) + , REQUESTED_PUSH_BACK_SPECIALIZATION_FOR_SEQUENCE_DOES_NOT_EXIST + , ( Sequence ) + ); + }; +}; + +template< typename Tag > +struct has_push_back_impl +{ + template< typename Seq > struct apply +#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) + : aux::has_type< push_back< Seq, has_push_back_arg > > + { +#else + { + typedef aux::has_type< push_back< Seq, has_push_back_arg > > type; + BOOST_STATIC_CONSTANT(bool, value = + (aux::has_type< push_back< Seq, has_push_back_arg > >::value) + ); +#endif + }; +}; + +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(2, push_back_impl) +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1, has_push_back_impl) + +}} + +#endif // BOOST_MPL_AUX_PUSH_BACK_IMPL_HPP_INCLUDED diff --git a/boost/mpl/aux_/push_front_impl.hpp b/boost/mpl/aux_/push_front_impl.hpp new file mode 100644 index 00000000..5b83ee76 --- /dev/null +++ b/boost/mpl/aux_/push_front_impl.hpp @@ -0,0 +1,71 @@ + +#ifndef BOOST_MPL_AUX_PUSH_FRONT_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_PUSH_FRONT_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-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/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { namespace mpl { + +struct has_push_front_arg {}; + +// agurt 05/feb/04: no default implementation; the stub definition is needed +// to enable the default 'has_push_front' implementation below + +template< typename Tag > +struct push_front_impl +{ + template< typename Sequence, typename T > struct apply + { + // should be instantiated only in the context of 'has_push_front_impl'; + // if you've got an assert here, you are requesting a 'push_front' + // specialization that doesn't exist. + BOOST_MPL_ASSERT_MSG( + ( boost::is_same< T, has_push_front_arg >::value ) + , REQUESTED_PUSH_FRONT_SPECIALIZATION_FOR_SEQUENCE_DOES_NOT_EXIST + , ( Sequence ) + ); + }; +}; + +template< typename Tag > +struct has_push_front_impl +{ + template< typename Seq > struct apply +#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) + : aux::has_type< push_front< Seq, has_push_front_arg > > + { +#else + { + typedef aux::has_type< push_front< Seq, has_push_front_arg > > type; + BOOST_STATIC_CONSTANT(bool, value = + (aux::has_type< push_front< Seq, has_push_front_arg > >::value) + ); +#endif + }; +}; + +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(2, push_front_impl) +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1, has_push_front_impl) + +}} + +#endif // BOOST_MPL_AUX_PUSH_FRONT_IMPL_HPP_INCLUDED diff --git a/boost/mpl/aux_/reverse_fold_impl.hpp b/boost/mpl/aux_/reverse_fold_impl.hpp new file mode 100644 index 00000000..a27a35fa --- /dev/null +++ b/boost/mpl/aux_/reverse_fold_impl.hpp @@ -0,0 +1,44 @@ + +#ifndef BOOST_MPL_AUX_REVERSE_FOLD_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_REVERSE_FOLD_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +# include +# include +# include +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + || defined(BOOST_MPL_CFG_NO_NONTYPE_TEMPLATE_PARTIAL_SPEC) +# include +# include +# endif +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER reverse_fold_impl.hpp +# include + +#else + +# define AUX778076_FOLD_IMPL_OP(iter) typename deref::type +# define AUX778076_FOLD_IMPL_NAME_PREFIX reverse_fold +# include + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#endif // BOOST_MPL_AUX_REVERSE_FOLD_IMPL_HPP_INCLUDED diff --git a/boost/mpl/aux_/reverse_fold_impl_body.hpp b/boost/mpl/aux_/reverse_fold_impl_body.hpp new file mode 100644 index 00000000..0f800106 --- /dev/null +++ b/boost/mpl/aux_/reverse_fold_impl_body.hpp @@ -0,0 +1,412 @@ + +// NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION! + +#if !defined(BOOST_PP_IS_ITERATING) + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +# include +# include +# include +# include + +# include +# include +# include +# include +# include + +// local macros, #undef-ined at the end of the header + +# define AUX778076_ITER_FOLD_FORWARD_STEP(unused, n_, unused2) \ + typedef typename apply2< \ + ForwardOp \ + , BOOST_PP_CAT(fwd_state,n_) \ + , AUX778076_FOLD_IMPL_OP(BOOST_PP_CAT(iter,n_)) \ + >::type BOOST_PP_CAT(fwd_state,BOOST_PP_INC(n_)); \ + typedef typename mpl::next::type \ + BOOST_PP_CAT(iter,BOOST_PP_INC(n_)); \ + /**/ + +# define AUX778076_ITER_FOLD_BACKWARD_STEP_FUNC(n_) \ + typedef typename apply2< \ + BackwardOp \ + , BOOST_PP_CAT(bkwd_state,n_) \ + , AUX778076_FOLD_IMPL_OP(BOOST_PP_CAT(iter,BOOST_PP_DEC(n_))) \ + >::type BOOST_PP_CAT(bkwd_state,BOOST_PP_DEC(n_)); \ + /**/ + +# define AUX778076_ITER_FOLD_BACKWARD_STEP(unused, n_, j) \ + AUX778076_ITER_FOLD_BACKWARD_STEP_FUNC( \ + BOOST_PP_SUB_D(1,j,n_) \ + ) \ + /**/ + +# define AUX778076_FIRST_BACKWARD_STATE_TYPEDEF(n_) \ + typedef typename nested_chunk::state BOOST_PP_CAT(bkwd_state,n_); + /**/ + +# define AUX778076_FOLD_IMPL_NAME \ + BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_impl) \ + /**/ + +# define AUX778076_FOLD_CHUNK_NAME \ + BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_chunk) \ + /**/ + +namespace boost { namespace mpl { namespace aux { + +/// forward declaration +template< + BOOST_MPL_AUX_NTTP_DECL(long, N) + , typename First + , typename Last + , typename State + , typename BackwardOp + , typename ForwardOp + > +struct AUX778076_FOLD_IMPL_NAME; + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_MPL_CFG_NO_NONTYPE_TEMPLATE_PARTIAL_SPEC) + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(0, BOOST_MPL_LIMIT_UNROLLING, )) +# include BOOST_PP_ITERATE() + +// implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING +template< + BOOST_MPL_AUX_NTTP_DECL(long, N) + , typename First + , typename Last + , typename State + , typename BackwardOp + , typename ForwardOp + > +struct AUX778076_FOLD_IMPL_NAME +{ + typedef First iter0; + typedef State fwd_state0; + + BOOST_MPL_PP_REPEAT( + BOOST_MPL_LIMIT_UNROLLING + , AUX778076_ITER_FOLD_FORWARD_STEP + , unused + ) + + typedef AUX778076_FOLD_IMPL_NAME< + ( (N - BOOST_MPL_LIMIT_UNROLLING) < 0 ? 0 : N - BOOST_MPL_LIMIT_UNROLLING ) + , BOOST_PP_CAT(iter,BOOST_MPL_LIMIT_UNROLLING) + , Last + , BOOST_PP_CAT(fwd_state,BOOST_MPL_LIMIT_UNROLLING) + , BackwardOp + , ForwardOp + > nested_chunk; + + AUX778076_FIRST_BACKWARD_STATE_TYPEDEF(BOOST_MPL_LIMIT_UNROLLING) + + BOOST_MPL_PP_REPEAT( + BOOST_MPL_LIMIT_UNROLLING + , AUX778076_ITER_FOLD_BACKWARD_STEP + , BOOST_MPL_LIMIT_UNROLLING + ) + + typedef bkwd_state0 state; + typedef typename nested_chunk::iterator iterator; +}; + +// fallback implementation for sequences of unknown size +template< + typename First + , typename Last + , typename State + , typename BackwardOp + , typename ForwardOp + > +struct AUX778076_FOLD_IMPL_NAME<-1,First,Last,State,BackwardOp,ForwardOp> +{ + typedef AUX778076_FOLD_IMPL_NAME< + -1 + , typename mpl::next::type + , Last + , typename apply2::type + , BackwardOp + , ForwardOp + > nested_step; + + typedef typename apply2< + BackwardOp + , typename nested_step::state + , AUX778076_FOLD_IMPL_OP(First) + >::type state; + + typedef typename nested_step::iterator iterator; +}; + +template< + typename Last + , typename State + , typename BackwardOp + , typename ForwardOp + > +struct AUX778076_FOLD_IMPL_NAME<-1,Last,Last,State,BackwardOp,ForwardOp> +{ + typedef State state; + typedef Last iterator; +}; + +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +template< BOOST_MPL_AUX_NTTP_DECL(long, N) > +struct AUX778076_FOLD_CHUNK_NAME; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(0, BOOST_MPL_LIMIT_UNROLLING, )) +# include BOOST_PP_ITERATE() + +// implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING +template< BOOST_MPL_AUX_NTTP_DECL(long, N) > +struct AUX778076_FOLD_CHUNK_NAME +{ + template< + typename First + , typename Last + , typename State + , typename BackwardOp + , typename ForwardOp + > + struct result_ + { + typedef First iter0; + typedef State fwd_state0; + + BOOST_MPL_PP_REPEAT( + BOOST_MPL_LIMIT_UNROLLING + , AUX778076_ITER_FOLD_FORWARD_STEP + , unused + ) + + typedef AUX778076_FOLD_IMPL_NAME< + ( (N - BOOST_MPL_LIMIT_UNROLLING) < 0 ? 0 : N - BOOST_MPL_LIMIT_UNROLLING ) + , BOOST_PP_CAT(iter,BOOST_MPL_LIMIT_UNROLLING) + , Last + , BOOST_PP_CAT(fwd_state,BOOST_MPL_LIMIT_UNROLLING) + , BackwardOp + , ForwardOp + > nested_chunk; + + AUX778076_FIRST_BACKWARD_STATE_TYPEDEF(BOOST_MPL_LIMIT_UNROLLING) + + BOOST_MPL_PP_REPEAT( + BOOST_MPL_LIMIT_UNROLLING + , AUX778076_ITER_FOLD_BACKWARD_STEP + , BOOST_MPL_LIMIT_UNROLLING + ) + + typedef bkwd_state0 state; + typedef typename nested_chunk::iterator iterator; + }; +}; + +// fallback implementation for sequences of unknown size +template< + typename First + , typename Last + , typename State + , typename BackwardOp + , typename ForwardOp + > +struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step); + +template< + typename Last + , typename State + > +struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_null_step) +{ + typedef Last iterator; + typedef State state; +}; + +template<> +struct AUX778076_FOLD_CHUNK_NAME<-1> +{ + template< + typename First + , typename Last + , typename State + , typename BackwardOp + , typename ForwardOp + > + struct result_ + { + typedef typename if_< + typename is_same::type + , BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_null_step) + , BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step) + >::type res_; + + typedef typename res_::state state; + typedef typename res_::iterator iterator; + }; + +#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) + /// ETI workaround + template<> struct result_ + { + typedef int state; + typedef int iterator; + }; +#endif +}; + +template< + typename First + , typename Last + , typename State + , typename BackwardOp + , typename ForwardOp + > +struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step) +{ + typedef AUX778076_FOLD_CHUNK_NAME<-1>::template result_< + typename mpl::next::type + , Last + , typename apply2::type + , BackwardOp + , ForwardOp + > nested_step; + + typedef typename apply2< + BackwardOp + , typename nested_step::state + , AUX778076_FOLD_IMPL_OP(First) + >::type state; + + typedef typename nested_step::iterator iterator; +}; + +template< + BOOST_MPL_AUX_NTTP_DECL(long, N) + , typename First + , typename Last + , typename State + , typename BackwardOp + , typename ForwardOp + > +struct AUX778076_FOLD_IMPL_NAME + : AUX778076_FOLD_CHUNK_NAME + ::template result_ +{ +}; + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +}}} + +# undef AUX778076_FIRST_BACKWARD_STATE_TYPEDEF +# undef AUX778076_ITER_FOLD_BACKWARD_STEP +# undef AUX778076_ITER_FOLD_BACKWARD_STEP_FUNC +# undef AUX778076_ITER_FOLD_FORWARD_STEP + +#undef AUX778076_FOLD_IMPL_OP +#undef AUX778076_FOLD_IMPL_NAME_PREFIX + +///// iteration + +#else + +# define n_ BOOST_PP_FRAME_ITERATION(1) + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_MPL_CFG_NO_NONTYPE_TEMPLATE_PARTIAL_SPEC) + +template< + typename First + , typename Last + , typename State + , typename BackwardOp + , typename ForwardOp + > +struct AUX778076_FOLD_IMPL_NAME +{ + typedef First iter0; + typedef State fwd_state0; + + BOOST_MPL_PP_REPEAT( + n_ + , AUX778076_ITER_FOLD_FORWARD_STEP + , unused + ) + + typedef BOOST_PP_CAT(fwd_state,n_) BOOST_PP_CAT(bkwd_state,n_); + + BOOST_MPL_PP_REPEAT( + n_ + , AUX778076_ITER_FOLD_BACKWARD_STEP + , n_ + ) + + typedef bkwd_state0 state; + typedef BOOST_PP_CAT(iter,n_) iterator; +}; + +#else + +template<> struct AUX778076_FOLD_CHUNK_NAME +{ + template< + typename First + , typename Last + , typename State + , typename BackwardOp + , typename ForwardOp + > + struct result_ + { + typedef First iter0; + typedef State fwd_state0; + + BOOST_MPL_PP_REPEAT( + n_ + , AUX778076_ITER_FOLD_FORWARD_STEP + , unused + ) + + typedef BOOST_PP_CAT(fwd_state,n_) BOOST_PP_CAT(bkwd_state,n_); + + BOOST_MPL_PP_REPEAT( + n_ + , AUX778076_ITER_FOLD_BACKWARD_STEP + , n_ + ) + + typedef bkwd_state0 state; + typedef BOOST_PP_CAT(iter,n_) iterator; + }; + +#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) + /// ETI workaround + template<> struct result_ + { + typedef int state; + typedef int iterator; + }; +#endif +}; + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +# undef n_ + +#endif // BOOST_PP_IS_ITERATING diff --git a/boost/mpl/aux_/sequence_wrapper.hpp b/boost/mpl/aux_/sequence_wrapper.hpp new file mode 100644 index 00000000..3f5e5530 --- /dev/null +++ b/boost/mpl/aux_/sequence_wrapper.hpp @@ -0,0 +1,292 @@ + +// NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION + +#if !defined(BOOST_PP_IS_ITERATING) + +///// header body + +// Copyright Aleksey Gurtovoy 2000-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/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +# include +# include +# include + +# include +# include +# include +# include +# include +# include +# include +# include + +#if defined(BOOST_MPL_PREPROCESSING_MODE) +# undef LONG_MAX +#endif + +namespace boost { namespace mpl { + +#if !defined(AUX778076_SEQUENCE_BASE_NAME) +# define AUX778076_SEQUENCE_BASE_NAME AUX778076_SEQUENCE_NAME +#endif + +#if !defined(AUX778076_SEQUENCE_INTEGRAL_WRAPPER) + +# define AUX778076_SEQUENCE_PARAM_NAME T +# define AUX778076_SEQUENCE_TEMPLATE_PARAM typename T +# define AUX778076_SEQUENCE_DEFAULT na + +# define AUX778076_SEQUENCE_NAME_N(n) \ + BOOST_PP_CAT(AUX778076_SEQUENCE_BASE_NAME,n) \ + /**/ + +# define AUX778076_SEQUENCE_PARAMS() \ + BOOST_PP_ENUM_PARAMS( \ + AUX778076_SEQUENCE_LIMIT \ + , AUX778076_SEQUENCE_TEMPLATE_PARAM \ + ) \ + /**/ + +# define AUX778076_SEQUENCE_ARGS() \ + BOOST_PP_ENUM_PARAMS( \ + AUX778076_SEQUENCE_LIMIT \ + , T \ + ) \ + /**/ + +# define AUX778076_SEQUENCE_DEFAULT_PARAMS() \ + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( \ + AUX778076_SEQUENCE_LIMIT \ + , AUX778076_SEQUENCE_TEMPLATE_PARAM \ + , AUX778076_SEQUENCE_DEFAULT \ + ) \ + /**/ + +# define AUX778076_SEQUENCE_N_PARAMS(n) \ + BOOST_PP_ENUM_PARAMS(n, AUX778076_SEQUENCE_TEMPLATE_PARAM) \ + /**/ + +# define AUX778076_SEQUENCE_N_ARGS(n) \ + BOOST_PP_ENUM_PARAMS(n, T) \ + /**/ + +# define AUX778076_SEQUENCE_N_PARTIAL_SPEC_ARGS(n) \ + BOOST_PP_ENUM_PARAMS(n, T) \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM( \ + BOOST_PP_SUB_D(1,AUX778076_SEQUENCE_LIMIT,n) \ + , BOOST_PP_TUPLE_ELEM_3_2 \ + , AUX778076_SEQUENCE_DEFAULT \ + ) \ + /**/ + +#else // AUX778076_SEQUENCE_INTEGRAL_WRAPPER + +# define AUX778076_SEQUENCE_PARAM_NAME C +# define AUX778076_SEQUENCE_TEMPLATE_PARAM BOOST_MPL_AUX_NTTP_DECL(long, C) +# define AUX778076_SEQUENCE_DEFAULT LONG_MAX + +# define AUX778076_SEQUENCE_PARAMS() \ + typename T, BOOST_PP_ENUM_PARAMS( \ + AUX778076_SEQUENCE_LIMIT \ + , AUX778076_SEQUENCE_TEMPLATE_PARAM \ + ) \ + /**/ + +# define AUX778076_SEQUENCE_ARGS() \ + T, BOOST_PP_ENUM_PARAMS( \ + AUX778076_SEQUENCE_LIMIT \ + , C \ + ) \ + /**/ + +# define AUX778076_SEQUENCE_DEFAULT_PARAMS() \ + typename T, \ + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( \ + AUX778076_SEQUENCE_LIMIT \ + , AUX778076_SEQUENCE_TEMPLATE_PARAM \ + , AUX778076_SEQUENCE_DEFAULT \ + ) \ + /**/ + +# define AUX778076_SEQUENCE_N_PARAMS(n) \ + typename T BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM_PARAMS(n, AUX778076_SEQUENCE_TEMPLATE_PARAM) \ + /**/ + +# if !defined(AUX778076_SEQUENCE_CONVERT_CN_TO) +# define AUX778076_SEQUENCE_CONVERT_CN_TO(z,n,TARGET) BOOST_PP_CAT(C,n) +# endif + +# define AUX778076_SEQUENCE_N_ARGS(n) \ + T BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM(n,AUX778076_SEQUENCE_CONVERT_CN_TO,T) \ + /**/ + +# define AUX778076_SEQUENCE_N_PARTIAL_SPEC_ARGS(n) \ + T, BOOST_PP_ENUM_PARAMS(n, C) \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM( \ + BOOST_PP_SUB_D(1,AUX778076_SEQUENCE_LIMIT,n) \ + , BOOST_PP_TUPLE_ELEM_3_2 \ + , AUX778076_SEQUENCE_DEFAULT \ + ) \ + /**/ + +#endif // AUX778076_SEQUENCE_INTEGRAL_WRAPPER + + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +// forward declaration +template< + AUX778076_SEQUENCE_DEFAULT_PARAMS() + > +struct AUX778076_SEQUENCE_NAME; +#else +namespace aux { +template< BOOST_MPL_AUX_NTTP_DECL(int, N) > +struct BOOST_PP_CAT(AUX778076_SEQUENCE_NAME,_chooser); +} +#endif + +#define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(0, AUX778076_SEQUENCE_LIMIT, )) +#include BOOST_PP_ITERATE() + +// real C++ version is already taken care of +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +namespace aux { +// ???_count_args +#define AUX778076_COUNT_ARGS_PREFIX AUX778076_SEQUENCE_NAME +#define AUX778076_COUNT_ARGS_DEFAULT AUX778076_SEQUENCE_DEFAULT +#define AUX778076_COUNT_ARGS_PARAM_NAME AUX778076_SEQUENCE_PARAM_NAME +#define AUX778076_COUNT_ARGS_TEMPLATE_PARAM AUX778076_SEQUENCE_TEMPLATE_PARAM +#define AUX778076_COUNT_ARGS_ARITY AUX778076_SEQUENCE_LIMIT +#define AUX778076_COUNT_ARGS_USE_STANDARD_PP_PRIMITIVES +#include + +template< + AUX778076_SEQUENCE_PARAMS() + > +struct BOOST_PP_CAT(AUX778076_SEQUENCE_NAME,_impl) +{ + typedef aux::BOOST_PP_CAT(AUX778076_SEQUENCE_NAME,_count_args)< + BOOST_PP_ENUM_PARAMS(AUX778076_SEQUENCE_LIMIT, AUX778076_SEQUENCE_PARAM_NAME) + > arg_num_; + + typedef typename aux::BOOST_PP_CAT(AUX778076_SEQUENCE_NAME,_chooser)< arg_num_::value > + ::template result_< AUX778076_SEQUENCE_ARGS() >::type type; +}; + +} // namespace aux + +template< + AUX778076_SEQUENCE_DEFAULT_PARAMS() + > +struct AUX778076_SEQUENCE_NAME + : aux::BOOST_PP_CAT(AUX778076_SEQUENCE_NAME,_impl)< + AUX778076_SEQUENCE_ARGS() + >::type +{ + typedef typename aux::BOOST_PP_CAT(AUX778076_SEQUENCE_NAME,_impl)< + AUX778076_SEQUENCE_ARGS() + >::type type; +}; + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +# undef AUX778076_SEQUENCE_N_PARTIAL_SPEC_ARGS +# undef AUX778076_SEQUENCE_N_ARGS +# undef AUX778076_SEQUENCE_CONVERT_CN_TO +# undef AUX778076_SEQUENCE_N_PARAMS +# undef AUX778076_SEQUENCE_DEFAULT_PARAMS +# undef AUX778076_SEQUENCE_ARGS +# undef AUX778076_SEQUENCE_PARAMS +# undef AUX778076_SEQUENCE_NAME_N +# undef AUX778076_SEQUENCE_DEFAULT +# undef AUX778076_SEQUENCE_TEMPLATE_PARAM +# undef AUX778076_SEQUENCE_PARAM_NAME +# undef AUX778076_SEQUENCE_LIMIT +# undef AUX778076_SEQUENCE_BASE_NAME +# undef AUX778076_SEQUENCE_NAME +# undef AUX778076_SEQUENCE_INTEGRAL_WRAPPER + +}} + +///// iteration + +#else +#define i_ BOOST_PP_FRAME_ITERATION(1) + +# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +#if i_ == AUX778076_SEQUENCE_LIMIT + +/// primary template (not a specialization!) +template< + AUX778076_SEQUENCE_N_PARAMS(i_) + > +struct AUX778076_SEQUENCE_NAME + : AUX778076_SEQUENCE_NAME_N(i_)< AUX778076_SEQUENCE_N_ARGS(i_) > +{ + typedef typename AUX778076_SEQUENCE_NAME_N(i_)< AUX778076_SEQUENCE_N_ARGS(i_) >::type type; +}; + +#else + +template< + AUX778076_SEQUENCE_N_PARAMS(i_) + > +struct AUX778076_SEQUENCE_NAME< AUX778076_SEQUENCE_N_PARTIAL_SPEC_ARGS(i_) > + : AUX778076_SEQUENCE_NAME_N(i_)< AUX778076_SEQUENCE_N_ARGS(i_) > +{ +#if i_ > 0 || defined(AUX778076_SEQUENCE_INTEGRAL_WRAPPER) + typedef typename AUX778076_SEQUENCE_NAME_N(i_)< AUX778076_SEQUENCE_N_ARGS(i_) >::type type; +#else + typedef AUX778076_SEQUENCE_NAME_N(i_)< AUX778076_SEQUENCE_N_ARGS(i_) >::type type; +#endif +}; + +#endif // i_ == AUX778076_SEQUENCE_LIMIT + +# else + +namespace aux { + +template<> +struct BOOST_PP_CAT(AUX778076_SEQUENCE_NAME,_chooser) +{ + template< + AUX778076_SEQUENCE_PARAMS() + > + struct result_ + { +#if i_ > 0 || defined(AUX778076_SEQUENCE_INTEGRAL_WRAPPER) + typedef typename AUX778076_SEQUENCE_NAME_N(i_)< + AUX778076_SEQUENCE_N_ARGS(i_) + >::type type; +#else + typedef AUX778076_SEQUENCE_NAME_N(i_)< + AUX778076_SEQUENCE_N_ARGS(i_) + >::type type; +#endif + }; +}; + +} // namespace aux + +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +#undef i_ +#endif // BOOST_PP_IS_ITERATING diff --git a/boost/mpl/aux_/size_impl.hpp b/boost/mpl/aux_/size_impl.hpp new file mode 100644 index 00000000..21fbe632 --- /dev/null +++ b/boost/mpl/aux_/size_impl.hpp @@ -0,0 +1,52 @@ + +#ifndef BOOST_MPL_AUX_SIZE_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_SIZE_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +// default implementation; conrete sequences might override it by +// specializing either the 'size_impl' or the primary 'size' template + +template< typename Tag > +struct size_impl +{ + template< typename Sequence > struct apply +#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x561)) + : distance< + typename begin::type + , typename end::type + > + { +#else + { + typedef typename distance< + typename begin::type + , typename end::type + >::type type; +#endif + }; +}; + +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1, size_impl) + +}} + +#endif // BOOST_MPL_AUX_SIZE_IMPL_HPP_INCLUDED diff --git a/boost/mpl/aux_/traits_lambda_spec.hpp b/boost/mpl/aux_/traits_lambda_spec.hpp new file mode 100644 index 00000000..4a7ff26b --- /dev/null +++ b/boost/mpl/aux_/traits_lambda_spec.hpp @@ -0,0 +1,63 @@ + +#ifndef BOOST_MPL_AUX_TRAITS_LAMBDA_SPEC_HPP_INCLUDED +#define BOOST_MPL_AUX_TRAITS_LAMBDA_SPEC_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-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/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include + +#if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) + +# define BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(i, trait) /**/ + +#elif !defined(BOOST_MPL_CFG_MSVC_ETI_BUG) + +# define BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(i, trait) \ +template<> struct trait \ +{ \ + template< BOOST_MPL_PP_PARAMS(i, typename T) > struct apply \ + { \ + }; \ +}; \ +/**/ + +#else + +# define BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(i, trait) \ +template<> struct trait \ +{ \ + template< BOOST_MPL_PP_PARAMS(i, typename T) > struct apply \ + { \ + }; \ +}; \ +template<> struct trait \ +{ \ + template< BOOST_MPL_PP_PARAMS(i, typename T) > struct apply \ + { \ + typedef int type; \ + }; \ +}; \ +/**/ + +#endif // BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT + + +#define BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(i, trait) \ + BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(i, trait) \ + template<> struct trait {}; \ +/**/ + +#endif // BOOST_MPL_AUX_TRAITS_LAMBDA_SPEC_HPP_INCLUDED diff --git a/boost/mpl/back_inserter.hpp b/boost/mpl/back_inserter.hpp new file mode 100644 index 00000000..8fc4083c --- /dev/null +++ b/boost/mpl/back_inserter.hpp @@ -0,0 +1,34 @@ + +#ifndef BOOST_MPL_BACK_INSERTER_HPP_INCLUDED +#define BOOST_MPL_BACK_INSERTER_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include + +namespace boost { +namespace mpl { + +template< + typename Sequence + > +struct back_inserter + : inserter< Sequence,push_back<> > +{ +}; + +}} + +#endif // BOOST_MPL_BACK_INSERTER_HPP_INCLUDED diff --git a/boost/mpl/begin_end.hpp b/boost/mpl/begin_end.hpp new file mode 100644 index 00000000..b7074afd --- /dev/null +++ b/boost/mpl/begin_end.hpp @@ -0,0 +1,57 @@ + +#ifndef BOOST_MPL_BEGIN_END_HPP_INCLUDED +#define BOOST_MPL_BEGIN_END_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +// agurt, 13/sep/02: switched from inheritance to typedef; MSVC is more +// happy this way (less ETI-related errors), and it doesn't affect +// anything else +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + > +struct begin +{ + typedef typename sequence_tag::type tag_; + typedef typename begin_impl< tag_ > + ::template apply< Sequence >::type type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,begin,(Sequence)) +}; + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + > +struct end +{ + typedef typename sequence_tag::type tag_; + typedef typename end_impl< tag_ > + ::template apply< Sequence >::type type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,end,(Sequence)) +}; + +BOOST_MPL_AUX_NA_SPEC(1, begin) +BOOST_MPL_AUX_NA_SPEC(1, end) + +}} + +#endif // BOOST_MPL_BEGIN_END_HPP_INCLUDED diff --git a/boost/mpl/begin_end_fwd.hpp b/boost/mpl/begin_end_fwd.hpp new file mode 100644 index 00000000..70ef9efe --- /dev/null +++ b/boost/mpl/begin_end_fwd.hpp @@ -0,0 +1,27 @@ + +#ifndef BOOST_MPL_BEGIN_END_FWD_HPP_INCLUDED +#define BOOST_MPL_BEGIN_END_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +namespace boost { namespace mpl { + +template< typename Tag > struct begin_impl; +template< typename Tag > struct end_impl; + +template< typename Sequence > struct begin; +template< typename Sequence > struct end; + +}} + +#endif // BOOST_MPL_BEGIN_END_FWD_HPP_INCLUDED diff --git a/boost/mpl/clear.hpp b/boost/mpl/clear.hpp new file mode 100644 index 00000000..c6b95edf --- /dev/null +++ b/boost/mpl/clear.hpp @@ -0,0 +1,39 @@ + +#ifndef BOOST_MPL_CLEAR_HPP_INCLUDED +#define BOOST_MPL_CLEAR_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + > +struct clear + : clear_impl< typename sequence_tag::type > + ::template apply< Sequence > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,clear,(Sequence)) +}; + +BOOST_MPL_AUX_NA_SPEC(1, clear) + +}} + +#endif // BOOST_MPL_CLEAR_HPP_INCLUDED diff --git a/boost/mpl/clear_fwd.hpp b/boost/mpl/clear_fwd.hpp new file mode 100644 index 00000000..d14a1d2b --- /dev/null +++ b/boost/mpl/clear_fwd.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_CLEAR_FWD_HPP_INCLUDED +#define BOOST_MPL_CLEAR_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +namespace boost { namespace mpl { + +template< typename Tag > struct clear_impl; +template< typename Sequence > struct clear; + +}} + +#endif // BOOST_MPL_CLEAR_FWD_HPP_INCLUDED diff --git a/boost/mpl/deref.hpp b/boost/mpl/deref.hpp new file mode 100644 index 00000000..1105ec90 --- /dev/null +++ b/boost/mpl/deref.hpp @@ -0,0 +1,41 @@ + +#ifndef BOOST_MPL_DEREF_HPP_INCLUDED +#define BOOST_MPL_DEREF_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2002-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Iterator) + > +struct deref +{ +#if !defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG) + typedef typename Iterator::type type; +#else + typedef typename aux::msvc_type::type type; +#endif + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,deref,(Iterator)) +}; + +BOOST_MPL_AUX_NA_SPEC(1, deref) + +}} + +#endif // BOOST_MPL_DEREF_HPP_INCLUDED diff --git a/boost/mpl/distance.hpp b/boost/mpl/distance.hpp new file mode 100644 index 00000000..95f4f335 --- /dev/null +++ b/boost/mpl/distance.hpp @@ -0,0 +1,78 @@ + +#ifndef BOOST_MPL_DISTANCE_HPP_INCLUDED +#define BOOST_MPL_DISTANCE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace boost { namespace mpl { + +// default implementation for forward/bidirectional iterators +template< typename Tag > struct distance_impl +{ + template< typename First, typename Last > struct apply +#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) + : aux::msvc_eti_base< typename iter_fold< + iterator_range + , mpl::long_<0> + , next<> + >::type > + { +#else + { + typedef typename iter_fold< + iterator_range + , mpl::long_<0> + , next<> + >::type type; + + BOOST_STATIC_CONSTANT(long, value = + (iter_fold< + iterator_range + , mpl::long_<0> + , next<> + >::type::value) + ); +#endif + }; +}; + +template< + typename BOOST_MPL_AUX_NA_PARAM(First) + , typename BOOST_MPL_AUX_NA_PARAM(Last) + > +struct distance + : distance_impl< typename tag::type > + ::template apply +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(2, distance, (First, Last)) +}; + +BOOST_MPL_AUX_NA_SPEC(2, distance) + +}} + +#endif // BOOST_MPL_DISTANCE_HPP_INCLUDED diff --git a/boost/mpl/distance_fwd.hpp b/boost/mpl/distance_fwd.hpp new file mode 100644 index 00000000..a69a7c51 --- /dev/null +++ b/boost/mpl/distance_fwd.hpp @@ -0,0 +1,28 @@ + +#ifndef BOOST_MPL_DISTANCE_FWD_HPP_INCLUDED +#define BOOST_MPL_DISTANCE_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include + +namespace boost { namespace mpl { + +BOOST_MPL_AUX_COMMON_NAME_WKND(distance) + +template< typename Tag > struct distance_impl; +template< typename First, typename Last > struct distance; + +}} + +#endif // BOOST_MPL_DISTANCE_FWD_HPP_INCLUDED diff --git a/boost/mpl/empty.hpp b/boost/mpl/empty.hpp new file mode 100644 index 00000000..1185324c --- /dev/null +++ b/boost/mpl/empty.hpp @@ -0,0 +1,39 @@ + +#ifndef BOOST_MPL_EMPTY_HPP_INCLUDED +#define BOOST_MPL_EMPTY_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + > +struct empty + : empty_impl< typename sequence_tag::type > + ::template apply< Sequence > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,empty,(Sequence)) +}; + +BOOST_MPL_AUX_NA_SPEC(1, empty) + +}} + +#endif // BOOST_MPL_EMPTY_HPP_INCLUDED diff --git a/boost/mpl/empty_fwd.hpp b/boost/mpl/empty_fwd.hpp new file mode 100644 index 00000000..551c9660 --- /dev/null +++ b/boost/mpl/empty_fwd.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_EMPTY_FWD_HPP_INCLUDED +#define BOOST_MPL_EMPTY_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +namespace boost { namespace mpl { + +template< typename Tag > struct empty_impl; +template< typename Sequence > struct empty; + +}} + +#endif // BOOST_MPL_EMPTY_FWD_HPP_INCLUDED diff --git a/boost/mpl/equal.hpp b/boost/mpl/equal.hpp new file mode 100644 index 00000000..8937ef3a --- /dev/null +++ b/boost/mpl/equal.hpp @@ -0,0 +1,112 @@ + +#ifndef BOOST_MPL_EQUAL_HPP_INCLUDED +#define BOOST_MPL_EQUAL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { namespace mpl { + +namespace aux { + +template< + typename Predicate + , typename LastIterator1 + , typename LastIterator2 + > +struct equal_pred +{ + template< + typename Iterator2 + , typename Iterator1 + > + struct apply + { + typedef typename and_< + not_< is_same > + , not_< is_same > + , aux::iter_apply2 + >::type type; + }; +}; + +template< + typename Sequence1 + , typename Sequence2 + , typename Predicate + > +struct equal_impl +{ + typedef typename begin::type first1_; + typedef typename begin::type first2_; + typedef typename end::type last1_; + typedef typename end::type last2_; + + typedef aux::iter_fold_if_impl< + first1_ + , first2_ + , next<> + , protect< aux::equal_pred > + , void_ + , always + > fold_; + + typedef typename fold_::iterator iter1_; + typedef typename fold_::state iter2_; + typedef and_< + is_same + , is_same + > result_; + + typedef typename result_::type type; +}; + + +} // namespace aux + + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence1) + , typename BOOST_MPL_AUX_NA_PARAM(Sequence2) + , typename Predicate = is_same<_,_> + > +struct equal + : aux::msvc_eti_base< + typename aux::equal_impl::type + >::type +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,equal,(Sequence1,Sequence2)) +}; + +BOOST_MPL_AUX_NA_SPEC(2, equal) + +}} + +#endif // BOOST_MPL_EQUAL_HPP_INCLUDED diff --git a/boost/mpl/find_if.hpp b/boost/mpl/find_if.hpp new file mode 100644 index 00000000..83a007e7 --- /dev/null +++ b/boost/mpl/find_if.hpp @@ -0,0 +1,50 @@ + +#ifndef BOOST_MPL_FIND_IF_HPP_INCLUDED +#define BOOST_MPL_FIND_IF_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +BOOST_MPL_AUX_COMMON_NAME_WKND(find_if) + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + , typename BOOST_MPL_AUX_NA_PARAM(Predicate) + > +struct find_if +{ + typedef typename iter_fold_if< + Sequence + , void + , mpl::arg<1> // ignore + , protect< aux::find_if_pred > + >::type result_; + + typedef typename second::type type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,find_if,(Sequence,Predicate)) +}; + +BOOST_MPL_AUX_NA_SPEC(2,find_if) + +}} + +#endif // BOOST_MPL_FIND_IF_HPP_INCLUDED diff --git a/boost/mpl/fold.hpp b/boost/mpl/fold.hpp new file mode 100644 index 00000000..0bc67ef3 --- /dev/null +++ b/boost/mpl/fold.hpp @@ -0,0 +1,48 @@ + +#ifndef BOOST_MPL_FOLD_HPP_INCLUDED +#define BOOST_MPL_FOLD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2001-2004 +// Copyright David Abrahams 2001-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) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + , typename BOOST_MPL_AUX_NA_PARAM(State) + , typename BOOST_MPL_AUX_NA_PARAM(ForwardOp) + > +struct fold +{ + typedef typename aux::fold_impl< + ::boost::mpl::O1_size::value + , typename begin::type + , typename end::type + , State + , ForwardOp + >::state type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT(3,fold,(Sequence,State,ForwardOp)) +}; + +BOOST_MPL_AUX_NA_SPEC(3, fold) + +}} + +#endif // BOOST_MPL_FOLD_HPP_INCLUDED diff --git a/boost/mpl/front.hpp b/boost/mpl/front.hpp new file mode 100644 index 00000000..b222ff25 --- /dev/null +++ b/boost/mpl/front.hpp @@ -0,0 +1,39 @@ + +#ifndef BOOST_MPL_FRONT_HPP_INCLUDED +#define BOOST_MPL_FRONT_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + > +struct front + : front_impl< typename sequence_tag::type > + ::template apply< Sequence > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,front,(Sequence)) +}; + +BOOST_MPL_AUX_NA_SPEC(1, front) + +}} + +#endif // BOOST_MPL_FRONT_HPP_INCLUDED diff --git a/boost/mpl/front_fwd.hpp b/boost/mpl/front_fwd.hpp new file mode 100644 index 00000000..f01282a7 --- /dev/null +++ b/boost/mpl/front_fwd.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_FRONT_FWD_HPP_INCLUDED +#define BOOST_MPL_FRONT_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +namespace boost { namespace mpl { + +template< typename Tag > struct front_impl; +template< typename Sequence > struct front; + +}} + +#endif // BOOST_MPL_FRONT_FWD_HPP_INCLUDED diff --git a/boost/mpl/front_inserter.hpp b/boost/mpl/front_inserter.hpp new file mode 100644 index 00000000..0a6b197e --- /dev/null +++ b/boost/mpl/front_inserter.hpp @@ -0,0 +1,33 @@ + +#ifndef BOOST_MPL_FRONT_INSERTER_HPP_INCLUDED +#define BOOST_MPL_FRONT_INSERTER_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include + +namespace boost { namespace mpl { + +template< + typename Sequence + > +struct front_inserter + : inserter< Sequence,push_front<> > +{ +}; + +}} + +#endif // BOOST_MPL_FRONT_INSERTER_HPP_INCLUDED diff --git a/boost/mpl/insert.hpp b/boost/mpl/insert.hpp new file mode 100644 index 00000000..5e379a49 --- /dev/null +++ b/boost/mpl/insert.hpp @@ -0,0 +1,41 @@ + +#ifndef BOOST_MPL_INSERT_HPP_INCLUDED +#define BOOST_MPL_INSERT_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + , typename BOOST_MPL_AUX_NA_PARAM(Pos_or_T) + , typename BOOST_MPL_AUX_NA_PARAM(T) + > +struct insert + : insert_impl< typename sequence_tag::type > + ::template apply< Sequence,Pos_or_T,T > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(3,insert,(Sequence,Pos_or_T,T)) +}; + +BOOST_MPL_AUX_NA_SPEC(3, insert) + +}} + +#endif // BOOST_MPL_INSERT_HPP_INCLUDED diff --git a/boost/mpl/insert_fwd.hpp b/boost/mpl/insert_fwd.hpp new file mode 100644 index 00000000..ba6b1617 --- /dev/null +++ b/boost/mpl/insert_fwd.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_INSERT_FWD_HPP_INCLUDED +#define BOOST_MPL_INSERT_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +namespace boost { namespace mpl { + +template< typename Tag > struct insert_impl; +template< typename Sequence, typename Pos_or_T, typename T > struct insert; + +}} + +#endif // BOOST_MPL_INSERT_FWD_HPP_INCLUDED diff --git a/boost/mpl/insert_range.hpp b/boost/mpl/insert_range.hpp new file mode 100644 index 00000000..0c362f5a --- /dev/null +++ b/boost/mpl/insert_range.hpp @@ -0,0 +1,41 @@ + +#ifndef BOOST_MPL_INSERT_RANGE_HPP_INCLUDED +#define BOOST_MPL_INSERT_RANGE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + , typename BOOST_MPL_AUX_NA_PARAM(Pos) + , typename BOOST_MPL_AUX_NA_PARAM(Range) + > +struct insert_range + : insert_range_impl< typename sequence_tag::type > + ::template apply< Sequence,Pos,Range > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(3,insert_range,(Sequence,Pos,Range)) +}; + +BOOST_MPL_AUX_NA_SPEC(3, insert_range) + +}} + +#endif // BOOST_MPL_INSERT_RANGE_HPP_INCLUDED diff --git a/boost/mpl/insert_range_fwd.hpp b/boost/mpl/insert_range_fwd.hpp new file mode 100644 index 00000000..d9c946f2 --- /dev/null +++ b/boost/mpl/insert_range_fwd.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_INSERT_RANGE_FWD_HPP_INCLUDED +#define BOOST_MPL_INSERT_RANGE_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +namespace boost { namespace mpl { + +template< typename Tag > struct insert_range_impl; +template< typename Sequence, typename Pos, typename Range > struct insert_range; + +}} + +#endif // BOOST_MPL_INSERT_RANGE_FWD_HPP_INCLUDED diff --git a/boost/mpl/inserter.hpp b/boost/mpl/inserter.hpp new file mode 100644 index 00000000..964df7f6 --- /dev/null +++ b/boost/mpl/inserter.hpp @@ -0,0 +1,32 @@ + +#ifndef BOOST_MPL_INSERTER_HPP_INCLUDED +#define BOOST_MPL_INSERTER_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +namespace boost { namespace mpl { + +template< + typename Sequence + , typename Operation + > +struct inserter +{ + typedef Sequence state; + typedef Operation operation; +}; + +}} + +#endif // BOOST_MPL_INSERTER_HPP_INCLUDED diff --git a/boost/mpl/is_sequence.hpp b/boost/mpl/is_sequence.hpp new file mode 100644 index 00000000..68e036fa --- /dev/null +++ b/boost/mpl/is_sequence.hpp @@ -0,0 +1,112 @@ + +#ifndef BOOST_MPL_IS_SEQUENCE_HPP_INCLUDED +#define BOOST_MPL_IS_SEQUENCE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2002-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +# include +#elif BOOST_WORKAROUND(BOOST_MSVC, == 1300) +# include +#endif + +#include + +namespace boost { namespace mpl { + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + +namespace aux { + +// agurt, 11/jun/03: +// MSVC 6.5/7.0 fails if 'has_begin' is instantiated on a class type that has a +// 'begin' member that doesn't name a type; e.g. 'has_begin< std::vector >' +// would fail; requiring 'T' to have _both_ 'tag' and 'begin' members workarounds +// the issue for most real-world cases +template< typename T > struct is_sequence_impl + : and_< + identity< aux::has_tag > + , identity< aux::has_begin > + > +{ +}; + +} // namespace aux + +template< + typename BOOST_MPL_AUX_NA_PARAM(T) + > +struct is_sequence + : if_< +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + aux::msvc_is_class +#else + boost::is_class +#endif + , aux::is_sequence_impl + , bool_ + >::type +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1, is_sequence, (T)) +}; + +#elif defined(BOOST_MPL_CFG_NO_HAS_XXX) + +template< + typename BOOST_MPL_AUX_NA_PARAM(T) + > +struct is_sequence + : bool_ +{ +}; + +#else + +template< + typename BOOST_MPL_AUX_NA_PARAM(T) + > +struct is_sequence + : not_< is_same< typename begin::type, void_ > > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1, is_sequence, (T)) +}; + +#endif // BOOST_MSVC + +#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) +template<> struct is_sequence + : bool_ +{ +}; +#endif + +BOOST_MPL_AUX_NA_SPEC_NO_ETI(1, is_sequence) + +}} + +#endif // BOOST_MPL_IS_SEQUENCE_HPP_INCLUDED diff --git a/boost/mpl/iter_fold.hpp b/boost/mpl/iter_fold.hpp new file mode 100644 index 00000000..1b56b790 --- /dev/null +++ b/boost/mpl/iter_fold.hpp @@ -0,0 +1,49 @@ + +#ifndef BOOST_MPL_ITER_FOLD_HPP_INCLUDED +#define BOOST_MPL_ITER_FOLD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2001-2004 +// Copyright David Abrahams 2001-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) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + , typename BOOST_MPL_AUX_NA_PARAM(State) + , typename BOOST_MPL_AUX_NA_PARAM(ForwardOp) + > +struct iter_fold +{ + typedef typename aux::iter_fold_impl< + ::boost::mpl::O1_size::value + , typename begin::type + , typename end::type + , State + , typename lambda::type + >::state type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT(3,iter_fold,(Sequence,State,ForwardOp)) +}; + +BOOST_MPL_AUX_NA_SPEC(3, iter_fold) + +}} + +#endif // BOOST_MPL_ITER_FOLD_HPP_INCLUDED diff --git a/boost/mpl/iter_fold_if.hpp b/boost/mpl/iter_fold_if.hpp new file mode 100644 index 00000000..0115b7b2 --- /dev/null +++ b/boost/mpl/iter_fold_if.hpp @@ -0,0 +1,117 @@ + +#ifndef BOOST_MPL_ITER_FOLD_IF_HPP_INCLUDED +#define BOOST_MPL_ITER_FOLD_IF_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright Eric Friedman 2003 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { namespace mpl { + +namespace aux { + +template< typename Predicate, typename LastIterator > +struct iter_fold_if_pred +{ + template< typename State, typename Iterator > struct apply +#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) + : and_< + not_< is_same > + , apply1 + > + { +#else + { + typedef and_< + not_< is_same > + , apply1 + > type; +#endif + }; +}; + +} // namespace aux + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + , typename BOOST_MPL_AUX_NA_PARAM(State) + , typename BOOST_MPL_AUX_NA_PARAM(ForwardOp) + , typename BOOST_MPL_AUX_NA_PARAM(ForwardPredicate) + , typename BOOST_MPL_AUX_NA_PARAM(BackwardOp) + , typename BOOST_MPL_AUX_NA_PARAM(BackwardPredicate) + > +struct iter_fold_if +{ + + typedef typename begin::type first_; + typedef typename end::type last_; + + typedef typename eval_if< + is_na + , if_< is_na, always, always > + , identity + >::type backward_pred_; + +// cwpro8 doesn't like 'cut-off' type here (use typedef instead) +#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) && !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) + struct result_ : +#else + typedef +#endif + aux::iter_fold_if_impl< + first_ + , State + , ForwardOp + , protect< aux::iter_fold_if_pred< ForwardPredicate,last_ > > + , BackwardOp + , backward_pred_ + > +#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) && !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) + { }; +#else + result_; +#endif + +public: + + typedef pair< + typename result_::state + , typename result_::iterator + > type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT( + 6 + , iter_fold_if + , (Sequence,State,ForwardOp,ForwardPredicate,BackwardOp,BackwardPredicate) + ) +}; + +BOOST_MPL_AUX_NA_SPEC(6, iter_fold_if) + +}} + +#endif // BOOST_MPL_ITER_FOLD_IF_HPP_INCLUDED diff --git a/boost/mpl/iterator_category.hpp b/boost/mpl/iterator_category.hpp new file mode 100644 index 00000000..d5ea4afe --- /dev/null +++ b/boost/mpl/iterator_category.hpp @@ -0,0 +1,35 @@ + +#ifndef BOOST_MPL_ITERATOR_CATEGORY_HPP_INCLUDED +#define BOOST_MPL_ITERATOR_CATEGORY_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Iterator) + > +struct iterator_category +{ + typedef typename Iterator::category type; + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,iterator_category,(Iterator)) +}; + +BOOST_MPL_AUX_NA_SPEC(1, iterator_category) + +}} + +#endif // BOOST_MPL_ITERATOR_CATEGORY_HPP_INCLUDED diff --git a/boost/mpl/iterator_range.hpp b/boost/mpl/iterator_range.hpp new file mode 100644 index 00000000..a637e224 --- /dev/null +++ b/boost/mpl/iterator_range.hpp @@ -0,0 +1,42 @@ + +#ifndef BOOST_MPL_ITERATOR_RANGE_HPP_INCLUDED +#define BOOST_MPL_ITERATOR_RANGE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2001-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include + +namespace boost { namespace mpl { + +struct iterator_range_tag; + +template< + typename BOOST_MPL_AUX_NA_PARAM(First) + , typename BOOST_MPL_AUX_NA_PARAM(Last) + > +struct iterator_range +{ + typedef iterator_range_tag tag; + typedef iterator_range type; + typedef First begin; + typedef Last end; + + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,iterator_range,(First,Last)) +}; + +BOOST_MPL_AUX_NA_SPEC(2, iterator_range) + +}} + +#endif // BOOST_MPL_ITERATOR_RANGE_HPP_INCLUDED diff --git a/boost/mpl/iterator_tags.hpp b/boost/mpl/iterator_tags.hpp new file mode 100644 index 00000000..7c3116ab --- /dev/null +++ b/boost/mpl/iterator_tags.hpp @@ -0,0 +1,27 @@ + +#ifndef BOOST_MPL_ITERATOR_TAG_HPP_INCLUDED +#define BOOST_MPL_ITERATOR_TAG_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include + +namespace boost { namespace mpl { + +struct forward_iterator_tag : int_<0> { typedef forward_iterator_tag type; }; +struct bidirectional_iterator_tag : int_<1> { typedef bidirectional_iterator_tag type; }; +struct random_access_iterator_tag : int_<2> { typedef random_access_iterator_tag type; }; + +}} + +#endif // BOOST_MPL_ITERATOR_TAG_HPP_INCLUDED diff --git a/boost/mpl/joint_view.hpp b/boost/mpl/joint_view.hpp new file mode 100644 index 00000000..cd9cddac --- /dev/null +++ b/boost/mpl/joint_view.hpp @@ -0,0 +1,65 @@ + +#ifndef BOOST_MPL_JOINT_VIEW_HPP_INCLUDED +#define BOOST_MPL_JOINT_VIEW_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +namespace aux { +struct joint_view_tag; +} + +template<> +struct size_impl< aux::joint_view_tag > +{ + template < typename JointView > struct apply + : plus< + size + , size + > + {}; +}; + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence1_) + , typename BOOST_MPL_AUX_NA_PARAM(Sequence2_) + > +struct joint_view +{ + typedef typename mpl::begin::type first1_; + typedef typename mpl::end::type last1_; + typedef typename mpl::begin::type first2_; + typedef typename mpl::end::type last2_; + + // agurt, 25/may/03: for the 'size_traits' implementation above + typedef Sequence1_ sequence1_; + typedef Sequence2_ sequence2_; + + typedef joint_view type; + typedef aux::joint_view_tag tag; + typedef joint_iter begin; + typedef joint_iter end; +}; + +BOOST_MPL_AUX_NA_SPEC(2, joint_view) + +}} + +#endif // BOOST_MPL_JOINT_VIEW_HPP_INCLUDED diff --git a/boost/mpl/limits/list.hpp b/boost/mpl/limits/list.hpp new file mode 100644 index 00000000..b22d6a7b --- /dev/null +++ b/boost/mpl/limits/list.hpp @@ -0,0 +1,21 @@ + +#ifndef BOOST_MPL_LIMITS_LIST_HPP_INCLUDED +#define BOOST_MPL_LIMITS_LIST_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_LIMIT_LIST_SIZE) +# define BOOST_MPL_LIMIT_LIST_SIZE 20 +#endif + +#endif // BOOST_MPL_LIMITS_LIST_HPP_INCLUDED diff --git a/boost/mpl/limits/unrolling.hpp b/boost/mpl/limits/unrolling.hpp new file mode 100644 index 00000000..6dba9422 --- /dev/null +++ b/boost/mpl/limits/unrolling.hpp @@ -0,0 +1,21 @@ + +#ifndef BOOST_MPL_LIMITS_UNROLLING_HPP_INCLUDED +#define BOOST_MPL_LIMITS_UNROLLING_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_LIMIT_UNROLLING) +# define BOOST_MPL_LIMIT_UNROLLING 4 +#endif + +#endif // BOOST_MPL_LIMITS_UNROLLING_HPP_INCLUDED diff --git a/boost/mpl/list.hpp b/boost/mpl/list.hpp new file mode 100644 index 00000000..cff8a4dd --- /dev/null +++ b/boost/mpl/list.hpp @@ -0,0 +1,57 @@ + +#ifndef BOOST_MPL_LIST_HPP_INCLUDED +#define BOOST_MPL_LIST_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +# include +# include + +# include +# include +# include + +#if !defined(BOOST_NEEDS_TOKEN_PASTING_OP_FOR_TOKENS_JUXTAPOSING) +# define AUX778076_LIST_HEADER \ + BOOST_PP_CAT(list,BOOST_MPL_LIMIT_LIST_SIZE).hpp \ + /**/ +#else +# define AUX778076_LIST_HEADER \ + BOOST_PP_CAT(list,BOOST_MPL_LIMIT_LIST_SIZE)##.hpp \ + /**/ +#endif + +# include BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_LIST_HEADER) +# undef AUX778076_LIST_HEADER +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER list.hpp +# include + +#else + +# include + +# define AUX778076_SEQUENCE_NAME list +# define AUX778076_SEQUENCE_LIMIT BOOST_MPL_LIMIT_LIST_SIZE +# include + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#endif // BOOST_MPL_LIST_HPP_INCLUDED diff --git a/boost/mpl/list/aux_/O1_size.hpp b/boost/mpl/list/aux_/O1_size.hpp new file mode 100644 index 00000000..ccbc3f1b --- /dev/null +++ b/boost/mpl/list/aux_/O1_size.hpp @@ -0,0 +1,33 @@ + +#ifndef BOOST_MPL_LIST_AUX_O1_SIZE_HPP_INCLUDED +#define BOOST_MPL_LIST_AUX_O1_SIZE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include + +namespace boost { namespace mpl { + +template<> +struct O1_size_impl< aux::list_tag > +{ + template< typename List > struct apply + : List::size + { + }; +}; + +}} + +#endif // BOOST_MPL_LIST_AUX_O1_SIZE_HPP_INCLUDED diff --git a/boost/mpl/list/aux_/begin_end.hpp b/boost/mpl/list/aux_/begin_end.hpp new file mode 100644 index 00000000..b568bee2 --- /dev/null +++ b/boost/mpl/list/aux_/begin_end.hpp @@ -0,0 +1,44 @@ + +#ifndef BOOST_MPL_LIST_AUX_BEGIN_END_HPP_INCLUDED +#define BOOST_MPL_LIST_AUX_BEGIN_END_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template<> +struct begin_impl< aux::list_tag > +{ + template< typename List > struct apply + { + typedef l_iter type; + }; +}; + +template<> +struct end_impl< aux::list_tag > +{ + template< typename > struct apply + { + typedef l_iter type; + }; +}; + +}} + +#endif // BOOST_MPL_LIST_AUX_BEGIN_END_HPP_INCLUDED diff --git a/boost/mpl/list/aux_/clear.hpp b/boost/mpl/list/aux_/clear.hpp new file mode 100644 index 00000000..b16162f7 --- /dev/null +++ b/boost/mpl/list/aux_/clear.hpp @@ -0,0 +1,34 @@ + +#ifndef BOOST_MPL_LIST_AUX_CLEAR_HPP_INCLUDED +#define BOOST_MPL_LIST_AUX_CLEAR_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include + +namespace boost { namespace mpl { + +template<> +struct clear_impl< aux::list_tag > +{ + template< typename List > struct apply + { + typedef l_end type; + }; +}; + +}} + +#endif // BOOST_MPL_LIST_AUX_CLEAR_HPP_INCLUDED diff --git a/boost/mpl/list/aux_/empty.hpp b/boost/mpl/list/aux_/empty.hpp new file mode 100644 index 00000000..95f92439 --- /dev/null +++ b/boost/mpl/list/aux_/empty.hpp @@ -0,0 +1,34 @@ + +#ifndef BOOST_MPL_LIST_AUX_EMPTY_HPP_INCLUDED +#define BOOST_MPL_LIST_AUX_EMPTY_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include + +namespace boost { namespace mpl { + +template<> +struct empty_impl< aux::list_tag > +{ + template< typename List > struct apply + : not_ + { + }; +}; + +}} + +#endif // BOOST_MPL_LIST_AUX_EMPTY_HPP_INCLUDED diff --git a/boost/mpl/list/aux_/front.hpp b/boost/mpl/list/aux_/front.hpp new file mode 100644 index 00000000..9bea1fd3 --- /dev/null +++ b/boost/mpl/list/aux_/front.hpp @@ -0,0 +1,33 @@ + +#ifndef BOOST_MPL_LIST_AUX_FRONT_HPP_INCLUDED +#define BOOST_MPL_LIST_AUX_FRONT_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include + +namespace boost { namespace mpl { + +template<> +struct front_impl< aux::list_tag > +{ + template< typename List > struct apply + { + typedef typename List::item type; + }; +}; + +}} + +#endif // BOOST_MPL_LIST_AUX_FRONT_HPP_INCLUDED diff --git a/boost/mpl/list/aux_/include_preprocessed.hpp b/boost/mpl/list/aux_/include_preprocessed.hpp new file mode 100644 index 00000000..4f7cab26 --- /dev/null +++ b/boost/mpl/list/aux_/include_preprocessed.hpp @@ -0,0 +1,35 @@ + +// Copyright Aleksey Gurtovoy 2001-2006 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +// NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION! + +#include + +#include +#include + +# define AUX778076_HEADER \ + aux_/preprocessed/plain/BOOST_MPL_PREPROCESSED_HEADER \ +/**/ + +#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(700)) +# define AUX778076_INCLUDE_STRING BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_HEADER) +# include AUX778076_INCLUDE_STRING +# undef AUX778076_INCLUDE_STRING +#else +# include BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_HEADER) +#endif + +# undef AUX778076_HEADER + +#undef BOOST_MPL_PREPROCESSED_HEADER diff --git a/boost/mpl/list/aux_/item.hpp b/boost/mpl/list/aux_/item.hpp new file mode 100644 index 00000000..8505deb2 --- /dev/null +++ b/boost/mpl/list/aux_/item.hpp @@ -0,0 +1,55 @@ + +#ifndef BOOST_MPL_LIST_AUX_NODE_HPP_INCLUDED +#define BOOST_MPL_LIST_AUX_NODE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename Size + , typename T + , typename Next + > +struct l_item +{ +// agurt, 17/jul/03: to facilitate the deficient 'is_sequence' implementation +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + typedef int begin; +#endif + typedef aux::list_tag tag; + typedef l_item type; + + typedef Size size; + typedef T item; + typedef Next next; +}; + +struct l_end +{ +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + typedef int begin; +#endif + typedef aux::list_tag tag; + typedef l_end type; + typedef long_<0> size; +}; + +}} + +#endif // BOOST_MPL_LIST_AUX_NODE_HPP_INCLUDED diff --git a/boost/mpl/list/aux_/iterator.hpp b/boost/mpl/list/aux_/iterator.hpp new file mode 100644 index 00000000..6b5ea786 --- /dev/null +++ b/boost/mpl/list/aux_/iterator.hpp @@ -0,0 +1,76 @@ + +#ifndef BOOST_MPL_LIST_AUX_ITERATOR_HPP_INCLUDED +#define BOOST_MPL_LIST_AUX_ITERATOR_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template< typename Node > +struct l_iter +{ + typedef aux::l_iter_tag tag; + typedef forward_iterator_tag category; +}; + +template< typename Node > +struct deref< l_iter > +{ + typedef typename Node::item type; +}; + +template< typename Node > +struct next< l_iter > +{ + typedef l_iter< typename Node::next > type; +}; + +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +template< typename Node > +struct l_iter +{ + typedef aux::l_iter_tag tag; + typedef forward_iterator_tag category; + typedef typename Node::item type; + typedef l_iter< typename mpl::next::type > next; +}; + +#endif + + +template<> struct l_iter +{ + typedef aux::l_iter_tag tag; + typedef forward_iterator_tag category; +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + typedef na type; + typedef l_iter next; +#endif +}; + +BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(1, l_iter) + +}} + +#endif // BOOST_MPL_LIST_AUX_ITERATOR_HPP_INCLUDED diff --git a/boost/mpl/list/aux_/numbered.hpp b/boost/mpl/list/aux_/numbered.hpp new file mode 100644 index 00000000..0cd49a6d --- /dev/null +++ b/boost/mpl/list/aux_/numbered.hpp @@ -0,0 +1,68 @@ + +// NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION + +// Copyright Peter Dimov 2000-2002 +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if defined(BOOST_PP_IS_ITERATING) + +#include +#include +#include +#include + +#define i BOOST_PP_FRAME_ITERATION(1) + +#if i == 1 + +template< + BOOST_PP_ENUM_PARAMS(i, typename T) + > +struct list1 + : l_item< + long_<1> + , T0 + , l_end + > +{ + typedef list1 type; +}; + +#else + +# define MPL_AUX_LIST_TAIL(list, i, T) \ + BOOST_PP_CAT(list,BOOST_PP_DEC(i))< \ + BOOST_PP_ENUM_SHIFTED_PARAMS(i, T) \ + > \ + /**/ + +template< + BOOST_PP_ENUM_PARAMS(i, typename T) + > +struct BOOST_PP_CAT(list,i) + : l_item< + long_ + , T0 + , MPL_AUX_LIST_TAIL(list,i,T) + > +{ + typedef BOOST_PP_CAT(list,i) type; +}; + +# undef MPL_AUX_LIST_TAIL + +#endif // i == 1 + +#undef i + +#endif // BOOST_PP_IS_ITERATING diff --git a/boost/mpl/list/aux_/numbered_c.hpp b/boost/mpl/list/aux_/numbered_c.hpp new file mode 100644 index 00000000..0006fd6c --- /dev/null +++ b/boost/mpl/list/aux_/numbered_c.hpp @@ -0,0 +1,71 @@ + +// NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if defined(BOOST_PP_IS_ITERATING) + +#include +#include +#include +#include + +#define i BOOST_PP_FRAME_ITERATION(1) + +#if i == 1 + +template< + typename T + , BOOST_PP_ENUM_PARAMS(i, T C) + > +struct list1_c + : l_item< + long_<1> + , integral_c + , l_end + > +{ + typedef list1_c type; + typedef T value_type; +}; + +#else + +# define MPL_AUX_LIST_C_TAIL(list, i, C) \ + BOOST_PP_CAT(BOOST_PP_CAT(list,BOOST_PP_DEC(i)),_c) \ + /**/ + +template< + typename T + , BOOST_PP_ENUM_PARAMS(i, T C) + > +struct BOOST_PP_CAT(BOOST_PP_CAT(list,i),_c) + : l_item< + long_ + , integral_c + , MPL_AUX_LIST_C_TAIL(list,i,C) + > +{ + typedef BOOST_PP_CAT(BOOST_PP_CAT(list,i),_c) type; + typedef T value_type; +}; + +# undef MPL_AUX_LIST_C_TAIL + +#endif // i == 1 + +#undef i + +#endif // BOOST_PP_IS_ITERATING diff --git a/boost/mpl/list/aux_/pop_front.hpp b/boost/mpl/list/aux_/pop_front.hpp new file mode 100644 index 00000000..46a04145 --- /dev/null +++ b/boost/mpl/list/aux_/pop_front.hpp @@ -0,0 +1,34 @@ + +#ifndef BOOST_MPL_LIST_AUX_POP_FRONT_HPP_INCLUDED +#define BOOST_MPL_LIST_AUX_POP_FRONT_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include + +namespace boost { namespace mpl { + +template<> +struct pop_front_impl< aux::list_tag > +{ + template< typename List > struct apply + { + typedef typename mpl::next::type type; + }; +}; + +}} + +#endif // BOOST_MPL_LIST_AUX_POP_FRONT_HPP_INCLUDED diff --git a/boost/mpl/list/aux_/preprocessed/plain/list10.hpp b/boost/mpl/list/aux_/preprocessed/plain/list10.hpp new file mode 100644 index 00000000..99368d2c --- /dev/null +++ b/boost/mpl/list/aux_/preprocessed/plain/list10.hpp @@ -0,0 +1,149 @@ + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +// Preprocessed version of "boost/mpl/list/list10.hpp" header +// -- DO NOT modify by hand! + +namespace boost { namespace mpl { + +template< + typename T0 + > +struct list1 + : l_item< + long_<1> + , T0 + , l_end + > +{ + typedef list1 type; +}; + +template< + typename T0, typename T1 + > +struct list2 + : l_item< + long_<2> + , T0 + , list1 + > +{ + typedef list2 type; +}; + +template< + typename T0, typename T1, typename T2 + > +struct list3 + : l_item< + long_<3> + , T0 + , list2< T1,T2 > + > +{ + typedef list3 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3 + > +struct list4 + : l_item< + long_<4> + , T0 + , list3< T1,T2,T3 > + > +{ + typedef list4 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + > +struct list5 + : l_item< + long_<5> + , T0 + , list4< T1,T2,T3,T4 > + > +{ + typedef list5 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5 + > +struct list6 + : l_item< + long_<6> + , T0 + , list5< T1,T2,T3,T4,T5 > + > +{ + typedef list6 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6 + > +struct list7 + : l_item< + long_<7> + , T0 + , list6< T1,T2,T3,T4,T5,T6 > + > +{ + typedef list7 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7 + > +struct list8 + : l_item< + long_<8> + , T0 + , list7< T1,T2,T3,T4,T5,T6,T7 > + > +{ + typedef list8 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8 + > +struct list9 + : l_item< + long_<9> + , T0 + , list8< T1,T2,T3,T4,T5,T6,T7,T8 > + > +{ + typedef list9 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + > +struct list10 + : l_item< + long_<10> + , T0 + , list9< T1,T2,T3,T4,T5,T6,T7,T8,T9 > + > +{ + typedef list10 type; +}; + +}} diff --git a/boost/mpl/list/aux_/preprocessed/plain/list10_c.hpp b/boost/mpl/list/aux_/preprocessed/plain/list10_c.hpp new file mode 100644 index 00000000..7133d712 --- /dev/null +++ b/boost/mpl/list/aux_/preprocessed/plain/list10_c.hpp @@ -0,0 +1,164 @@ + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +// Preprocessed version of "boost/mpl/list/list10_c.hpp" header +// -- DO NOT modify by hand! + +namespace boost { namespace mpl { + +template< + typename T + , T C0 + > +struct list1_c + : l_item< + long_<1> + , integral_c< T,C0 > + , l_end + > +{ + typedef list1_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1 + > +struct list2_c + : l_item< + long_<2> + , integral_c< T,C0 > + , list1_c< T,C1 > + > +{ + typedef list2_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2 + > +struct list3_c + : l_item< + long_<3> + , integral_c< T,C0 > + , list2_c< T,C1,C2 > + > +{ + typedef list3_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3 + > +struct list4_c + : l_item< + long_<4> + , integral_c< T,C0 > + , list3_c< T,C1,C2,C3 > + > +{ + typedef list4_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4 + > +struct list5_c + : l_item< + long_<5> + , integral_c< T,C0 > + , list4_c< T,C1,C2,C3,C4 > + > +{ + typedef list5_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5 + > +struct list6_c + : l_item< + long_<6> + , integral_c< T,C0 > + , list5_c< T,C1,C2,C3,C4,C5 > + > +{ + typedef list6_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6 + > +struct list7_c + : l_item< + long_<7> + , integral_c< T,C0 > + , list6_c< T,C1,C2,C3,C4,C5,C6 > + > +{ + typedef list7_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7 + > +struct list8_c + : l_item< + long_<8> + , integral_c< T,C0 > + , list7_c< T,C1,C2,C3,C4,C5,C6,C7 > + > +{ + typedef list8_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8 + > +struct list9_c + : l_item< + long_<9> + , integral_c< T,C0 > + , list8_c< T,C1,C2,C3,C4,C5,C6,C7,C8 > + > +{ + typedef list9_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9 + > +struct list10_c + : l_item< + long_<10> + , integral_c< T,C0 > + , list9_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9 > + > +{ + typedef list10_c type; + typedef T value_type; +}; + +}} diff --git a/boost/mpl/list/aux_/preprocessed/plain/list20.hpp b/boost/mpl/list/aux_/preprocessed/plain/list20.hpp new file mode 100644 index 00000000..750e495f --- /dev/null +++ b/boost/mpl/list/aux_/preprocessed/plain/list20.hpp @@ -0,0 +1,169 @@ + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +// Preprocessed version of "boost/mpl/list/list20.hpp" header +// -- DO NOT modify by hand! + +namespace boost { namespace mpl { + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10 + > +struct list11 + : l_item< + long_<11> + , T0 + , list10< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 > + > +{ + typedef list11 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11 + > +struct list12 + : l_item< + long_<12> + , T0 + , list11< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 > + > +{ + typedef list12 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12 + > +struct list13 + : l_item< + long_<13> + , T0 + , list12< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 > + > +{ + typedef list13 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13 + > +struct list14 + : l_item< + long_<14> + , T0 + , list13< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 > + > +{ + typedef list14 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + > +struct list15 + : l_item< + long_<15> + , T0 + , list14< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 > + > +{ + typedef list15 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15 + > +struct list16 + : l_item< + long_<16> + , T0 + , list15< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 > + > +{ + typedef list16 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16 + > +struct list17 + : l_item< + long_<17> + , T0 + , list16< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 > + > +{ + typedef list17 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17 + > +struct list18 + : l_item< + long_<18> + , T0 + , list17< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 > + > +{ + typedef list18 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18 + > +struct list19 + : l_item< + long_<19> + , T0 + , list18< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 > + > +{ + typedef list19 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + > +struct list20 + : l_item< + long_<20> + , T0 + , list19< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 > + > +{ + typedef list20 type; +}; + +}} diff --git a/boost/mpl/list/aux_/preprocessed/plain/list20_c.hpp b/boost/mpl/list/aux_/preprocessed/plain/list20_c.hpp new file mode 100644 index 00000000..7f15acf3 --- /dev/null +++ b/boost/mpl/list/aux_/preprocessed/plain/list20_c.hpp @@ -0,0 +1,173 @@ + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +// Preprocessed version of "boost/mpl/list/list20_c.hpp" header +// -- DO NOT modify by hand! + +namespace boost { namespace mpl { + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + > +struct list11_c + : l_item< + long_<11> + , integral_c< T,C0 > + , list10_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10 > + > +{ + typedef list11_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11 + > +struct list12_c + : l_item< + long_<12> + , integral_c< T,C0 > + , list11_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11 > + > +{ + typedef list12_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12 + > +struct list13_c + : l_item< + long_<13> + , integral_c< T,C0 > + , list12_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12 > + > +{ + typedef list13_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13 + > +struct list14_c + : l_item< + long_<14> + , integral_c< T,C0 > + , list13_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13 > + > +{ + typedef list14_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14 + > +struct list15_c + : l_item< + long_<15> + , integral_c< T,C0 > + , list14_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14 > + > +{ + typedef list15_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15 + > +struct list16_c + : l_item< + long_<16> + , integral_c< T,C0 > + , list15_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15 > + > +{ + typedef list16_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16 + > +struct list17_c + : l_item< + long_<17> + , integral_c< T,C0 > + , list16_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16 > + > +{ + typedef list17_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17 + > +struct list18_c + : l_item< + long_<18> + , integral_c< T,C0 > + , list17_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17 > + > +{ + typedef list18_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18 + > +struct list19_c + : l_item< + long_<19> + , integral_c< T,C0 > + , list18_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18 > + > +{ + typedef list19_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19 + > +struct list20_c + : l_item< + long_<20> + , integral_c< T,C0 > + , list19_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19 > + > +{ + typedef list20_c type; + typedef T value_type; +}; + +}} diff --git a/boost/mpl/list/aux_/preprocessed/plain/list30.hpp b/boost/mpl/list/aux_/preprocessed/plain/list30.hpp new file mode 100644 index 00000000..54591011 --- /dev/null +++ b/boost/mpl/list/aux_/preprocessed/plain/list30.hpp @@ -0,0 +1,189 @@ + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +// Preprocessed version of "boost/mpl/list/list30.hpp" header +// -- DO NOT modify by hand! + +namespace boost { namespace mpl { + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20 + > +struct list21 + : l_item< + long_<21> + , T0 + , list20< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20 > + > +{ + typedef list21 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21 + > +struct list22 + : l_item< + long_<22> + , T0 + , list21< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21 > + > +{ + typedef list22 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22 + > +struct list23 + : l_item< + long_<23> + , T0 + , list22< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22 > + > +{ + typedef list23 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23 + > +struct list24 + : l_item< + long_<24> + , T0 + , list23< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23 > + > +{ + typedef list24 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + > +struct list25 + : l_item< + long_<25> + , T0 + , list24< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24 > + > +{ + typedef list25 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25 + > +struct list26 + : l_item< + long_<26> + , T0 + , list25< 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 > + > +{ + typedef list26 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26 + > +struct list27 + : l_item< + long_<27> + , T0 + , list26< 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 > + > +{ + typedef list27 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27 + > +struct list28 + : l_item< + long_<28> + , T0 + , list27< 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 > + > +{ + typedef list28 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28 + > +struct list29 + : l_item< + long_<29> + , T0 + , list28< 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 > + > +{ + typedef list29 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + > +struct list30 + : l_item< + long_<30> + , T0 + , list29< 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 > + > +{ + typedef list30 type; +}; + +}} diff --git a/boost/mpl/list/aux_/preprocessed/plain/list30_c.hpp b/boost/mpl/list/aux_/preprocessed/plain/list30_c.hpp new file mode 100644 index 00000000..5393d792 --- /dev/null +++ b/boost/mpl/list/aux_/preprocessed/plain/list30_c.hpp @@ -0,0 +1,183 @@ + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +// Preprocessed version of "boost/mpl/list/list30_c.hpp" header +// -- DO NOT modify by hand! + +namespace boost { namespace mpl { + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + > +struct list21_c + : l_item< + long_<21> + , integral_c< T,C0 > + , list20_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20 > + > +{ + typedef list21_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21 + > +struct list22_c + : l_item< + long_<22> + , integral_c< T,C0 > + , list21_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21 > + > +{ + typedef list22_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22 + > +struct list23_c + : l_item< + long_<23> + , integral_c< T,C0 > + , list22_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22 > + > +{ + typedef list23_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23 + > +struct list24_c + : l_item< + long_<24> + , integral_c< T,C0 > + , list23_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23 > + > +{ + typedef list24_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24 + > +struct list25_c + : l_item< + long_<25> + , integral_c< T,C0 > + , list24_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24 > + > +{ + typedef list25_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25 + > +struct list26_c + : l_item< + long_<26> + , integral_c< T,C0 > + , list25_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25 > + > +{ + typedef list26_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26 + > +struct list27_c + : l_item< + long_<27> + , integral_c< T,C0 > + , list26_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26 > + > +{ + typedef list27_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27 + > +struct list28_c + : l_item< + long_<28> + , integral_c< T,C0 > + , list27_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27 > + > +{ + typedef list28_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28 + > +struct list29_c + : l_item< + long_<29> + , integral_c< T,C0 > + , list28_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28 > + > +{ + typedef list29_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29 + > +struct list30_c + : l_item< + long_<30> + , integral_c< T,C0 > + , list29_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29 > + > +{ + typedef list30_c type; + typedef T value_type; +}; + +}} diff --git a/boost/mpl/list/aux_/preprocessed/plain/list40.hpp b/boost/mpl/list/aux_/preprocessed/plain/list40.hpp new file mode 100644 index 00000000..68c67613 --- /dev/null +++ b/boost/mpl/list/aux_/preprocessed/plain/list40.hpp @@ -0,0 +1,209 @@ + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +// Preprocessed version of "boost/mpl/list/list40.hpp" header +// -- DO NOT modify by hand! + +namespace boost { namespace mpl { + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30 + > +struct list31 + : l_item< + long_<31> + , T0 + , list30< 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 > + > +{ + typedef list31 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31 + > +struct list32 + : l_item< + long_<32> + , T0 + , list31< 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 > + > +{ + typedef list32 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32 + > +struct list33 + : l_item< + long_<33> + , T0 + , list32< 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 > + > +{ + typedef list33 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33 + > +struct list34 + : l_item< + long_<34> + , T0 + , list33< 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 > + > +{ + typedef list34 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + > +struct list35 + : l_item< + long_<35> + , T0 + , list34< 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 > + > +{ + typedef list35 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35 + > +struct list36 + : l_item< + long_<36> + , T0 + , list35< 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 > + > +{ + typedef list36 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35, typename T36 + > +struct list37 + : l_item< + long_<37> + , T0 + , list36< 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 > + > +{ + typedef list37 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35, typename T36, typename T37 + > +struct list38 + : l_item< + long_<38> + , T0 + , list37< 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 > + > +{ + typedef list38 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35, typename T36, typename T37, typename T38 + > +struct list39 + : l_item< + long_<39> + , T0 + , list38< 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 > + > +{ + typedef list39 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35, typename T36, typename T37, typename T38, typename T39 + > +struct list40 + : l_item< + long_<40> + , T0 + , list39< 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 > + > +{ + typedef list40 type; +}; + +}} diff --git a/boost/mpl/list/aux_/preprocessed/plain/list40_c.hpp b/boost/mpl/list/aux_/preprocessed/plain/list40_c.hpp new file mode 100644 index 00000000..0c51ba20 --- /dev/null +++ b/boost/mpl/list/aux_/preprocessed/plain/list40_c.hpp @@ -0,0 +1,193 @@ + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +// Preprocessed version of "boost/mpl/list/list40_c.hpp" header +// -- DO NOT modify by hand! + +namespace boost { namespace mpl { + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + > +struct list31_c + : l_item< + long_<31> + , integral_c< T,C0 > + , list30_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30 > + > +{ + typedef list31_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31 + > +struct list32_c + : l_item< + long_<32> + , integral_c< T,C0 > + , list31_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31 > + > +{ + typedef list32_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32 + > +struct list33_c + : l_item< + long_<33> + , integral_c< T,C0 > + , list32_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32 > + > +{ + typedef list33_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33 + > +struct list34_c + : l_item< + long_<34> + , integral_c< T,C0 > + , list33_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33 > + > +{ + typedef list34_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34 + > +struct list35_c + : l_item< + long_<35> + , integral_c< T,C0 > + , list34_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34 > + > +{ + typedef list35_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35 + > +struct list36_c + : l_item< + long_<36> + , integral_c< T,C0 > + , list35_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35 > + > +{ + typedef list36_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35, T C36 + > +struct list37_c + : l_item< + long_<37> + , integral_c< T,C0 > + , list36_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36 > + > +{ + typedef list37_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35, T C36, T C37 + > +struct list38_c + : l_item< + long_<38> + , integral_c< T,C0 > + , list37_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37 > + > +{ + typedef list38_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38 + > +struct list39_c + : l_item< + long_<39> + , integral_c< T,C0 > + , list38_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38 > + > +{ + typedef list39_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39 + > +struct list40_c + : l_item< + long_<40> + , integral_c< T,C0 > + , list39_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39 > + > +{ + typedef list40_c type; + typedef T value_type; +}; + +}} diff --git a/boost/mpl/list/aux_/preprocessed/plain/list50.hpp b/boost/mpl/list/aux_/preprocessed/plain/list50.hpp new file mode 100644 index 00000000..4cc22da2 --- /dev/null +++ b/boost/mpl/list/aux_/preprocessed/plain/list50.hpp @@ -0,0 +1,229 @@ + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +// Preprocessed version of "boost/mpl/list/list50.hpp" header +// -- DO NOT modify by hand! + +namespace boost { namespace mpl { + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35, typename T36, typename T37, typename T38, typename T39 + , typename T40 + > +struct list41 + : l_item< + long_<41> + , T0 + , list40< 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 > + > +{ + typedef list41 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35, typename T36, typename T37, typename T38, typename T39 + , typename T40, typename T41 + > +struct list42 + : l_item< + long_<42> + , T0 + , list41< 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 > + > +{ + typedef list42 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35, typename T36, typename T37, typename T38, typename T39 + , typename T40, typename T41, typename T42 + > +struct list43 + : l_item< + long_<43> + , T0 + , list42< 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 > + > +{ + typedef list43 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35, typename T36, typename T37, typename T38, typename T39 + , typename T40, typename T41, typename T42, typename T43 + > +struct list44 + : l_item< + long_<44> + , T0 + , list43< 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 > + > +{ + typedef list44 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35, typename T36, typename T37, typename T38, typename T39 + , typename T40, typename T41, typename T42, typename T43, typename T44 + > +struct list45 + : l_item< + long_<45> + , T0 + , list44< 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 > + > +{ + typedef list45 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35, typename T36, typename T37, typename T38, typename T39 + , typename T40, typename T41, typename T42, typename T43, typename T44 + , typename T45 + > +struct list46 + : l_item< + long_<46> + , T0 + , list45< 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 > + > +{ + typedef list46 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35, typename T36, typename T37, typename T38, typename T39 + , typename T40, typename T41, typename T42, typename T43, typename T44 + , typename T45, typename T46 + > +struct list47 + : l_item< + long_<47> + , T0 + , list46< 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 > + > +{ + typedef list47 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35, typename T36, typename T37, typename T38, typename T39 + , typename T40, typename T41, typename T42, typename T43, typename T44 + , typename T45, typename T46, typename T47 + > +struct list48 + : l_item< + long_<48> + , T0 + , list47< 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 > + > +{ + typedef list48 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35, typename T36, typename T37, typename T38, typename T39 + , typename T40, typename T41, typename T42, typename T43, typename T44 + , typename T45, typename T46, typename T47, typename T48 + > +struct list49 + : l_item< + long_<49> + , T0 + , list48< 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 > + > +{ + typedef list49 type; +}; + +template< + typename T0, typename T1, typename T2, typename T3, typename T4 + , typename T5, typename T6, typename T7, typename T8, typename T9 + , typename T10, typename T11, typename T12, typename T13, typename T14 + , typename T15, typename T16, typename T17, typename T18, typename T19 + , typename T20, typename T21, typename T22, typename T23, typename T24 + , typename T25, typename T26, typename T27, typename T28, typename T29 + , typename T30, typename T31, typename T32, typename T33, typename T34 + , typename T35, typename T36, typename T37, typename T38, typename T39 + , typename T40, typename T41, typename T42, typename T43, typename T44 + , typename T45, typename T46, typename T47, typename T48, typename T49 + > +struct list50 + : l_item< + long_<50> + , T0 + , list49< 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 > + > +{ + typedef list50 type; +}; + +}} diff --git a/boost/mpl/list/aux_/preprocessed/plain/list50_c.hpp b/boost/mpl/list/aux_/preprocessed/plain/list50_c.hpp new file mode 100644 index 00000000..28c061d5 --- /dev/null +++ b/boost/mpl/list/aux_/preprocessed/plain/list50_c.hpp @@ -0,0 +1,203 @@ + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +// Preprocessed version of "boost/mpl/list/list50_c.hpp" header +// -- DO NOT modify by hand! + +namespace boost { namespace mpl { + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 + > +struct list41_c + : l_item< + long_<41> + , integral_c< T,C0 > + , list40_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40 > + > +{ + typedef list41_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 + , T C41 + > +struct list42_c + : l_item< + long_<42> + , integral_c< T,C0 > + , list41_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41 > + > +{ + typedef list42_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 + , T C41, T C42 + > +struct list43_c + : l_item< + long_<43> + , integral_c< T,C0 > + , list42_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42 > + > +{ + typedef list43_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 + , T C41, T C42, T C43 + > +struct list44_c + : l_item< + long_<44> + , integral_c< T,C0 > + , list43_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42,C43 > + > +{ + typedef list44_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 + , T C41, T C42, T C43, T C44 + > +struct list45_c + : l_item< + long_<45> + , integral_c< T,C0 > + , list44_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42,C43,C44 > + > +{ + typedef list45_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 + , T C41, T C42, T C43, T C44, T C45 + > +struct list46_c + : l_item< + long_<46> + , integral_c< T,C0 > + , list45_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42,C43,C44,C45 > + > +{ + typedef list46_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 + , T C41, T C42, T C43, T C44, T C45, T C46 + > +struct list47_c + : l_item< + long_<47> + , integral_c< T,C0 > + , list46_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42,C43,C44,C45,C46 > + > +{ + typedef list47_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 + , T C41, T C42, T C43, T C44, T C45, T C46, T C47 + > +struct list48_c + : l_item< + long_<48> + , integral_c< T,C0 > + , list47_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42,C43,C44,C45,C46,C47 > + > +{ + typedef list48_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 + , T C41, T C42, T C43, T C44, T C45, T C46, T C47, T C48 + > +struct list49_c + : l_item< + long_<49> + , integral_c< T,C0 > + , list48_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42,C43,C44,C45,C46,C47,C48 > + > +{ + typedef list49_c type; + typedef T value_type; +}; + +template< + typename T + , T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10 + , T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20 + , T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30 + , T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39, T C40 + , T C41, T C42, T C43, T C44, T C45, T C46, T C47, T C48, T C49 + > +struct list50_c + : l_item< + long_<50> + , integral_c< T,C0 > + , list49_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39,C40,C41,C42,C43,C44,C45,C46,C47,C48,C49 > + > +{ + typedef list50_c type; + typedef T value_type; +}; + +}} diff --git a/boost/mpl/list/aux_/push_back.hpp b/boost/mpl/list/aux_/push_back.hpp new file mode 100644 index 00000000..8f3b73e4 --- /dev/null +++ b/boost/mpl/list/aux_/push_back.hpp @@ -0,0 +1,36 @@ + +#ifndef BOOST_MPL_LIST_AUX_PUSH_BACK_HPP_INCLUDED +#define BOOST_MPL_LIST_AUX_PUSH_BACK_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include + +namespace boost { namespace mpl { + +template< typename Tag > struct has_push_back_impl; + +template<> +struct has_push_back_impl< aux::list_tag > +{ + template< typename Seq > struct apply + : false_ + { + }; +}; + +}} + +#endif // BOOST_MPL_LIST_AUX_PUSH_BACK_HPP_INCLUDED diff --git a/boost/mpl/list/aux_/push_front.hpp b/boost/mpl/list/aux_/push_front.hpp new file mode 100644 index 00000000..fcfbe4ab --- /dev/null +++ b/boost/mpl/list/aux_/push_front.hpp @@ -0,0 +1,39 @@ + +#ifndef BOOST_MPL_LIST_AUX_PUSH_FRONT_HPP_INCLUDED +#define BOOST_MPL_LIST_AUX_PUSH_FRONT_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template<> +struct push_front_impl< aux::list_tag > +{ + template< typename List, typename T > struct apply + { + typedef l_item< + typename next::type + , T + , typename List::type + > type; + }; +}; + +}} + +#endif // BOOST_MPL_LIST_AUX_PUSH_FRONT_HPP_INCLUDED diff --git a/boost/mpl/list/aux_/size.hpp b/boost/mpl/list/aux_/size.hpp new file mode 100644 index 00000000..f5e7feaf --- /dev/null +++ b/boost/mpl/list/aux_/size.hpp @@ -0,0 +1,33 @@ + +#ifndef BOOST_MPL_LIST_AUX_SIZE_HPP_INCLUDED +#define BOOST_MPL_LIST_AUX_SIZE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include + +namespace boost { namespace mpl { + +template<> +struct size_impl< aux::list_tag > +{ + template< typename List > struct apply + : List::size + { + }; +}; + +}} + +#endif // BOOST_MPL_LIST_AUX_SIZE_HPP_INCLUDED diff --git a/boost/mpl/list/aux_/tag.hpp b/boost/mpl/list/aux_/tag.hpp new file mode 100644 index 00000000..f5ed2bbf --- /dev/null +++ b/boost/mpl/list/aux_/tag.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_LIST_AUX_TAG_HPP_INCLUDED +#define BOOST_MPL_LIST_AUX_TAG_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +namespace boost { namespace mpl { namespace aux { + +struct list_tag; +struct l_iter_tag; + +}}} + +#endif // BOOST_MPL_LIST_AUX_TAG_HPP_INCLUDED diff --git a/boost/mpl/list/list0.hpp b/boost/mpl/list/list0.hpp new file mode 100644 index 00000000..8e06b8d0 --- /dev/null +++ b/boost/mpl/list/list0.hpp @@ -0,0 +1,42 @@ + +#ifndef BOOST_MPL_LIST_LIST0_HPP_INCLUDED +#define BOOST_MPL_LIST_LIST0_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< typename Dummy = na > struct list0; + +template<> struct list0 + : l_end +{ + typedef l_end type; +}; + +}} + +#endif // BOOST_MPL_LIST_LIST0_HPP_INCLUDED diff --git a/boost/mpl/list/list0_c.hpp b/boost/mpl/list/list0_c.hpp new file mode 100644 index 00000000..807ca1c2 --- /dev/null +++ b/boost/mpl/list/list0_c.hpp @@ -0,0 +1,31 @@ + +#ifndef BOOST_MPL_LIST_LIST0_C_HPP_INCLUDED +#define BOOST_MPL_LIST_LIST0_C_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include + +namespace boost { namespace mpl { + +template< typename T > struct list0_c + : l_end +{ + typedef l_end type; + typedef T value_type; +}; + +}} + +#endif // BOOST_MPL_LIST_LIST0_C_HPP_INCLUDED diff --git a/boost/mpl/list/list10.hpp b/boost/mpl/list/list10.hpp new file mode 100644 index 00000000..d32d0d8c --- /dev/null +++ b/boost/mpl/list/list10.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_MPL_LIST_LIST10_HPP_INCLUDED +#define BOOST_MPL_LIST_LIST10_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER list10.hpp +# include + +#else + +# include + +namespace boost { namespace mpl { + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(1, 10, )) +# include BOOST_PP_ITERATE() + +}} + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +#endif // BOOST_MPL_LIST_LIST10_HPP_INCLUDED diff --git a/boost/mpl/list/list10_c.hpp b/boost/mpl/list/list10_c.hpp new file mode 100644 index 00000000..25c8f9de --- /dev/null +++ b/boost/mpl/list/list10_c.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_MPL_LIST_LIST10_C_HPP_INCLUDED +#define BOOST_MPL_LIST_LIST10_C_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER list10_c.hpp +# include + +#else + +# include + +namespace boost { namespace mpl { + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(1, 10, )) +# include BOOST_PP_ITERATE() + +}} + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +#endif // BOOST_MPL_LIST_LIST10_C_HPP_INCLUDED diff --git a/boost/mpl/list/list20.hpp b/boost/mpl/list/list20.hpp new file mode 100644 index 00000000..724cabd2 --- /dev/null +++ b/boost/mpl/list/list20.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_MPL_LIST_LIST20_HPP_INCLUDED +#define BOOST_MPL_LIST_LIST20_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER list20.hpp +# include + +#else + +# include + +namespace boost { namespace mpl { + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(11, 20, )) +# include BOOST_PP_ITERATE() + +}} + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +#endif // BOOST_MPL_LIST_LIST20_HPP_INCLUDED diff --git a/boost/mpl/list/list20_c.hpp b/boost/mpl/list/list20_c.hpp new file mode 100644 index 00000000..0026f695 --- /dev/null +++ b/boost/mpl/list/list20_c.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_MPL_LIST_LIST20_C_HPP_INCLUDED +#define BOOST_MPL_LIST_LIST20_C_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER list20_c.hpp +# include + +#else + +# include + +namespace boost { namespace mpl { + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(11, 20, )) +# include BOOST_PP_ITERATE() + +}} + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +#endif // BOOST_MPL_LIST_LIST20_C_HPP_INCLUDED diff --git a/boost/mpl/list/list30.hpp b/boost/mpl/list/list30.hpp new file mode 100644 index 00000000..a9004c73 --- /dev/null +++ b/boost/mpl/list/list30.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_MPL_LIST_LIST30_HPP_INCLUDED +#define BOOST_MPL_LIST_LIST30_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER list30.hpp +# include + +#else + +# include + +namespace boost { namespace mpl { + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(21, 30, )) +# include BOOST_PP_ITERATE() + +}} + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +#endif // BOOST_MPL_LIST_LIST30_HPP_INCLUDED diff --git a/boost/mpl/list/list30_c.hpp b/boost/mpl/list/list30_c.hpp new file mode 100644 index 00000000..c9965747 --- /dev/null +++ b/boost/mpl/list/list30_c.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_MPL_LIST_LIST30_C_HPP_INCLUDED +#define BOOST_MPL_LIST_LIST30_C_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER list30_c.hpp +# include + +#else + +# include + +namespace boost { namespace mpl { + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(21, 30, )) +# include BOOST_PP_ITERATE() + +}} + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +#endif // BOOST_MPL_LIST_LIST30_C_HPP_INCLUDED diff --git a/boost/mpl/list/list40.hpp b/boost/mpl/list/list40.hpp new file mode 100644 index 00000000..02f869ef --- /dev/null +++ b/boost/mpl/list/list40.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_MPL_LIST_LIST40_HPP_INCLUDED +#define BOOST_MPL_LIST_LIST40_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER list40.hpp +# include + +#else + +# include + +namespace boost { namespace mpl { + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(31, 40, )) +# include BOOST_PP_ITERATE() + +}} + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +#endif // BOOST_MPL_LIST_LIST40_HPP_INCLUDED diff --git a/boost/mpl/list/list40_c.hpp b/boost/mpl/list/list40_c.hpp new file mode 100644 index 00000000..808d599d --- /dev/null +++ b/boost/mpl/list/list40_c.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_MPL_LIST_LIST40_C_HPP_INCLUDED +#define BOOST_MPL_LIST_LIST40_C_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER list40_c.hpp +# include + +#else + +# include + +namespace boost { namespace mpl { + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(31, 40, )) +# include BOOST_PP_ITERATE() + +}} + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +#endif // BOOST_MPL_LIST_LIST40_C_HPP_INCLUDED diff --git a/boost/mpl/list/list50.hpp b/boost/mpl/list/list50.hpp new file mode 100644 index 00000000..f16c68ce --- /dev/null +++ b/boost/mpl/list/list50.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_MPL_LIST_LIST50_HPP_INCLUDED +#define BOOST_MPL_LIST_LIST50_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER list50.hpp +# include + +#else + +# include + +namespace boost { namespace mpl { + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(41, 50, )) +# include BOOST_PP_ITERATE() + +}} + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +#endif // BOOST_MPL_LIST_LIST50_HPP_INCLUDED diff --git a/boost/mpl/list/list50_c.hpp b/boost/mpl/list/list50_c.hpp new file mode 100644 index 00000000..20692d89 --- /dev/null +++ b/boost/mpl/list/list50_c.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_MPL_LIST_LIST50_C_HPP_INCLUDED +#define BOOST_MPL_LIST_LIST50_C_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include +#endif + +#include + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER list50_c.hpp +# include + +#else + +# include + +namespace boost { namespace mpl { + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3,(41, 50, )) +# include BOOST_PP_ITERATE() + +}} + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +#endif // BOOST_MPL_LIST_LIST50_C_HPP_INCLUDED diff --git a/boost/mpl/long.hpp b/boost/mpl/long.hpp new file mode 100644 index 00000000..c4552673 --- /dev/null +++ b/boost/mpl/long.hpp @@ -0,0 +1,22 @@ + +#ifndef BOOST_MPL_LONG_HPP_INCLUDED +#define BOOST_MPL_LONG_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include + +#define AUX_WRAPPER_VALUE_TYPE long +#include + +#endif // BOOST_MPL_LONG_HPP_INCLUDED diff --git a/boost/mpl/long_fwd.hpp b/boost/mpl/long_fwd.hpp new file mode 100644 index 00000000..5f62f2b8 --- /dev/null +++ b/boost/mpl/long_fwd.hpp @@ -0,0 +1,27 @@ + +#ifndef BOOST_MPL_LONG_FWD_HPP_INCLUDED +#define BOOST_MPL_LONG_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include + +BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN + +template< BOOST_MPL_AUX_NTTP_DECL(long, N) > struct long_; + +BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE +BOOST_MPL_AUX_ADL_BARRIER_DECL(long_) + +#endif // BOOST_MPL_LONG_FWD_HPP_INCLUDED diff --git a/boost/mpl/max_element.hpp b/boost/mpl/max_element.hpp new file mode 100644 index 00000000..33244f36 --- /dev/null +++ b/boost/mpl/max_element.hpp @@ -0,0 +1,72 @@ + +#ifndef BOOST_MPL_MAX_ELEMENT_HPP_INCLUDED +#define BOOST_MPL_MAX_ELEMENT_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +BOOST_MPL_AUX_COMMON_NAME_WKND(max_element) + +namespace aux { + +template< typename Predicate > +struct select_max +{ + template< typename OldIterator, typename Iterator > + struct apply + { + typedef typename apply2< + Predicate + , typename deref::type + , typename deref::type + >::type condition_; + + typedef typename if_< + condition_ + , Iterator + , OldIterator + >::type type; + }; +}; + +} // namespace aux + + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + , typename Predicate = less<_,_> + > +struct max_element + : iter_fold< + Sequence + , typename begin::type + , protect< aux::select_max > + > +{ +}; + +BOOST_MPL_AUX_NA_SPEC(1, max_element) + +}} + +#endif // BOOST_MPL_MAX_ELEMENT_HPP_INCLUDED diff --git a/boost/mpl/min_max.hpp b/boost/mpl/min_max.hpp new file mode 100644 index 00000000..77545cd3 --- /dev/null +++ b/boost/mpl/min_max.hpp @@ -0,0 +1,46 @@ + +#ifndef BOOST_MPL_MIN_MAX_HPP_INCLUDED +#define BOOST_MPL_MIN_MAX_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-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/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(N1) + , typename BOOST_MPL_AUX_NA_PARAM(N2) + > +struct min + : if_< less,N1,N2 > +{ +}; + +template< + typename BOOST_MPL_AUX_NA_PARAM(N1) + , typename BOOST_MPL_AUX_NA_PARAM(N2) + > +struct max + : if_< less,N2,N1 > +{ +}; + +BOOST_MPL_AUX_NA_SPEC(2, min) +BOOST_MPL_AUX_NA_SPEC(2, max) + +}} + +#endif // BOOST_MPL_MIN_MAX_HPP_INCLUDED diff --git a/boost/mpl/negate.hpp b/boost/mpl/negate.hpp new file mode 100644 index 00000000..d6aa0654 --- /dev/null +++ b/boost/mpl/negate.hpp @@ -0,0 +1,81 @@ + +#ifndef BOOST_MPL_NEGATE_HPP_INCLUDED +#define BOOST_MPL_NEGATE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< typename Tag > struct negate_impl; + +template< typename T > struct negate_tag +{ + typedef typename T::tag type; +}; + +template< + typename BOOST_MPL_AUX_NA_PARAM(N) + > +struct negate +#if !defined(BOOST_MPL_CFG_MSVC_ETI_BUG) + : negate_impl< + typename negate_tag::type + >::template apply::type +#else + : aux::msvc_eti_base< typename apply_wrap1< + negate_impl< typename negate_tag::type > + , N + >::type >::type +#endif +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1, negate, (N)) +}; + +BOOST_MPL_AUX_NA_SPEC(1, negate) + + +#if defined(BOOST_MPL_CFG_NO_NESTED_VALUE_ARITHMETIC) +namespace aux { +template< typename T, T n > struct negate_wknd +{ + BOOST_STATIC_CONSTANT(T, value = -n); + typedef integral_c type; +}; +} +#endif + +template<> +struct negate_impl +{ +#if defined(BOOST_MPL_CFG_NO_NESTED_VALUE_ARITHMETIC) + template< typename N > struct apply + : aux::negate_wknd< typename N::value_type, N::value > +#else + template< typename N > struct apply + : integral_c< typename N::value_type, (-N::value) > +#endif + { + }; +}; + +}} + +#endif // BOOST_MPL_NEGATE_HPP_INCLUDED diff --git a/boost/mpl/pair.hpp b/boost/mpl/pair.hpp new file mode 100644 index 00000000..67c01d73 --- /dev/null +++ b/boost/mpl/pair.hpp @@ -0,0 +1,70 @@ + +#ifndef BOOST_MPL_PAIR_HPP_INCLUDED +#define BOOST_MPL_PAIR_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2001-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(T1) + , typename BOOST_MPL_AUX_NA_PARAM(T2) + > +struct pair +{ + typedef pair type; + typedef T1 first; + typedef T2 second; + + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,pair,(T1,T2)) +}; + +template< + typename BOOST_MPL_AUX_NA_PARAM(P) + > +struct first +{ +#if !defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG) + typedef typename P::first type; +#else + typedef typename aux::msvc_eti_base

::first type; +#endif + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,first,(P)) +}; + +template< + typename BOOST_MPL_AUX_NA_PARAM(P) + > +struct second +{ +#if !defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG) + typedef typename P::second type; +#else + typedef typename aux::msvc_eti_base

::second type; +#endif + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,second,(P)) +}; + + +BOOST_MPL_AUX_NA_SPEC_NO_ETI(2, pair) +BOOST_MPL_AUX_NA_SPEC(1, first) +BOOST_MPL_AUX_NA_SPEC(1, second) + +}} + +#endif // BOOST_MPL_PAIR_HPP_INCLUDED diff --git a/boost/mpl/pair_view.hpp b/boost/mpl/pair_view.hpp new file mode 100644 index 00000000..a72cf928 --- /dev/null +++ b/boost/mpl/pair_view.hpp @@ -0,0 +1,169 @@ + +#ifndef BOOST_MPL_PAIR_VIEW_HPP_INCLUDED +#define BOOST_MPL_PAIR_VIEW_HPP_INCLUDED + +// Copyright David Abrahams 2003-2004 +// Copyright Aleksey Gurtovoy 2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +namespace aux { +struct pair_iter_tag; + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template< typename Iter1, typename Iter2, typename Category > +struct pair_iter; + +template< typename Category > struct prior_pair_iter +{ + template< typename Iter1, typename Iter2 > struct apply + { + typedef typename mpl::prior::type i1_; + typedef typename mpl::prior::type i2_; + typedef pair_iter type; + }; +}; + +template<> struct prior_pair_iter +{ + template< typename Iter1, typename Iter2 > struct apply + { + typedef pair_iter type; + }; +}; + +#endif +} + +template< + typename Iter1 + , typename Iter2 + , typename Category + > +struct pair_iter +{ + typedef aux::pair_iter_tag tag; + typedef Category category; + typedef Iter1 first; + typedef Iter2 second; + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + typedef pair< + typename deref::type + , typename deref::type + > type; + + typedef typename mpl::next::type i1_; + typedef typename mpl::next::type i2_; + typedef pair_iter next; + + typedef apply_wrap2< aux::prior_pair_iter,Iter1,Iter2 >::type prior; +#endif +}; + + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template< typename Iter1, typename Iter2, typename C > +struct deref< pair_iter > +{ + typedef pair< + typename deref::type + , typename deref::type + > type; +}; + +template< typename Iter1, typename Iter2, typename C > +struct next< pair_iter > +{ + typedef typename mpl::next::type i1_; + typedef typename mpl::next::type i2_; + typedef pair_iter type; +}; + +template< typename Iter1, typename Iter2, typename C > +struct prior< pair_iter > +{ + typedef typename mpl::prior::type i1_; + typedef typename mpl::prior::type i2_; + typedef pair_iter type; +}; + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + +template<> struct advance_impl +{ + template< typename Iter, typename D > struct apply + { + typedef typename mpl::advance< typename Iter::first,D >::type i1_; + typedef typename mpl::advance< typename Iter::second,D >::type i2_; + typedef pair_iter type; + }; +}; + +template<> struct distance_impl +{ + template< typename Iter1, typename Iter2 > struct apply + { + // agurt, 10/nov/04: MSVC 6.5 ICE-s on forwarding + typedef typename mpl::distance< + typename first::type + , typename first::type + >::type type; + }; +}; + + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence1) + , typename BOOST_MPL_AUX_NA_PARAM(Sequence2) + > +struct pair_view +{ + typedef nested_begin_end_tag tag; + + typedef typename begin::type iter1_; + typedef typename begin::type iter2_; + typedef typename min< + typename iterator_category::type + , typename iterator_category::type + >::type category_; + + typedef pair_iter begin; + + typedef pair_iter< + typename end::type + , typename end::type + , category_ + > end; +}; + +BOOST_MPL_AUX_NA_SPEC(2, pair_view) + +}} + +#endif // BOOST_MPL_PAIR_VIEW_HPP_INCLUDED diff --git a/boost/mpl/plus.hpp b/boost/mpl/plus.hpp new file mode 100644 index 00000000..455920b5 --- /dev/null +++ b/boost/mpl/plus.hpp @@ -0,0 +1,21 @@ + +#ifndef BOOST_MPL_PLUS_HPP_INCLUDED +#define BOOST_MPL_PLUS_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#define AUX778076_OP_NAME plus +#define AUX778076_OP_TOKEN + +#include + +#endif // BOOST_MPL_PLUS_HPP_INCLUDED diff --git a/boost/mpl/pop_front_fwd.hpp b/boost/mpl/pop_front_fwd.hpp new file mode 100644 index 00000000..719c8b21 --- /dev/null +++ b/boost/mpl/pop_front_fwd.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_POP_FRONT_FWD_HPP_INCLUDED +#define BOOST_MPL_POP_FRONT_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +namespace boost { namespace mpl { + +template< typename Tag > struct pop_front_impl; +template< typename Sequence > struct pop_front; + +}} + +#endif // BOOST_MPL_POP_FRONT_FWD_HPP_INCLUDED diff --git a/boost/mpl/prior.hpp b/boost/mpl/prior.hpp new file mode 100644 index 00000000..849802cf --- /dev/null +++ b/boost/mpl/prior.hpp @@ -0,0 +1,19 @@ + +#ifndef BOOST_MPL_PRIOR_HPP_INCLUDED +#define BOOST_MPL_PRIOR_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include + +#endif // BOOST_MPL_PRIOR_HPP_INCLUDED diff --git a/boost/mpl/push_back.hpp b/boost/mpl/push_back.hpp new file mode 100644 index 00000000..95a2587b --- /dev/null +++ b/boost/mpl/push_back.hpp @@ -0,0 +1,53 @@ + +#ifndef BOOST_MPL_PUSH_BACK_HPP_INCLUDED +#define BOOST_MPL_PUSH_BACK_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + , typename BOOST_MPL_AUX_NA_PARAM(T) + > +struct push_back + : push_back_impl< typename sequence_tag::type > + ::template apply< Sequence,T > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,push_back,(Sequence,T)) +}; + + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + > +struct has_push_back + : has_push_back_impl< typename sequence_tag::type > + ::template apply< Sequence > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,has_push_back,(Sequence)) +}; + + +BOOST_MPL_AUX_NA_SPEC(2, push_back) +BOOST_MPL_AUX_NA_SPEC(1, has_push_back) + +}} + +#endif // BOOST_MPL_PUSH_BACK_HPP_INCLUDED diff --git a/boost/mpl/push_back_fwd.hpp b/boost/mpl/push_back_fwd.hpp new file mode 100644 index 00000000..7a4f7a75 --- /dev/null +++ b/boost/mpl/push_back_fwd.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_PUSH_BACK_FWD_HPP_INCLUDED +#define BOOST_MPL_PUSH_BACK_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +namespace boost { namespace mpl { + +template< typename Tag > struct push_back_impl; +template< typename Sequence, typename T > struct push_back; + +}} + +#endif // BOOST_MPL_PUSH_BACK_FWD_HPP_INCLUDED diff --git a/boost/mpl/push_front.hpp b/boost/mpl/push_front.hpp new file mode 100644 index 00000000..e4d0dfb7 --- /dev/null +++ b/boost/mpl/push_front.hpp @@ -0,0 +1,52 @@ + +#ifndef BOOST_MPL_PUSH_FRONT_HPP_INCLUDED +#define BOOST_MPL_PUSH_FRONT_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + , typename BOOST_MPL_AUX_NA_PARAM(T) + > +struct push_front + : push_front_impl< typename sequence_tag::type > + ::template apply< Sequence,T > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,push_front,(Sequence,T)) +}; + + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + > +struct has_push_front + : has_push_front_impl< typename sequence_tag::type > + ::template apply< Sequence > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,has_push_front,(Sequence)) +}; + +BOOST_MPL_AUX_NA_SPEC(2, push_front) +BOOST_MPL_AUX_NA_SPEC(1, has_push_front) + +}} + +#endif // BOOST_MPL_PUSH_FRONT_HPP_INCLUDED diff --git a/boost/mpl/push_front_fwd.hpp b/boost/mpl/push_front_fwd.hpp new file mode 100644 index 00000000..d6ad5af5 --- /dev/null +++ b/boost/mpl/push_front_fwd.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_PUSH_FRONT_FWD_HPP_INCLUDED +#define BOOST_MPL_PUSH_FRONT_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +namespace boost { namespace mpl { + +template< typename Tag > struct push_front_impl; +template< typename Sequence, typename T > struct push_front; + +}} + +#endif // BOOST_MPL_PUSH_FRONT_FWD_HPP_INCLUDED diff --git a/boost/mpl/reverse_fold.hpp b/boost/mpl/reverse_fold.hpp new file mode 100644 index 00000000..87c26a9a --- /dev/null +++ b/boost/mpl/reverse_fold.hpp @@ -0,0 +1,50 @@ + +#ifndef BOOST_MPL_REVERSE_FOLD_HPP_INCLUDED +#define BOOST_MPL_REVERSE_FOLD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2001-2004 +// Copyright David Abrahams 2001-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) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + , typename BOOST_MPL_AUX_NA_PARAM(State) + , typename BOOST_MPL_AUX_NA_PARAM(BackwardOp) + , typename ForwardOp = arg<1> + > +struct reverse_fold +{ + typedef typename aux::reverse_fold_impl< + ::boost::mpl::O1_size::value + , typename begin::type + , typename end::type + , State + , BackwardOp + , ForwardOp + >::state type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT(3,reverse_fold,(Sequence,State,BackwardOp)) +}; + +BOOST_MPL_AUX_NA_SPEC(3, reverse_fold) + +}} + +#endif // BOOST_MPL_REVERSE_FOLD_HPP_INCLUDED diff --git a/boost/mpl/same_as.hpp b/boost/mpl/same_as.hpp new file mode 100644 index 00000000..4be20bc3 --- /dev/null +++ b/boost/mpl/same_as.hpp @@ -0,0 +1,55 @@ + +#ifndef BOOST_MPL_SAME_AS_HPP_INCLUDED +#define BOOST_MPL_SAME_AS_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include + +#include + +namespace boost { namespace mpl { + +template< typename T1 > +struct same_as +{ + template< typename T2 > struct apply +#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) + : is_same + { +#else + { + typedef typename is_same::type type; +#endif + }; +}; + +template< typename T1 > +struct not_same_as +{ + template< typename T2 > struct apply +#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) + : not_< is_same > + { +#else + { + typedef typename not_< is_same >::type type; +#endif + }; +}; + +}} + +#endif // BOOST_MPL_SAME_AS_HPP_INCLUDED diff --git a/boost/mpl/sequence_tag.hpp b/boost/mpl/sequence_tag.hpp new file mode 100644 index 00000000..f87d92b2 --- /dev/null +++ b/boost/mpl/sequence_tag.hpp @@ -0,0 +1,124 @@ + +#ifndef BOOST_MPL_SEQUENCE_TAG_HPP_INCLUDED +#define BOOST_MPL_SEQUENCE_TAG_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +// agurt, 27/nov/02: have to use a simplistic 'sequence_tag' implementation +// on MSVC to avoid dreadful "internal structure overflow" error +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) \ + || defined(BOOST_MPL_CFG_NO_HAS_XXX) + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + > +struct sequence_tag +{ + typedef typename Sequence::tag type; +}; + +#elif BOOST_WORKAROUND(BOOST_MSVC, == 1300) + +// agurt, 07/feb/03: workaround for what seems to be MSVC 7.0-specific ETI issue + +namespace aux { + +template< bool > +struct sequence_tag_impl +{ + template< typename Sequence > struct result_ + { + typedef typename Sequence::tag type; + }; +}; + +template<> +struct sequence_tag_impl +{ + template< typename Sequence > struct result_ + { + typedef int type; + }; +}; + +} // namespace aux + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + > +struct sequence_tag + : aux::sequence_tag_impl< !aux::is_msvc_eti_arg::value > + ::template result_ +{ +}; + +#else + +namespace aux { + +template< bool has_tag_, bool has_begin_ > +struct sequence_tag_impl +{ + // agurt 24/nov/02: MSVC 6.5 gets confused in 'sequence_tag_impl' + // specialization below, if we name it 'result_' here + template< typename Sequence > struct result2_; +}; + +# define AUX_CLASS_SEQUENCE_TAG_SPEC(has_tag, has_begin, result_type) \ +template<> struct sequence_tag_impl \ +{ \ + template< typename Sequence > struct result2_ \ + { \ + typedef result_type type; \ + }; \ +}; \ +/**/ + +AUX_CLASS_SEQUENCE_TAG_SPEC(true, true, typename Sequence::tag) +AUX_CLASS_SEQUENCE_TAG_SPEC(true, false, typename Sequence::tag) +AUX_CLASS_SEQUENCE_TAG_SPEC(false, true, nested_begin_end_tag) +AUX_CLASS_SEQUENCE_TAG_SPEC(false, false, non_sequence_tag) + +# undef AUX_CLASS_SEQUENCE_TAG_SPEC + +} // namespace aux + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + > +struct sequence_tag + : aux::sequence_tag_impl< + ::boost::mpl::aux::has_tag::value + , ::boost::mpl::aux::has_begin::value + >::template result2_ +{ +}; + +#endif // BOOST_MSVC + +BOOST_MPL_AUX_NA_SPEC(1, sequence_tag) + +}} + +#endif // BOOST_MPL_SEQUENCE_TAG_HPP_INCLUDED diff --git a/boost/mpl/sequence_tag_fwd.hpp b/boost/mpl/sequence_tag_fwd.hpp new file mode 100644 index 00000000..4b0ed6f6 --- /dev/null +++ b/boost/mpl/sequence_tag_fwd.hpp @@ -0,0 +1,26 @@ + +#ifndef BOOST_MPL_SEQUENCE_TAG_FWD_HPP_INCLUDED +#define BOOST_MPL_SEQUENCE_TAG_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +namespace boost { namespace mpl { + +struct nested_begin_end_tag; +struct non_sequence_tag; + +template< typename Sequence > struct sequence_tag; + +}} + +#endif // BOOST_MPL_SEQUENCE_TAG_FWD_HPP_INCLUDED diff --git a/boost/mpl/size.hpp b/boost/mpl/size.hpp new file mode 100644 index 00000000..12ffefbb --- /dev/null +++ b/boost/mpl/size.hpp @@ -0,0 +1,42 @@ + +#ifndef BOOST_MPL_SIZE_HPP_INCLUDED +#define BOOST_MPL_SIZE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + > +struct size + : aux::msvc_eti_base< + typename size_impl< typename sequence_tag::type > + ::template apply< Sequence >::type + >::type +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1, size, (Sequence)) +}; + +BOOST_MPL_AUX_NA_SPEC(1, size) + +}} + +#endif // BOOST_MPL_SIZE_HPP_INCLUDED diff --git a/boost/mpl/size_fwd.hpp b/boost/mpl/size_fwd.hpp new file mode 100644 index 00000000..c72628dd --- /dev/null +++ b/boost/mpl/size_fwd.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_SIZE_FWD_HPP_INCLUDED +#define BOOST_MPL_SIZE_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +namespace boost { namespace mpl { + +template< typename Tag > struct size_impl; +template< typename Sequence > struct size; + +}} + +#endif // BOOST_MPL_SIZE_FWD_HPP_INCLUDED diff --git a/boost/mpl/size_t.hpp b/boost/mpl/size_t.hpp new file mode 100644 index 00000000..99e9b41d --- /dev/null +++ b/boost/mpl/size_t.hpp @@ -0,0 +1,25 @@ + +#ifndef BOOST_MPL_SIZE_T_HPP_INCLUDED +#define BOOST_MPL_SIZE_T_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include + +#define AUX_WRAPPER_VALUE_TYPE std::size_t +#define AUX_WRAPPER_NAME size_t +#define AUX_WRAPPER_PARAMS(N) std::size_t N + +#include + +#endif // BOOST_MPL_SIZE_T_HPP_INCLUDED diff --git a/boost/mpl/size_t_fwd.hpp b/boost/mpl/size_t_fwd.hpp new file mode 100644 index 00000000..ffdf4b32 --- /dev/null +++ b/boost/mpl/size_t_fwd.hpp @@ -0,0 +1,28 @@ + +#ifndef BOOST_MPL_SIZE_T_FWD_HPP_INCLUDED +#define BOOST_MPL_SIZE_T_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include // make sure 'size_t' is placed into 'std' +#include + +BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN + +template< std::size_t N > struct size_t; + +BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE +BOOST_MPL_AUX_ADL_BARRIER_DECL(size_t) + +#endif // BOOST_MPL_SIZE_T_FWD_HPP_INCLUDED diff --git a/boost/mpl/sizeof.hpp b/boost/mpl/sizeof.hpp new file mode 100644 index 00000000..cf5e41c6 --- /dev/null +++ b/boost/mpl/sizeof.hpp @@ -0,0 +1,36 @@ + +#ifndef BOOST_MPL_SIZEOF_HPP_INCLUDED +#define BOOST_MPL_SIZEOF_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2003 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(T) + > +struct sizeof_ + : mpl::size_t< sizeof(T) > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,sizeof_,(T)) +}; + +BOOST_MPL_AUX_NA_SPEC_NO_ETI(1, sizeof_) + +}} + +#endif // BOOST_MPL_SIZEOF_HPP_INCLUDED diff --git a/boost/mpl/transform.hpp b/boost/mpl/transform.hpp new file mode 100644 index 00000000..4d3e2a04 --- /dev/null +++ b/boost/mpl/transform.hpp @@ -0,0 +1,145 @@ + +#ifndef BOOST_MPL_TRANSFORM_HPP_INCLUDED +#define BOOST_MPL_TRANSFORM_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id$ +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +namespace aux { + +template< + typename Seq + , typename Op + , typename In + > +struct transform1_impl + : fold< + Seq + , typename In::state + , bind2< typename lambda< typename In::operation >::type + , _1 + , bind1< typename lambda::type, _2> + > + > +{ +}; + +template< + typename Seq + , typename Op + , typename In + > +struct reverse_transform1_impl + : reverse_fold< + Seq + , typename In::state + , bind2< typename lambda< typename In::operation >::type + , _1 + , bind1< typename lambda::type, _2> + > + > +{ +}; + +template< + typename Seq1 + , typename Seq2 + , typename Op + , typename In + > +struct transform2_impl + : fold< + pair_view + , typename In::state + , bind2< typename lambda< typename In::operation >::type + , _1 + , bind2< + typename lambda::type + , bind1,_2> + , bind1,_2> + > + > + > +{ +}; + +template< + typename Seq1 + , typename Seq2 + , typename Op + , typename In + > +struct reverse_transform2_impl + : reverse_fold< + pair_view + , typename In::state + , bind2< typename lambda< typename In::operation >::type + , _1 + , bind2< typename lambda< Op >::type + , bind1,_2> + , bind1,_2> + > + > + > +{ +}; + +} // namespace aux + +BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF(3, transform1) +BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF(4, transform2) + +#define AUX778076_TRANSFORM_DEF(name) \ +template< \ + typename BOOST_MPL_AUX_NA_PARAM(Seq1) \ + , typename BOOST_MPL_AUX_NA_PARAM(Seq2OrOperation) \ + , typename BOOST_MPL_AUX_NA_PARAM(OperationOrInserter) \ + , typename BOOST_MPL_AUX_NA_PARAM(Inserter) \ + > \ +struct name \ +{ \ + typedef typename eval_if< \ + or_< \ + is_na \ + , is_lambda_expression< Seq2OrOperation > \ + , not_< is_sequence > \ + > \ + , name##1 \ + , name##2 \ + >::type type; \ +}; \ +BOOST_MPL_AUX_NA_SPEC(4, name) \ +/**/ + +AUX778076_TRANSFORM_DEF(transform) +AUX778076_TRANSFORM_DEF(reverse_transform) + +#undef AUX778076_TRANSFORM_DEF + +}} + +#endif // BOOST_MPL_TRANSFORM_HPP_INCLUDED diff --git a/boost/preprocessor/enum_params_with_a_default.hpp b/boost/preprocessor/enum_params_with_a_default.hpp new file mode 100644 index 00000000..fd1ad4cc --- /dev/null +++ b/boost/preprocessor/enum_params_with_a_default.hpp @@ -0,0 +1,17 @@ +# /* ************************************************************************** +# * * +# * (C) Copyright Paul Mensonides 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) +# * * +# ************************************************************************** */ +# +# /* See http://www.boost.org for most recent version. */ +# +# ifndef BOOST_PREPROCESSOR_ENUM_PARAMS_WITH_A_DEFAULT_HPP +# define BOOST_PREPROCESSOR_ENUM_PARAMS_WITH_A_DEFAULT_HPP +# +# include +# +# endif diff --git a/boost/preprocessor/repetition/enum_params_with_a_default.hpp b/boost/preprocessor/repetition/enum_params_with_a_default.hpp new file mode 100644 index 00000000..7496df62 --- /dev/null +++ b/boost/preprocessor/repetition/enum_params_with_a_default.hpp @@ -0,0 +1,25 @@ +# /* Copyright (C) 2001 +# * Housemarque Oy +# * http://www.housemarque.com +# * +# * Distributed under the Boost Software License, Version 1.0. (See +# * accompanying file LICENSE_1_0.txt or copy at +# * http://www.boost.org/LICENSE_1_0.txt) +# */ +# +# /* Revised by Paul Mensonides (2002) */ +# +# /* See http://www.boost.org for most recent version. */ +# +# ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_PARAMS_WITH_A_DEFAULT_HPP +# define BOOST_PREPROCESSOR_REPETITION_ENUM_PARAMS_WITH_A_DEFAULT_HPP +# +# include +# include +# include +# +# /* BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT */ +# +# define BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(count, param, def) BOOST_PP_ENUM_BINARY_PARAMS(count, param, = def BOOST_PP_INTERCEPT) +# +# endif diff --git a/boost/random/detail/config.hpp b/boost/random/detail/config.hpp deleted file mode 100644 index 724ab194..00000000 --- a/boost/random/detail/config.hpp +++ /dev/null @@ -1,18 +0,0 @@ -/* boost random/detail/config.hpp header file - * - * Copyright Steven Watanabe 2009 - * Distributed under the Boost Software License, Version 1.0. (See - * accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org for most recent version including documentation. - * - * $Id$ - */ - -#include - -#if (defined(BOOST_NO_OPERATORS_IN_NAMESPACE) || defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)) \ - && !defined(BOOST_MSVC) - #define BOOST_RANDOM_NO_STREAM_OPERATORS -#endif diff --git a/boost/random/detail/const_mod.hpp b/boost/random/detail/const_mod.hpp deleted file mode 100644 index e0a43ab2..00000000 --- a/boost/random/detail/const_mod.hpp +++ /dev/null @@ -1,216 +0,0 @@ -/* boost random/detail/const_mod.hpp header file - * - * Copyright Jens Maurer 2000-2001 - * Distributed under the Boost Software License, Version 1.0. (See - * accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org for most recent version including documentation. - * - * $Id$ - * - * Revision history - * 2001-02-18 moved to individual header files - */ - -#ifndef BOOST_RANDOM_CONST_MOD_HPP -#define BOOST_RANDOM_CONST_MOD_HPP - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace random { - -template -class const_mod -{ -public: - static IntType apply(IntType x) - { - if(((unsigned_m() - 1) & unsigned_m()) == 0) - return (unsigned_type(x)) & (unsigned_m() - 1); - else { - IntType suppress_warnings = (m == 0); - BOOST_ASSERT(suppress_warnings == 0); - return x % (m + suppress_warnings); - } - } - - static IntType add(IntType x, IntType c) - { - if(((unsigned_m() - 1) & unsigned_m()) == 0) - return (unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1); - else if(c == 0) - return x; - else if(x < m - c) - return x + c; - else - return x - (m - c); - } - - static IntType mult(IntType a, IntType x) - { - if(((unsigned_m() - 1) & unsigned_m()) == 0) - return unsigned_type(a) * unsigned_type(x) & (unsigned_m() - 1); - else if(a == 0) - return 0; - else if(a == 1) - return x; - else if(m <= traits::const_max/a) // i.e. a*m <= max - return mult_small(a, x); - else if(traits::is_signed && (m%a < m/a)) - return mult_schrage(a, x); - else - return mult_general(a, x); - } - - static IntType mult_add(IntType a, IntType x, IntType c) - { - if(((unsigned_m() - 1) & unsigned_m()) == 0) - return (unsigned_type(a) * unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1); - else if(a == 0) - return c; - else if(m <= (traits::const_max-c)/a) { // i.e. a*m+c <= max - IntType suppress_warnings = (m == 0); - BOOST_ASSERT(suppress_warnings == 0); - return (a*x+c) % (m + suppress_warnings); - } else - return add(mult(a, x), c); - } - - static IntType pow(IntType a, boost::uintmax_t exponent) - { - IntType result = 1; - while(exponent != 0) { - if(exponent % 2 == 1) { - result = mult(result, a); - } - a = mult(a, a); - exponent /= 2; - } - return result; - } - - static IntType invert(IntType x) - { return x == 0 ? 0 : (m == 0? invert_euclidian0(x) : invert_euclidian(x)); } - -private: - typedef integer_traits traits; - typedef typename make_unsigned::type unsigned_type; - - const_mod(); // don't instantiate - - static IntType mult_small(IntType a, IntType x) - { - IntType suppress_warnings = (m == 0); - BOOST_ASSERT(suppress_warnings == 0); - return a*x % (m + suppress_warnings); - } - - static IntType mult_schrage(IntType a, IntType value) - { - const IntType q = m / a; - const IntType r = m % a; - - BOOST_ASSERT(r < q); // check that overflow cannot happen - - return sub(a*(value%q), r*(value/q)); - } - - static IntType mult_general(IntType a, IntType b) - { - IntType suppress_warnings = (m == 0); - BOOST_ASSERT(suppress_warnings == 0); - IntType modulus = m + suppress_warnings; - BOOST_ASSERT(modulus == m); - if(::boost::uintmax_t(modulus) <= - (::std::numeric_limits< ::boost::uintmax_t>::max)() / modulus) - { - return static_cast(boost::uintmax_t(a) * b % modulus); - } else { - return static_cast(detail::mulmod(a, b, modulus)); - } - } - - static IntType sub(IntType a, IntType b) - { - if(a < b) - return m - (b - a); - else - return a - b; - } - - static unsigned_type unsigned_m() - { - if(m == 0) { - return unsigned_type((std::numeric_limits::max)()) + 1; - } else { - return unsigned_type(m); - } - } - - // invert c in the finite field (mod m) (m must be prime) - static IntType invert_euclidian(IntType c) - { - // we are interested in the gcd factor for c, because this is our inverse - BOOST_ASSERT(c > 0); - IntType l1 = 0; - IntType l2 = 1; - IntType n = c; - IntType p = m; - for(;;) { - IntType q = p / n; - l1 += q * l2; - p -= q * n; - if(p == 0) - return l2; - IntType q2 = n / p; - l2 += q2 * l1; - n -= q2 * p; - if(n == 0) - return m - l1; - } - } - - // invert c in the finite field (mod m) (c must be relatively prime to m) - static IntType invert_euclidian0(IntType c) - { - // we are interested in the gcd factor for c, because this is our inverse - BOOST_ASSERT(c > 0); - if(c == 1) return 1; - IntType l1 = 0; - IntType l2 = 1; - IntType n = c; - IntType p = m; - IntType max = (std::numeric_limits::max)(); - IntType q = max / n; - BOOST_ASSERT(max % n != n - 1 && "c must be relatively prime to m."); - l1 += q * l2; - p = max - q * n + 1; - for(;;) { - if(p == 0) - return l2; - IntType q2 = n / p; - l2 += q2 * l1; - n -= q2 * p; - if(n == 0) - return m - l1; - q = p / n; - l1 += q * l2; - p -= q * n; - } - } -}; - -} // namespace random -} // namespace boost - -#include - -#endif // BOOST_RANDOM_CONST_MOD_HPP diff --git a/boost/random/detail/disable_warnings.hpp b/boost/random/detail/disable_warnings.hpp deleted file mode 100644 index 4582dcb1..00000000 --- a/boost/random/detail/disable_warnings.hpp +++ /dev/null @@ -1,29 +0,0 @@ -/* boost random/detail/disable_warnings.hpp header file - * - * Copyright Steven Watanabe 2009 - * Distributed under the Boost Software License, Version 1.0. (See - * accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org for most recent version including documentation. - * - * $Id$ - * - */ - -// No #include guard. This header is intended to be included multiple times. - -#include - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:4512) -#pragma warning(disable:4127) -#pragma warning(disable:4724) -#pragma warning(disable:4800) // 'int' : forcing value to bool 'true' or 'false' (performance warning) -#endif - -#if defined(BOOST_GCC) && BOOST_GCC >= 40600 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wlogical-op" -#endif diff --git a/boost/random/detail/enable_warnings.hpp b/boost/random/detail/enable_warnings.hpp deleted file mode 100644 index 24f3bb3f..00000000 --- a/boost/random/detail/enable_warnings.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/* boost random/detail/enable_warnings.hpp header file - * - * Copyright Steven Watanabe 2009 - * Distributed under the Boost Software License, Version 1.0. (See - * accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org for most recent version including documentation. - * - * $Id$ - * - */ - -// No #include guard. This header is intended to be included multiple times. - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#if defined(BOOST_GCC) && BOOST_GCC >= 40600 -#pragma GCC diagnostic pop -#endif diff --git a/boost/random/detail/generator_bits.hpp b/boost/random/detail/generator_bits.hpp deleted file mode 100644 index 05276142..00000000 --- a/boost/random/detail/generator_bits.hpp +++ /dev/null @@ -1,36 +0,0 @@ -/* boost random/detail/generator_bits.hpp header file - * - * Copyright Steven Watanabe 2011 - * Distributed under the Boost Software License, Version 1.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 including documentation. - * - * $Id$ - * - */ - -#ifndef BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP -#define BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP - -#include - -namespace boost { -namespace random { -namespace detail { - -// This is a temporary measure that retains backwards -// compatibility. -template -struct generator_bits { - static std::size_t value() { - return std::numeric_limits::digits; - } -}; - -} // namespace detail -} // namespace random -} // namespace boost - -#endif // BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP diff --git a/boost/random/detail/integer_log2.hpp b/boost/random/detail/integer_log2.hpp deleted file mode 100644 index 2e49f281..00000000 --- a/boost/random/detail/integer_log2.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/* boost random/detail/integer_log2.hpp header file - * - * Copyright Steven Watanabe 2011 - * Distributed under the Boost Software License, Version 1.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 including documentation. - * - * $Id$ - * - */ - -#ifndef BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP -#define BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP - -#include -#include -#include - -namespace boost { -namespace random { -namespace detail { - -#if !defined(BOOST_NO_CXX11_CONSTEXPR) -#define BOOST_RANDOM_DETAIL_CONSTEXPR constexpr -#elif defined(BOOST_MSVC) -#define BOOST_RANDOM_DETAIL_CONSTEXPR __forceinline -#elif defined(__GNUC__) && __GNUC__ >= 4 -#define BOOST_RANDOM_DETAIL_CONSTEXPR inline __attribute__((__const__)) __attribute__((__always_inline__)) -#else -#define BOOST_RANDOM_DETAIL_CONSTEXPR inline -#endif - -template -struct integer_log2_impl -{ -#if defined(BOOST_NO_CXX11_CONSTEXPR) - template - BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum) - { - int update = ((t >> Shift) != 0) * Shift; - return integer_log2_impl::apply(t >> update, accum + update); - } -#else - template - BOOST_RANDOM_DETAIL_CONSTEXPR static int apply2(T t, int accum, int update) - { - return integer_log2_impl::apply(t >> update, accum + update); - } - - template - BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum) - { - return apply2(t, accum, ((t >> Shift) != 0) * Shift); - } -#endif -}; - -template<> -struct integer_log2_impl<1> -{ - template - BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum) - { - return int(t >> 1) + accum; - } -}; - -template -BOOST_RANDOM_DETAIL_CONSTEXPR int integer_log2(T t) -{ - return integer_log2_impl< - ::boost::detail::max_pow2_less< - ::std::numeric_limits::digits, 4 - >::value - >::apply(t, 0); -} - -} // namespace detail -} // namespace random -} // namespace boost - -#endif // BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP diff --git a/boost/random/detail/large_arithmetic.hpp b/boost/random/detail/large_arithmetic.hpp deleted file mode 100644 index 66f6b4e6..00000000 --- a/boost/random/detail/large_arithmetic.hpp +++ /dev/null @@ -1,122 +0,0 @@ -/* boost random/detail/large_arithmetic.hpp header file - * - * Copyright Steven Watanabe 2011 - * Distributed under the Boost Software License, Version 1.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 including documentation. - * - * $Id$ - */ - -#ifndef BOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP -#define BOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP - -#include -#include -#include -#include - -#include - -namespace boost { -namespace random { -namespace detail { - -struct div_t { - boost::uintmax_t quotient; - boost::uintmax_t remainder; -}; - -inline div_t muldivmod(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m) -{ - const int bits = - ::std::numeric_limits< ::boost::uintmax_t>::digits / 2; - const ::boost::uintmax_t mask = (::boost::uintmax_t(1) << bits) - 1; - typedef ::boost::uint_t::fast digit_t; - - int shift = std::numeric_limits< ::boost::uintmax_t>::digits - 1 - - detail::integer_log2(m); - - a <<= shift; - m <<= shift; - - digit_t product[4] = { 0, 0, 0, 0 }; - digit_t a_[2] = { digit_t(a & mask), digit_t((a >> bits) & mask) }; - digit_t b_[2] = { digit_t(b & mask), digit_t((b >> bits) & mask) }; - digit_t m_[2] = { digit_t(m & mask), digit_t((m >> bits) & mask) }; - - // multiply a * b - for(int i = 0; i < 2; ++i) { - digit_t carry = 0; - for(int j = 0; j < 2; ++j) { - ::boost::uint64_t temp = ::boost::uintmax_t(a_[i]) * b_[j] + - carry + product[i + j]; - product[i + j] = digit_t(temp & mask); - carry = digit_t(temp >> bits); - } - if(carry != 0) { - product[i + 2] += carry; - } - } - - digit_t quotient[2]; - - if(m == 0) { - div_t result = { - ((::boost::uintmax_t(product[3]) << bits) | product[2]), - ((::boost::uintmax_t(product[1]) << bits) | product[0]) >> shift, - }; - return result; - } - - // divide product / m - for(int i = 3; i >= 2; --i) { - ::boost::uintmax_t temp = - ::boost::uintmax_t(product[i]) << bits | product[i - 1]; - - digit_t q = digit_t((product[i] == m_[1]) ? mask : temp / m_[1]); - - ::boost::uintmax_t rem = - ((temp - ::boost::uintmax_t(q) * m_[1]) << bits) + product[i - 2]; - - ::boost::uintmax_t diff = m_[0] * ::boost::uintmax_t(q); - - int error = 0; - if(diff > rem) { - if(diff - rem > m) { - error = 2; - } else { - error = 1; - } - } - q -= error; - rem = rem + error * m - diff; - - quotient[i - 2] = q; - product[i] = 0; - product[i-1] = static_cast((rem >> bits) & mask); - product[i-2] = static_cast(rem & mask); - } - - div_t result = { - ((::boost::uintmax_t(quotient[1]) << bits) | quotient[0]), - ((::boost::uintmax_t(product[1]) << bits) | product[0]) >> shift, - }; - return result; -} - -inline boost::uintmax_t muldiv(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m) -{ return detail::muldivmod(a, b, m).quotient; } - -inline boost::uintmax_t mulmod(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m) -{ return detail::muldivmod(a, b, m).remainder; } - -} // namespace detail -} // namespace random -} // namespace boost - -#include - -#endif // BOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP diff --git a/boost/random/detail/operators.hpp b/boost/random/detail/operators.hpp deleted file mode 100644 index f363f37b..00000000 --- a/boost/random/detail/operators.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/* boost random/detail/operators.hpp header file - * - * Copyright Steven Watanabe 2010-2011 - * Distributed under the Boost Software License, Version 1.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 including documentation. - * - * $Id$ - */ - -#ifndef BOOST_RANDOM_DETAIL_OPERATORS_HPP -#define BOOST_RANDOM_DETAIL_OPERATORS_HPP - -#include -#include - -#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) \ - || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) - -#define BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t) \ - template \ - friend std::basic_ostream& \ - operator<<(std::basic_ostream& os, const T& t) { \ - t.print(os, t); \ - return os; \ - } \ - template \ - static std::basic_ostream& \ - print(std::basic_ostream& os, const T& t) - -#define BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, T, t) \ - template \ - friend std::basic_istream& \ - operator>>(std::basic_istream& is, T& t) { \ - t.read(is, t); \ - return is; \ - } \ - template \ - static std::basic_istream& \ - read(std::basic_istream& is, T& t) - -#endif - -#if defined(BOOST_BORLANDC) - -#define BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs) \ - bool operator==(const T& rhs) const \ - { return T::is_equal(*this, rhs); } \ - static bool is_equal(const T& lhs, const T& rhs) - -#define BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T) \ - bool operator!=(const T& rhs) const \ - { return !T::is_equal(*this, rhs); } - -#endif - -#ifndef BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR -#define BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t) \ - template \ - friend std::basic_ostream& \ - operator<<(std::basic_ostream& os, const T& t) -#endif - -#ifndef BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR -#define BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, T, t) \ - template \ - friend std::basic_istream& \ - operator>>(std::basic_istream& is, T& t) -#endif - -#ifndef BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR -#define BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs) \ - friend bool operator==(const T& lhs, const T& rhs) -#endif - -#ifndef BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR -#define BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T) \ - friend bool operator!=(const T& lhs, const T& rhs) \ - { return !(lhs == rhs); } -#endif - -#endif diff --git a/boost/random/detail/ptr_helper.hpp b/boost/random/detail/ptr_helper.hpp deleted file mode 100644 index f1b983d9..00000000 --- a/boost/random/detail/ptr_helper.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/* boost random/detail/ptr_helper.hpp header file - * - * Copyright Jens Maurer 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) - * - * See http://www.boost.org for most recent version including documentation. - * - * $Id$ - * - */ - -#ifndef BOOST_RANDOM_DETAIL_PTR_HELPER_HPP -#define BOOST_RANDOM_DETAIL_PTR_HELPER_HPP - -#include - - -namespace boost { -namespace random { -namespace detail { - -// type_traits could help here, but I don't want to depend on type_traits. -template -struct ptr_helper -{ - typedef T value_type; - typedef T& reference_type; - typedef const T& rvalue_type; - static reference_type ref(T& r) { return r; } - static const T& ref(const T& r) { return r; } -}; - -template -struct ptr_helper -{ - typedef T value_type; - typedef T& reference_type; - typedef T& rvalue_type; - static reference_type ref(T& r) { return r; } - static const T& ref(const T& r) { return r; } -}; - -template -struct ptr_helper -{ - typedef T value_type; - typedef T& reference_type; - typedef T* rvalue_type; - static reference_type ref(T * p) { return *p; } - static const T& ref(const T * p) { return *p; } -}; - -} // namespace detail -} // namespace random -} // namespace boost - -// -// BOOST_RANDOM_PTR_HELPER_SPEC -- -// -// Helper macro for broken compilers defines specializations of -// ptr_helper. -// -# define BOOST_RANDOM_PTR_HELPER_SPEC(T) - -#endif // BOOST_RANDOM_DETAIL_PTR_HELPER_HPP diff --git a/boost/random/detail/seed.hpp b/boost/random/detail/seed.hpp deleted file mode 100644 index d2e424ac..00000000 --- a/boost/random/detail/seed.hpp +++ /dev/null @@ -1,113 +0,0 @@ -/* boost random/detail/seed.hpp header file - * - * Copyright Steven Watanabe 2009 - * Distributed under the Boost Software License, Version 1.0. (See - * accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org for most recent version including documentation. - * - * $Id$ - */ - -#ifndef BOOST_RANDOM_DETAIL_SEED_HPP -#define BOOST_RANDOM_DETAIL_SEED_HPP - -#include - -// Sun seems to have trouble with the use of SFINAE for the -// templated constructor. So does Borland. -#if !defined(BOOST_NO_SFINAE) && !defined(__SUNPRO_CC) && !defined(BOOST_BORLANDC) - -#include -#include - -namespace boost { -namespace random { -namespace detail { - -template -struct disable_seed : boost::disable_if > {}; - -template -struct disable_constructor : disable_seed {}; - -template -struct disable_constructor {}; - -#define BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(Self, Generator, gen) \ - template \ - explicit Self(Generator& gen, typename ::boost::random::detail::disable_constructor::type* = 0) - -#define BOOST_RANDOM_DETAIL_GENERATOR_SEED(Self, Generator, gen) \ - template \ - void seed(Generator& gen, typename ::boost::random::detail::disable_seed::type* = 0) - -#define BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(Self, SeedSeq, seq) \ - template \ - explicit Self(SeedSeq& seq, typename ::boost::random::detail::disable_constructor::type* = 0) - -#define BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(Self, SeedSeq, seq) \ - template \ - void seed(SeedSeq& seq, typename ::boost::random::detail::disable_seed::type* = 0) - -#define BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(Self, T, x) \ - explicit Self(const T& x) - -#define BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(Self, T, x) \ - void seed(const T& x) -} -} -} - -#else - -#include - -#define BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(Self, Generator, gen) \ - Self(Self& other) { *this = other; } \ - Self(const Self& other) { *this = other; } \ - template \ - explicit Self(Generator& gen) { \ - boost_random_constructor_impl(gen, ::boost::is_arithmetic());\ - } \ - template \ - void boost_random_constructor_impl(Generator& gen, ::boost::false_type) - -#define BOOST_RANDOM_DETAIL_GENERATOR_SEED(Self, Generator, gen) \ - template \ - void seed(Generator& gen) { \ - boost_random_seed_impl(gen, ::boost::is_arithmetic());\ - }\ - template\ - void boost_random_seed_impl(Generator& gen, ::boost::false_type) - -#define BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(Self, SeedSeq, seq) \ - Self(Self& other) { *this = other; } \ - Self(const Self& other) { *this = other; } \ - template \ - explicit Self(SeedSeq& seq) { \ - boost_random_constructor_impl(seq, ::boost::is_arithmetic());\ - } \ - template \ - void boost_random_constructor_impl(SeedSeq& seq, ::boost::false_type) - -#define BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(Self, SeedSeq, seq) \ - template \ - void seed(SeedSeq& seq) { \ - boost_random_seed_impl(seq, ::boost::is_arithmetic()); \ - } \ - template \ - void boost_random_seed_impl(SeedSeq& seq, ::boost::false_type) - -#define BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(Self, T, x) \ - explicit Self(const T& x) { boost_random_constructor_impl(x, ::boost::true_type()); }\ - void boost_random_constructor_impl(const T& x, ::boost::true_type) - -#define BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(Self, T, x) \ - void seed(const T& x) { boost_random_seed_impl(x, ::boost::true_type()); }\ - void boost_random_seed_impl(const T& x, ::boost::true_type) - -#endif - -#endif diff --git a/boost/random/detail/seed_impl.hpp b/boost/random/detail/seed_impl.hpp deleted file mode 100644 index 5e79582a..00000000 --- a/boost/random/detail/seed_impl.hpp +++ /dev/null @@ -1,397 +0,0 @@ -/* boost random/detail/seed.hpp header file - * - * Copyright Steven Watanabe 2009 - * Distributed under the Boost Software License, Version 1.0. (See - * accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org for most recent version including documentation. - * - * $Id$ - */ - -#ifndef BOOST_RANDOM_DETAIL_SEED_IMPL_HPP -#define BOOST_RANDOM_DETAIL_SEED_IMPL_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace random { -namespace detail { - -// finds the seed type of an engine, given its -// result_type. If the result_type is integral -// the seed type is the same. If the result_type -// is floating point, the seed type is uint32_t -template -struct seed_type -{ - typedef typename boost::conditional::value, - T, - boost::uint32_t - >::type type; -}; - -template -struct const_pow_impl -{ - template - static T call(T arg, int n, T result) - { - return const_pow_impl::call(T(arg * arg), n / 2, - n%2 == 0? result : T(result * arg)); - } -}; - -template<> -struct const_pow_impl<0> -{ - template - static T call(T, int, T result) - { - return result; - } -}; - -// requires N is an upper bound on n -template -inline T const_pow(T arg, int n) { return const_pow_impl::call(arg, n, T(1)); } - -template -inline T pow2(int n) -{ - typedef unsigned int_type; - const int max_bits = std::numeric_limits::digits; - T multiplier = T(int_type(1) << (max_bits - 1)) * 2; - return (int_type(1) << (n % max_bits)) * - const_pow::digits / max_bits>(multiplier, n / max_bits); -} - -template -void generate_from_real(Engine& eng, Iter begin, Iter end) -{ - using std::fmod; - typedef typename Engine::result_type RealType; - const int Bits = detail::generator_bits::value(); - int remaining_bits = 0; - boost::uint_least32_t saved_bits = 0; - RealType multiplier = pow2( Bits); - RealType mult32 = RealType(4294967296.0); // 2^32 - while(true) { - RealType val = eng() * multiplier; - int available_bits = Bits; - // Make sure the compiler can optimize this out - // if it isn't possible. - if(Bits < 32 && available_bits < 32 - remaining_bits) { - saved_bits |= boost::uint_least32_t(val) << remaining_bits; - remaining_bits += Bits; - } else { - // If Bits < 32, then remaining_bits != 0, since - // if remaining_bits == 0, available_bits < 32 - 0, - // and we won't get here to begin with. - if(Bits < 32 || remaining_bits != 0) { - boost::uint_least32_t divisor = - (boost::uint_least32_t(1) << (32 - remaining_bits)); - boost::uint_least32_t extra_bits = boost::uint_least32_t(fmod(val, mult32)) & (divisor - 1); - val = val / divisor; - *begin++ = saved_bits | (extra_bits << remaining_bits); - if(begin == end) return; - available_bits -= 32 - remaining_bits; - remaining_bits = 0; - } - // If Bits < 32 we should never enter this loop - if(Bits >= 32) { - for(; available_bits >= 32; available_bits -= 32) { - boost::uint_least32_t word = boost::uint_least32_t(fmod(val, mult32)); - val /= mult32; - *begin++ = word; - if(begin == end) return; - } - } - remaining_bits = available_bits; - saved_bits = static_cast(val); - } - } -} - -template -void generate_from_int(Engine& eng, Iter begin, Iter end) -{ - typedef typename Engine::result_type IntType; - typedef typename boost::random::traits::make_unsigned::type unsigned_type; - int remaining_bits = 0; - boost::uint_least32_t saved_bits = 0; - unsigned_type range = boost::random::detail::subtract()((eng.max)(), (eng.min)()); - - int bits = - (range == (std::numeric_limits::max)()) ? - std::numeric_limits::digits : - detail::integer_log2(range + 1); - - { - int discarded_bits = detail::integer_log2(bits); - unsigned_type excess = (range + 1) >> (bits - discarded_bits); - if(excess != 0) { - int extra_bits = detail::integer_log2((excess - 1) ^ excess); - bits = bits - discarded_bits + extra_bits; - } - } - - unsigned_type mask = (static_cast(2) << (bits - 1)) - 1; - unsigned_type limit = ((range + 1) & ~mask) - 1; - - while(true) { - unsigned_type val; - do { - val = boost::random::detail::subtract()(eng(), (eng.min)()); - } while(limit != range && val > limit); - val &= mask; - int available_bits = bits; - if(available_bits == 32) { - *begin++ = static_cast(val) & 0xFFFFFFFFu; - if(begin == end) return; - } else if(available_bits % 32 == 0) { - for(int i = 0; i < available_bits / 32; ++i) { - boost::uint_least32_t word = boost::uint_least32_t(val) & 0xFFFFFFFFu; - int suppress_warning = (bits >= 32); - BOOST_ASSERT(suppress_warning == 1); - val >>= (32 * suppress_warning); - *begin++ = word; - if(begin == end) return; - } - } else if(bits < 32 && available_bits < 32 - remaining_bits) { - saved_bits |= boost::uint_least32_t(val) << remaining_bits; - remaining_bits += bits; - } else { - if(bits < 32 || remaining_bits != 0) { - boost::uint_least32_t extra_bits = boost::uint_least32_t(val) & ((boost::uint_least32_t(1) << (32 - remaining_bits)) - 1); - val >>= 32 - remaining_bits; - *begin++ = saved_bits | (extra_bits << remaining_bits); - if(begin == end) return; - available_bits -= 32 - remaining_bits; - remaining_bits = 0; - } - if(bits >= 32) { - for(; available_bits >= 32; available_bits -= 32) { - boost::uint_least32_t word = boost::uint_least32_t(val) & 0xFFFFFFFFu; - int suppress_warning = (bits >= 32); - BOOST_ASSERT(suppress_warning == 1); - val >>= (32 * suppress_warning); - *begin++ = word; - if(begin == end) return; - } - } - remaining_bits = available_bits; - saved_bits = static_cast(val); - } - } -} - -template -void generate_impl(Engine& eng, Iter first, Iter last, boost::true_type) -{ - return detail::generate_from_int(eng, first, last); -} - -template -void generate_impl(Engine& eng, Iter first, Iter last, boost::false_type) -{ - return detail::generate_from_real(eng, first, last); -} - -template -void generate(Engine& eng, Iter first, Iter last) -{ - return detail::generate_impl(eng, first, last, boost::random::traits::is_integral()); -} - - - -template -IntType seed_one_int(SeedSeq& seq) -{ - static const int log = ::boost::conditional<(m == 0), - ::boost::integral_constant::digits)>, - ::boost::static_log2 >::type::value; - static const int k = - (log + ((~(static_cast(2) << (log - 1)) & m)? 32 : 31)) / 32; - ::boost::uint_least32_t array[log / 32 + 4]; - seq.generate(&array[0], &array[0] + k + 3); - IntType s = 0; - for(int j = 0; j < k; ++j) { - IntType digit = const_mod::apply(IntType(array[j+3])); - IntType mult = IntType(1) << 32*j; - s = const_mod::mult_add(mult, digit, s); - } - return s; -} - -template -IntType get_one_int(Iter& first, Iter last) -{ - static const int log = ::boost::conditional<(m == 0), - ::boost::integral_constant::digits)>, - ::boost::static_log2 >::type::value; - static const int k = - (log + ((~(static_cast(2) << (log - 1)) & m)? 32 : 31)) / 32; - IntType s = 0; - for(int j = 0; j < k; ++j) { - if(first == last) { - boost::throw_exception(::std::invalid_argument("Not enough elements in call to seed.")); - } - IntType digit = const_mod::apply(IntType(*first++)); - IntType mult = IntType(1) << 32*j; - s = const_mod::mult_add(mult, digit, s); - } - return s; -} - -// TODO: work in-place whenever possible -template -void seed_array_int_impl(SeedSeq& seq, UIntType (&x)[n]) -{ - boost::uint_least32_t storage[((w+31)/32) * n]; - seq.generate(&storage[0], &storage[0] + ((w+31)/32) * n); - for(std::size_t j = 0; j < n; j++) { - UIntType val = 0; - for(std::size_t k = 0; k < (w+31)/32; ++k) { - val += static_cast(storage[(w+31)/32*j + k]) << 32*k; - } - x[j] = val & ::boost::low_bits_mask_t::sig_bits; - } -} - -template -inline void seed_array_int_impl(SeedSeq& seq, IntType (&x)[n], boost::true_type) -{ - BOOST_STATIC_ASSERT_MSG(boost::is_integral::value, "Sorry but this routine has not been ported to non built-in integers as it relies on a reinterpret_cast."); - typedef typename boost::make_unsigned::type unsigned_array[n]; - seed_array_int_impl(seq, reinterpret_cast(x)); -} - -template -inline void seed_array_int_impl(SeedSeq& seq, IntType (&x)[n], boost::false_type) -{ - seed_array_int_impl(seq, x); -} - -template -inline void seed_array_int(SeedSeq& seq, IntType (&x)[n]) -{ - seed_array_int_impl(seq, x, boost::random::traits::is_signed()); -} - -template -void fill_array_int_impl(Iter& first, Iter last, UIntType (&x)[n]) -{ - for(std::size_t j = 0; j < n; j++) { - UIntType val = 0; - for(std::size_t k = 0; k < (w+31)/32; ++k) { - if(first == last) { - boost::throw_exception(std::invalid_argument("Not enough elements in call to seed.")); - } - val += static_cast(*first++) << 32*k; - } - x[j] = val & ::boost::low_bits_mask_t::sig_bits; - } -} - -template -inline void fill_array_int_impl(Iter& first, Iter last, IntType (&x)[n], boost::true_type) -{ - BOOST_STATIC_ASSERT_MSG(boost::is_integral::value, "Sorry but this routine has not been ported to non built-in integers as it relies on a reinterpret_cast."); - typedef typename boost::make_unsigned::type unsigned_array[n]; - fill_array_int_impl(first, last, reinterpret_cast(x)); -} - -template -inline void fill_array_int_impl(Iter& first, Iter last, IntType (&x)[n], boost::false_type) -{ - fill_array_int_impl(first, last, x); -} - -template -inline void fill_array_int(Iter& first, Iter last, IntType (&x)[n]) -{ - fill_array_int_impl(first, last, x, boost::random::traits::is_signed()); -} - -template -void seed_array_real_impl(const boost::uint_least32_t* storage, RealType (&x)[n]) -{ - boost::uint_least32_t mask = ~((~boost::uint_least32_t(0)) << (w%32)); - RealType two32 = 4294967296.0; - const RealType divisor = RealType(1)/detail::pow2(w); - unsigned int j; - for(j = 0; j < n; ++j) { - RealType val = RealType(0); - RealType mult = divisor; - for(int k = 0; k < w/32; ++k) { - val += *storage++ * mult; - mult *= two32; - } - if(mask != 0) { - val += (*storage++ & mask) * mult; - } - BOOST_ASSERT(val >= 0); - BOOST_ASSERT(val < 1); - x[j] = val; - } -} - -template -void seed_array_real(SeedSeq& seq, RealType (&x)[n]) -{ - using std::pow; - boost::uint_least32_t storage[((w+31)/32) * n]; - seq.generate(&storage[0], &storage[0] + ((w+31)/32) * n); - seed_array_real_impl(storage, x); -} - -template -void fill_array_real(Iter& first, Iter last, RealType (&x)[n]) -{ - boost::uint_least32_t mask = ~((~boost::uint_least32_t(0)) << (w%32)); - RealType two32 = 4294967296.0; - const RealType divisor = RealType(1)/detail::pow2(w); - unsigned int j; - for(j = 0; j < n; ++j) { - RealType val = RealType(0); - RealType mult = divisor; - for(int k = 0; k < w/32; ++k, ++first) { - if(first == last) boost::throw_exception(std::invalid_argument("Not enough elements in call to seed.")); - val += *first * mult; - mult *= two32; - } - if(mask != 0) { - if(first == last) boost::throw_exception(std::invalid_argument("Not enough elements in call to seed.")); - val += (*first & mask) * mult; - ++first; - } - BOOST_ASSERT(val >= 0); - BOOST_ASSERT(val < 1); - x[j] = val; - } -} - -} -} -} - -#include - -#endif diff --git a/boost/random/detail/signed_unsigned_tools.hpp b/boost/random/detail/signed_unsigned_tools.hpp deleted file mode 100644 index 1979908a..00000000 --- a/boost/random/detail/signed_unsigned_tools.hpp +++ /dev/null @@ -1,89 +0,0 @@ -/* boost random/detail/signed_unsigned_tools.hpp header file - * - * Copyright Jens Maurer 2006 - * Distributed under the Boost Software License, Version 1.0. (See - * accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org for most recent version including documentation. - */ - -#ifndef BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS -#define BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS - -#include -#include -#include - -namespace boost { -namespace random { -namespace detail { - - -/* - * Compute x - y, we know that x >= y, return an unsigned value. - */ - -template::is_signed && std::numeric_limits::is_bounded> -struct subtract { }; - -template -struct subtract -{ - typedef T result_type; - result_type operator()(T x, T y) { return x - y; } -}; - -template -struct subtract -{ - typedef typename boost::random::traits::make_unsigned_or_unbounded::type result_type; - result_type operator()(T x, T y) - { - if (y >= 0) // because x >= y, it follows that x >= 0, too - return result_type(x) - result_type(y); - if (x >= 0) // y < 0 - // avoid the nasty two's complement case for y == min() - return result_type(x) + result_type(-(y+1)) + 1; - // both x and y are negative: no signed overflow - return result_type(x - y); - } -}; - -/* - * Compute x + y, x is unsigned, result fits in type of "y". - */ - -template::is_signed && (std::numeric_limits::digits >= std::numeric_limits::digits))> -struct add { }; - -template -struct add -{ - typedef T2 result_type; - result_type operator()(T1 x, T2 y) { return T2(x) + y; } -}; - -template -struct add -{ - typedef T2 result_type; - result_type operator()(T1 x, T2 y) - { - if (y >= 0) - return T2(x) + y; - // y < 0 - if (x > T1(-(y+1))) // result >= 0 after subtraction - // avoid the nasty two's complement edge case for y == min() - return T2(x - T1(-(y+1)) - 1); - // abs(x) < abs(y), thus T2 able to represent x - return T2(x) + y; - } -}; - -} // namespace detail -} // namespace random -} // namespace boost - -#endif // BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS - diff --git a/boost/random/linear_congruential.hpp b/boost/random/linear_congruential.hpp deleted file mode 100644 index 62b05ec0..00000000 --- a/boost/random/linear_congruential.hpp +++ /dev/null @@ -1,468 +0,0 @@ -/* boost random/linear_congruential.hpp header file - * - * Copyright Jens Maurer 2000-2001 - * Distributed under the Boost Software License, Version 1.0. (See - * accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org for most recent version including documentation. - * - * $Id$ - * - * Revision history - * 2001-02-18 moved to individual header files - */ - -#ifndef BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP -#define BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace random { - -/** - * Instantiations of class template linear_congruential_engine model a - * \pseudo_random_number_generator. Linear congruential pseudo-random - * number generators are described in: - * - * @blockquote - * "Mathematical methods in large-scale computing units", D. H. Lehmer, - * Proc. 2nd Symposium on Large-Scale Digital Calculating Machines, - * Harvard University Press, 1951, pp. 141-146 - * @endblockquote - * - * Let x(n) denote the sequence of numbers returned by some pseudo-random - * number generator. Then for the linear congruential generator, - * x(n+1) := (a * x(n) + c) mod m. Parameters for the generator are - * x(0), a, c, m. The template parameter IntType shall denote an integral - * type. It must be large enough to hold values a, c, and m. The template - * parameters a and c must be smaller than m. - * - * Note: The quality of the generator crucially depends on the choice of - * the parameters. User code should use one of the sensibly parameterized - * generators such as minstd_rand instead. - */ -template -class linear_congruential_engine -{ -public: - typedef IntType result_type; - - // Required for old Boost.Random concept - BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); - - BOOST_STATIC_CONSTANT(IntType, multiplier = a); - BOOST_STATIC_CONSTANT(IntType, increment = c); - BOOST_STATIC_CONSTANT(IntType, modulus = m); - BOOST_STATIC_CONSTANT(IntType, default_seed = 1); - - BOOST_STATIC_ASSERT(std::numeric_limits::is_integer); - BOOST_STATIC_ASSERT(m == 0 || a < m); - BOOST_STATIC_ASSERT(m == 0 || c < m); - - /** - * Constructs a @c linear_congruential_engine, using the default seed - */ - linear_congruential_engine() { seed(); } - - /** - * Constructs a @c linear_congruential_engine, seeding it with @c x0. - */ - BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(linear_congruential_engine, - IntType, x0) - { seed(x0); } - - /** - * Constructs a @c linear_congruential_engine, seeding it with values - * produced by a call to @c seq.generate(). - */ - BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(linear_congruential_engine, - SeedSeq, seq) - { seed(seq); } - - /** - * Constructs a @c linear_congruential_engine and seeds it - * with values taken from the itrator range [first, last) - * and adjusts first to point to the element after the last one - * used. If there are not enough elements, throws @c std::invalid_argument. - * - * first and last must be input iterators. - */ - template - linear_congruential_engine(It& first, It last) - { - seed(first, last); - } - - // compiler-generated copy constructor and assignment operator are fine - - /** - * Calls seed(default_seed) - */ - void seed() { seed(default_seed); } - - /** - * If c mod m is zero and x0 mod m is zero, changes the current value of - * the generator to 1. Otherwise, changes it to x0 mod m. If c is zero, - * distinct seeds in the range [1,m) will leave the generator in distinct - * states. If c is not zero, the range is [0,m). - */ - BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(linear_congruential_engine, IntType, x0_) - { - // Work around a msvc 12/14 optimizer bug, which causes - // the line _x = 1 to run unconditionally sometimes. - // Creating a local copy seems to make it work. - IntType x0 = x0_; - // wrap _x if it doesn't fit in the destination - if(modulus == 0) { - _x = x0; - } else { - _x = x0 % modulus; - } - // handle negative seeds - if(_x < 0) { - _x += modulus; - } - // adjust to the correct range - if(increment == 0 && _x == 0) { - _x = 1; - } - BOOST_ASSERT(_x >= (min)()); - BOOST_ASSERT(_x <= (max)()); - } - - /** - * Seeds a @c linear_congruential_engine using values from a SeedSeq. - */ - BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(linear_congruential_engine, SeedSeq, seq) - { seed(detail::seed_one_int(seq)); } - - /** - * seeds a @c linear_congruential_engine with values taken - * from the itrator range [first, last) and adjusts @c first to - * point to the element after the last one used. If there are - * not enough elements, throws @c std::invalid_argument. - * - * @c first and @c last must be input iterators. - */ - template - void seed(It& first, It last) - { seed(detail::get_one_int(first, last)); } - - /** - * Returns the smallest value that the @c linear_congruential_engine - * can produce. - */ - static BOOST_CONSTEXPR result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () - { return c == 0 ? 1 : 0; } - /** - * Returns the largest value that the @c linear_congruential_engine - * can produce. - */ - static BOOST_CONSTEXPR result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () - { return modulus-1; } - - /** Returns the next value of the @c linear_congruential_engine. */ - IntType operator()() - { - _x = const_mod::mult_add(a, _x, c); - return _x; - } - - /** Fills a range with random values */ - template - void generate(Iter first, Iter last) - { detail::generate_from_int(*this, first, last); } - - /** Advances the state of the generator by @c z. */ - void discard(boost::uintmax_t z) - { - typedef const_mod mod_type; - IntType b_inv = mod_type::invert(a-1); - IntType b_gcd = mod_type::mult(a-1, b_inv); - if(b_gcd == 1) { - IntType a_z = mod_type::pow(a, z); - _x = mod_type::mult_add(a_z, _x, - mod_type::mult(mod_type::mult(c, b_inv), a_z - 1)); - } else { - // compute (a^z - 1)*c % (b_gcd * m) / (b / b_gcd) * inv(b / b_gcd) - // we're storing the intermediate result / b_gcd - IntType a_zm1_over_gcd = 0; - IntType a_km1_over_gcd = (a - 1) / b_gcd; - boost::uintmax_t exponent = z; - while(exponent != 0) { - if(exponent % 2 == 1) { - a_zm1_over_gcd = - mod_type::mult_add( - b_gcd, - mod_type::mult(a_zm1_over_gcd, a_km1_over_gcd), - mod_type::add(a_zm1_over_gcd, a_km1_over_gcd)); - } - a_km1_over_gcd = mod_type::mult_add( - b_gcd, - mod_type::mult(a_km1_over_gcd, a_km1_over_gcd), - mod_type::add(a_km1_over_gcd, a_km1_over_gcd)); - exponent /= 2; - } - - IntType a_z = mod_type::mult_add(b_gcd, a_zm1_over_gcd, 1); - IntType num = mod_type::mult(c, a_zm1_over_gcd); - b_inv = mod_type::invert((a-1)/b_gcd); - _x = mod_type::mult_add(a_z, _x, mod_type::mult(b_inv, num)); - } - } - - friend bool operator==(const linear_congruential_engine& x, - const linear_congruential_engine& y) - { return x._x == y._x; } - friend bool operator!=(const linear_congruential_engine& x, - const linear_congruential_engine& y) - { return !(x == y); } - -#if !defined(BOOST_RANDOM_NO_STREAM_OPERATORS) - /** Writes a @c linear_congruential_engine to a @c std::ostream. */ - template - friend std::basic_ostream& - operator<<(std::basic_ostream& os, - const linear_congruential_engine& lcg) - { - return os << lcg._x; - } - - /** Reads a @c linear_congruential_engine from a @c std::istream. */ - template - friend std::basic_istream& - operator>>(std::basic_istream& is, - linear_congruential_engine& lcg) - { - lcg.read(is); - return is; - } -#endif - -private: - - /// \cond show_private - - template - void read(std::basic_istream& is) { - IntType x; - if(is >> x) { - if(x >= (min)() && x <= (max)()) { - _x = x; - } else { - is.setstate(std::ios_base::failbit); - } - } - } - - /// \endcond - - IntType _x; -}; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION -// A definition is required even for integral static constants -template -const bool linear_congruential_engine::has_fixed_range; -template -const IntType linear_congruential_engine::multiplier; -template -const IntType linear_congruential_engine::increment; -template -const IntType linear_congruential_engine::modulus; -template -const IntType linear_congruential_engine::default_seed; -#endif - -/// \cond show_deprecated - -// provided for backwards compatibility -template -class linear_congruential : public linear_congruential_engine -{ - typedef linear_congruential_engine base_type; -public: - linear_congruential(IntType x0 = 1) : base_type(x0) {} - template - linear_congruential(It& first, It last) : base_type(first, last) {} -}; - -/// \endcond - -/** - * The specialization \minstd_rand0 was originally suggested in - * - * @blockquote - * A pseudo-random number generator for the System/360, P.A. Lewis, - * A.S. Goodman, J.M. Miller, IBM Systems Journal, Vol. 8, No. 2, - * 1969, pp. 136-146 - * @endblockquote - * - * It is examined more closely together with \minstd_rand in - * - * @blockquote - * "Random Number Generators: Good ones are hard to find", - * Stephen K. Park and Keith W. Miller, Communications of - * the ACM, Vol. 31, No. 10, October 1988, pp. 1192-1201 - * @endblockquote - */ -typedef linear_congruential_engine minstd_rand0; - -/** The specialization \minstd_rand was suggested in - * - * @blockquote - * "Random Number Generators: Good ones are hard to find", - * Stephen K. Park and Keith W. Miller, Communications of - * the ACM, Vol. 31, No. 10, October 1988, pp. 1192-1201 - * @endblockquote - */ -typedef linear_congruential_engine minstd_rand; - - -#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T) -/** - * Class @c rand48 models a \pseudo_random_number_generator. It uses - * the linear congruential algorithm with the parameters a = 0x5DEECE66D, - * c = 0xB, m = 2**48. It delivers identical results to the @c lrand48() - * function available on some systems (assuming lcong48 has not been called). - * - * It is only available on systems where @c uint64_t is provided as an - * integral type, so that for example static in-class constants and/or - * enum definitions with large @c uint64_t numbers work. - */ -class rand48 -{ -public: - typedef boost::uint32_t result_type; - - BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); - /** - * Returns the smallest value that the generator can produce - */ - static BOOST_CONSTEXPR uint32_t min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; } - /** - * Returns the largest value that the generator can produce - */ - static BOOST_CONSTEXPR uint32_t max BOOST_PREVENT_MACRO_SUBSTITUTION () - { return 0x7FFFFFFF; } - - /** Seeds the generator with the default seed. */ - rand48() : lcf(cnv(static_cast(1))) {} - /** - * Constructs a \rand48 generator with x(0) := (x0 << 16) | 0x330e. - */ - BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(rand48, result_type, x0) - { seed(x0); } - /** - * Seeds the generator with values produced by @c seq.generate(). - */ - BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(rand48, SeedSeq, seq) - { seed(seq); } - /** - * Seeds the generator using values from an iterator range, - * and updates first to point one past the last value consumed. - */ - template rand48(It& first, It last) : lcf(first, last) { } - - // compiler-generated copy ctor and assignment operator are fine - - /** Seeds the generator with the default seed. */ - void seed() { seed(static_cast(1)); } - /** - * Changes the current value x(n) of the generator to (x0 << 16) | 0x330e. - */ - BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(rand48, result_type, x0) - { lcf.seed(cnv(x0)); } - /** - * Seeds the generator using values from an iterator range, - * and updates first to point one past the last value consumed. - */ - template void seed(It& first, It last) { lcf.seed(first,last); } - /** - * Seeds the generator with values produced by @c seq.generate(). - */ - BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(rand48, SeedSeq, seq) - { lcf.seed(seq); } - - /** Returns the next value of the generator. */ - uint32_t operator()() { return static_cast(lcf() >> 17); } - - /** Advances the state of the generator by @c z. */ - void discard(boost::uintmax_t z) { lcf.discard(z); } - - /** Fills a range with random values */ - template - void generate(Iter first, Iter last) - { - for(; first != last; ++first) { - *first = (*this)(); - } - } - -#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS - /** Writes a @c rand48 to a @c std::ostream. */ - template - friend std::basic_ostream& - operator<<(std::basic_ostream& os, const rand48& r) - { os << r.lcf; return os; } - - /** Reads a @c rand48 from a @c std::istream. */ - template - friend std::basic_istream& - operator>>(std::basic_istream& is, rand48& r) - { is >> r.lcf; return is; } -#endif - - /** - * Returns true if the two generators will produce identical - * sequences of values. - */ - friend bool operator==(const rand48& x, const rand48& y) - { return x.lcf == y.lcf; } - /** - * Returns true if the two generators will produce different - * sequences of values. - */ - friend bool operator!=(const rand48& x, const rand48& y) - { return !(x == y); } -private: - /// \cond show_private - typedef random::linear_congruential_engine lcf_t; - lcf_t lcf; - - static boost::uint64_t cnv(boost::uint32_t x) - { return (static_cast(x) << 16) | 0x330e; } - /// \endcond -}; -#endif /* !BOOST_NO_INT64_T && !BOOST_NO_INTEGRAL_INT64_T */ - -} // namespace random - -using random::minstd_rand0; -using random::minstd_rand; -using random::rand48; - -} // namespace boost - -#include - -#endif // BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP diff --git a/boost/random/traits.hpp b/boost/random/traits.hpp deleted file mode 100644 index 437157cd..00000000 --- a/boost/random/traits.hpp +++ /dev/null @@ -1,107 +0,0 @@ -/* boost random/traits.hpp header file - * - * Copyright John Maddock 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 including documentation. - * - * These traits classes serve two purposes: they are designed to mostly - * work out of the box for multiprecision types (ie number types that are - * C++ class types and not integers or floats from type-traits point of view), - * they are also a potential point of specialization for user-defined - * number types. - * - * $Id$ - */ - -#ifndef BOOST_RANDOM_TRAITS_HPP -#define BOOST_RANDOM_TRAITS_HPP - -#include -#include -#include -#include -#include - -namespace boost { -namespace random { -namespace traits { - // \cond show_private - template - struct make_unsigned_imp - { - typedef typename boost::make_unsigned::type type; - }; - template - struct make_unsigned_imp - { - BOOST_STATIC_ASSERT(std::numeric_limits::is_specialized); - BOOST_STATIC_ASSERT(std::numeric_limits::is_signed == false); - BOOST_STATIC_ASSERT(std::numeric_limits::is_integer == true); - typedef T type; - }; - // \endcond - /** \brief Converts the argument type T to an unsigned type. - * - * This trait has a single member `type` which is the unsigned type corresponding to T. - * Note that - * if T is signed, then member `type` *should define a type with one more bit precision than T*. For built-in - * types this trait defaults to `boost::make_unsigned::type`. For user defined types it simply asserts that - * the argument type T is an unsigned integer (using std::numeric_limits). - * User defined specializations may be provided for other cases. - */ - template - struct make_unsigned - // \cond show_private - : public make_unsigned_imp < T, boost::is_integral::value > - // \endcond - {}; - // \cond show_private - template - struct make_unsigned_or_unbounded_imp - { - typedef typename boost::make_unsigned::type type; - }; - template - struct make_unsigned_or_unbounded_imp - { - BOOST_STATIC_ASSERT(std::numeric_limits::is_specialized); - BOOST_STATIC_ASSERT((std::numeric_limits::is_signed == false) || (std::numeric_limits::is_bounded == false)); - BOOST_STATIC_ASSERT(std::numeric_limits::is_integer == true); - typedef T type; - }; - // \endcond - /** \brief Converts the argument type T to either an unsigned type or an unbounded integer type. - * - * This trait has a single member `type` which is either the unsigned type corresponding to T or an unbounded - * integer type. This trait is used to generate types suitable for the calculation of a range: as a result - * if T is signed, then member `type` *should define a type with one more bit precision than T*. For built-in - * types this trait defaults to `boost::make_unsigned::type`. For user defined types it simply asserts that - * the argument type T is either an unbounded integer, or an unsigned one (using std::numeric_limits). - * User defined specializations may be provided for other cases. - */ - template - struct make_unsigned_or_unbounded - // \cond show_private - : public make_unsigned_or_unbounded_imp < T, boost::is_integral::value > - // \endcond - {}; - /** \brief Traits class that indicates whether type T is an integer - */ - template - struct is_integral - : public integral_constant::value || (std::numeric_limits::is_integer)> - {}; - /** \brief Traits class that indicates whether type T is a signed integer - */ - template struct is_signed - : public integral_constant::value || (std::numeric_limits::is_specialized && std::numeric_limits::is_integer && std::numeric_limits::is_signed)> - {}; - -} -} -} - -#endif diff --git a/boost/random/uniform_01.hpp b/boost/random/uniform_01.hpp deleted file mode 100644 index 37258f58..00000000 --- a/boost/random/uniform_01.hpp +++ /dev/null @@ -1,257 +0,0 @@ -/* boost random/uniform_01.hpp header file - * - * Copyright Jens Maurer 2000-2001 - * Distributed under the Boost Software License, Version 1.0. (See - * accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org for most recent version including documentation. - * - * $Id$ - * - * Revision history - * 2001-02-18 moved to individual header files - */ - -#ifndef BOOST_RANDOM_UNIFORM_01_HPP -#define BOOST_RANDOM_UNIFORM_01_HPP - -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace random { - -#ifdef BOOST_RANDOM_DOXYGEN - -/** - * The distribution function uniform_01 models a \random_distribution. - * On each invocation, it returns a random floating-point value - * uniformly distributed in the range [0..1). - * - * The template parameter RealType shall denote a float-like value type - * with support for binary operators +, -, and /. - * - * Note: The current implementation is buggy, because it may not fill - * all of the mantissa with random bits. I'm unsure how to fill a - * (to-be-invented) @c boost::bigfloat class with random bits efficiently. - * It's probably time for a traits class. - */ -template -class uniform_01 -{ -public: - typedef RealType input_type; - typedef RealType result_type; - result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const; - result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const; - void reset(); - - template - result_type operator()(Engine& eng); - -#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS - template - friend std::basic_ostream& - operator<<(std::basic_ostream& os, const new_uniform_01&) - { - return os; - } - - template - friend std::basic_istream& - operator>>(std::basic_istream& is, new_uniform_01&) - { - return is; - } -#endif -}; - -#else - -namespace detail { - -template -class new_uniform_01 -{ -public: - typedef RealType input_type; - typedef RealType result_type; - // compiler-generated copy ctor and copy assignment are fine - result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); } - result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); } - void reset() { } - - template - result_type operator()(Engine& eng) { - for (;;) { - typedef typename Engine::result_type base_result; - result_type factor = result_type(1) / - (result_type(base_result((eng.max)()-(eng.min)())) + - result_type(std::numeric_limits::is_integer ? 1 : 0)); - result_type result = result_type(base_result(eng() - (eng.min)())) * factor; - if (result < result_type(1)) - return result; - } - } - -#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS - template - friend std::basic_ostream& - operator<<(std::basic_ostream& os, const new_uniform_01&) - { - return os; - } - - template - friend std::basic_istream& - operator>>(std::basic_istream& is, new_uniform_01&) - { - return is; - } -#endif -}; - -template -class backward_compatible_uniform_01 -{ - typedef boost::random::detail::ptr_helper traits; -public: - typedef UniformRandomNumberGenerator base_type; - typedef RealType result_type; - - BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); - -#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) - BOOST_STATIC_ASSERT(!std::numeric_limits::is_integer); -#endif - - explicit backward_compatible_uniform_01(typename traits::rvalue_type rng) - : _rng(rng), - _factor(result_type(1) / - (result_type((base().max)()-(base().min)()) + - result_type(std::numeric_limits::is_integer ? 1 : 0))) - { - } - // compiler-generated copy ctor and copy assignment are fine - - result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); } - result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); } - typename traits::value_type& base() { return traits::ref(_rng); } - const typename traits::value_type& base() const { return traits::ref(_rng); } - void reset() { } - - result_type operator()() { - for (;;) { - result_type result = result_type(base()() - (base().min)()) * _factor; - if (result < result_type(1)) - return result; - } - } - -#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) - template - friend std::basic_ostream& - operator<<(std::basic_ostream& os, const backward_compatible_uniform_01& u) - { - os << u._rng; - return os; - } - - template - friend std::basic_istream& - operator>>(std::basic_istream& is, backward_compatible_uniform_01& u) - { - is >> u._rng; - return is; - } -#endif - -private: - typedef typename traits::value_type::result_type base_result; - UniformRandomNumberGenerator _rng; - result_type _factor; -}; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION -// A definition is required even for integral static constants -template -const bool backward_compatible_uniform_01::has_fixed_range; -#endif - -template::is_specialized> -struct select_uniform_01 -{ - template - struct apply - { - typedef backward_compatible_uniform_01 type; - }; -}; - -template -struct select_uniform_01 -{ - template - struct apply - { - typedef new_uniform_01 type; - }; -}; - -} - -// Because it is so commonly used: uniform distribution on the real [0..1) -// range. This allows for specializations to avoid a costly int -> float -// conversion plus float multiplication -template -class uniform_01 - : public detail::select_uniform_01::BOOST_NESTED_TEMPLATE apply::type -{ - typedef typename detail::select_uniform_01::BOOST_NESTED_TEMPLATE apply::type impl_type; - typedef boost::random::detail::ptr_helper traits; -public: - - uniform_01() {} - - explicit uniform_01(typename traits::rvalue_type rng) - : impl_type(rng) - { - } - -#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) - template - friend std::basic_ostream& - operator<<(std::basic_ostream& os, const uniform_01& u) - { - os << static_cast(u); - return os; - } - - template - friend std::basic_istream& - operator>>(std::basic_istream& is, uniform_01& u) - { - is >> static_cast(u); - return is; - } -#endif -}; - -#endif - -} // namespace random - -using random::uniform_01; - -} // namespace boost - -#include - -#endif // BOOST_RANDOM_UNIFORM_01_HPP diff --git a/boost/random/uniform_smallint.hpp b/boost/random/uniform_smallint.hpp deleted file mode 100644 index d8f0cd3b..00000000 --- a/boost/random/uniform_smallint.hpp +++ /dev/null @@ -1,306 +0,0 @@ -/* boost random/uniform_smallint.hpp header file - * - * Copyright Jens Maurer 2000-2001 - * Distributed under the Boost Software License, Version 1.0. (See - * accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org for most recent version including documentation. - * - * $Id$ - * - * Revision history - * 2001-04-08 added min -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS -#include -#endif - -namespace boost { -namespace random { - -// uniform integer distribution on a small range [min, max] - -/** - * The distribution function uniform_smallint models a \random_distribution. - * On each invocation, it returns a random integer value uniformly distributed - * in the set of integer numbers {min, min+1, min+2, ..., max}. It assumes - * that the desired range (max-min+1) is small compared to the range of the - * underlying source of random numbers and thus makes no attempt to limit - * quantization errors. - * - * Let \f$r_{\mathtt{out}} = (\mbox{max}-\mbox{min}+1)\f$ the desired range of - * integer numbers, and - * let \f$r_{\mathtt{base}}\f$ be the range of the underlying source of random - * numbers. Then, for the uniform distribution, the theoretical probability - * for any number i in the range \f$r_{\mathtt{out}}\f$ will be - * \f$\displaystyle p_{\mathtt{out}}(i) = \frac{1}{r_{\mathtt{out}}}\f$. - * Likewise, assume a uniform distribution on \f$r_{\mathtt{base}}\f$ for - * the underlying source of random numbers, i.e. - * \f$\displaystyle p_{\mathtt{base}}(i) = \frac{1}{r_{\mathtt{base}}}\f$. - * Let \f$p_{\mathtt{out\_s}}(i)\f$ denote the random - * distribution generated by @c uniform_smallint. Then the sum over all - * i in \f$r_{\mathtt{out}}\f$ of - * \f$\displaystyle - * \left(\frac{p_{\mathtt{out\_s}}(i)}{p_{\mathtt{out}}(i)} - 1\right)^2\f$ - * shall not exceed - * \f$\displaystyle \frac{r_{\mathtt{out}}}{r_{\mathtt{base}}^2} - * (r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}}) - * (r_{\mathtt{out}} - r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})\f$. - * - * The template parameter IntType shall denote an integer-like value type. - * - * @xmlnote - * The property above is the square sum of the relative differences - * in probabilities between the desired uniform distribution - * \f$p_{\mathtt{out}}(i)\f$ and the generated distribution - * \f$p_{\mathtt{out\_s}}(i)\f$. - * The property can be fulfilled with the calculation - * \f$(\mbox{base\_rng} \mbox{ mod } r_{\mathtt{out}})\f$, as follows: - * Let \f$r = r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}}\f$. - * The base distribution on \f$r_{\mathtt{base}}\f$ is folded onto the - * range \f$r_{\mathtt{out}}\f$. The numbers i < r have assigned - * \f$\displaystyle - * \left\lfloor\frac{r_{\mathtt{base}}}{r_{\mathtt{out}}}\right\rfloor+1\f$ - * numbers of the base distribution, the rest has only \f$\displaystyle - * \left\lfloor\frac{r_{\mathtt{base}}}{r_{\mathtt{out}}}\right\rfloor\f$. - * Therefore, - * \f$\displaystyle p_{\mathtt{out\_s}}(i) = - * \left(\left\lfloor\frac{r_{\mathtt{base}}} - * {r_{\mathtt{out}}}\right\rfloor+1\right) / - * r_{\mathtt{base}}\f$ for i < r and \f$\displaystyle p_{\mathtt{out\_s}}(i) = - * \left\lfloor\frac{r_{\mathtt{base}}} - * {r_{\mathtt{out}}}\right\rfloor/r_{\mathtt{base}}\f$ otherwise. - * Substituting this in the - * above sum formula leads to the desired result. - * @endxmlnote - * - * Note: The upper bound for - * \f$(r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}}) - * (r_{\mathtt{out}} - r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})\f$ is - * \f$\displaystyle \frac{r_{\mathtt{out}}^2}{4}\f$. Regarding the upper bound - * for the square sum of the relative quantization error of - * \f$\displaystyle \frac{r_\mathtt{out}^3}{4r_{\mathtt{base}}^2}\f$, it - * seems wise to either choose \f$r_{\mathtt{base}}\f$ so that - * \f$r_{\mathtt{base}} > 10r_{\mathtt{out}}^2\f$ or ensure that - * \f$r_{\mathtt{base}}\f$ is - * divisible by \f$r_{\mathtt{out}}\f$. - */ -template -class uniform_smallint -{ -public: - typedef IntType input_type; - typedef IntType result_type; - - class param_type - { - public: - - typedef uniform_smallint distribution_type; - - /** constructs the parameters of a @c uniform_smallint distribution. */ - param_type(IntType min_arg = 0, IntType max_arg = 9) - : _min(min_arg), _max(max_arg) - { - BOOST_ASSERT(_min <= _max); - } - - /** Returns the minimum value. */ - IntType a() const { return _min; } - /** Returns the maximum value. */ - IntType b() const { return _max; } - - - /** Writes the parameters to a @c std::ostream. */ - BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm) - { - os << parm._min << " " << parm._max; - return os; - } - - /** Reads the parameters from a @c std::istream. */ - BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm) - { - is >> parm._min >> std::ws >> parm._max; - return is; - } - - /** Returns true if the two sets of parameters are equal. */ - BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs) - { return lhs._min == rhs._min && lhs._max == rhs._max; } - - /** Returns true if the two sets of parameters are different. */ - BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type) - - private: - IntType _min; - IntType _max; - }; - - /** - * Constructs a @c uniform_smallint. @c min and @c max are the - * lower and upper bounds of the output range, respectively. - */ - explicit uniform_smallint(IntType min_arg = 0, IntType max_arg = 9) - : _min(min_arg), _max(max_arg) {} - - /** - * Constructs a @c uniform_smallint from its parameters. - */ - explicit uniform_smallint(const param_type& parm) - : _min(parm.a()), _max(parm.b()) {} - - /** Returns the minimum value of the distribution. */ - result_type a() const { return _min; } - /** Returns the maximum value of the distribution. */ - result_type b() const { return _max; } - /** Returns the minimum value of the distribution. */ - result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; } - /** Returns the maximum value of the distribution. */ - result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; } - - /** Returns the parameters of the distribution. */ - param_type param() const { return param_type(_min, _max); } - /** Sets the parameters of the distribution. */ - void param(const param_type& parm) - { - _min = parm.a(); - _max = parm.b(); - } - - /** - * Effects: Subsequent uses of the distribution do not depend - * on values produced by any engine prior to invoking reset. - */ - void reset() { } - - /** Returns a value uniformly distributed in the range [min(), max()]. */ - template - result_type operator()(Engine& eng) const - { - typedef typename Engine::result_type base_result; - return generate(eng, boost::random::traits::is_integral()); - } - - /** Returns a value uniformly distributed in the range [param.a(), param.b()]. */ - template - result_type operator()(Engine& eng, const param_type& parm) const - { return uniform_smallint(parm)(eng); } - - /** Writes the distribution to a @c std::ostream. */ - BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_smallint, ud) - { - os << ud._min << " " << ud._max; - return os; - } - - /** Reads the distribution from a @c std::istream. */ - BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_smallint, ud) - { - is >> ud._min >> std::ws >> ud._max; - return is; - } - - /** - * Returns true if the two distributions will produce identical - * sequences of values given equal generators. - */ - BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_smallint, lhs, rhs) - { return lhs._min == rhs._min && lhs._max == rhs._max; } - - /** - * Returns true if the two distributions may produce different - * sequences of values given equal generators. - */ - BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_smallint) - -private: - - // \cond show_private - template - result_type generate(Engine& eng, boost::true_type) const - { - // equivalent to (eng() - eng.min()) % (_max - _min + 1) + _min, - // but guarantees no overflow. - typedef typename Engine::result_type base_result; - typedef typename boost::random::traits::make_unsigned::type base_unsigned; - typedef typename boost::random::traits::make_unsigned_or_unbounded::type range_type; -#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS - typedef typename conditional< - std::numeric_limits::is_specialized && std::numeric_limits::is_specialized - && (std::numeric_limits::digits >= std::numeric_limits::digits), - range_type, base_unsigned>::type mixed_range_type; -#else - typedef base_unsigned mixed_range_type; -#endif - range_type range = random::detail::subtract()(_max, _min); - base_unsigned base_range = - random::detail::subtract()((eng.max)(), (eng.min)()); - base_unsigned val = - random::detail::subtract()(eng(), (eng.min)()); - if(range >= base_range) { - return boost::random::detail::add()( - static_cast(val), _min); - } else { - // This involves mixed arithmetic between the base generators range - // type, and the result_type's range type. mixed_range_type is - // normally the same as base_unsigned which is the most efficient - // option, but requires a narrowing explcit cast if result_type - // is a multiprecision type. If no such casts are available then use - // multiprecision arithmetic throughout instead. - mixed_range_type modulus = static_cast(range)+1; - return boost::random::detail::add()( - static_cast(val) % modulus, _min); - } - } - - template - result_type generate(Engine& eng, boost::false_type) const - { - typedef typename Engine::result_type base_result; - typedef typename boost::random::traits::make_unsigned::type range_type; - range_type range = random::detail::subtract()(_max, _min); - base_result val = boost::uniform_01()(eng); - // what is the worst that can possibly happen here? - // base_result may not be able to represent all the values in [0, range] - // exactly. If this happens, it will cause round off error and we - // won't be able to produce all the values in the range. We don't - // care about this because the user has already told us not to by - // using uniform_smallint. However, we do need to be careful - // to clamp the result, or floating point rounding can produce - // an out of range result. - range_type offset = static_cast(val * (static_cast(range) + 1)); - if(offset > range) return _max; - return boost::random::detail::add()(offset , _min); - } - // \endcond - - result_type _min; - result_type _max; -}; - -} // namespace random - -using random::uniform_smallint; - -} // namespace boost - -#endif // BOOST_RANDOM_UNIFORM_SMALLINT_HPP diff --git a/boost/type_index.hpp b/boost/type_index.hpp new file mode 100644 index 00000000..07ea5153 --- /dev/null +++ b/boost/type_index.hpp @@ -0,0 +1,285 @@ +// +// Copyright 2012-2023 Antony Polukhin. +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_TYPE_INDEX_HPP +#define BOOST_TYPE_INDEX_HPP + +/// \file boost/type_index.hpp +/// \brief Includes minimal set of headers required to use the Boost.TypeIndex library. +/// +/// By inclusion of this file most optimal type index classes will be included and used +/// as a boost::typeindex::type_index and boost::typeindex::type_info. + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + + + +#include +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \ + defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) || \ + defined(BOOST_NO_CXX11_CONSTEXPR) || \ + defined(BOOST_NO_CXX11_NULLPTR) || \ + defined(BOOST_NO_CXX11_NOEXCEPT) || \ + defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || \ + defined(BOOST_NO_CXX11_FINAL) || \ + defined(BOOST_NO_CXX11_ALIGNOF) || \ + defined(BOOST_NO_CXX11_STATIC_ASSERT) || \ + defined(BOOST_NO_CXX11_SMART_PTR) || \ + defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) || \ + defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + +BOOST_PRAGMA_MESSAGE("C++03 support is deprecated in Boost.TypeIndex 1.82 and will be removed in Boost.TypeIndex 1.84.") + +#endif + +#if defined(BOOST_TYPE_INDEX_USER_TYPEINDEX) +# include BOOST_TYPE_INDEX_USER_TYPEINDEX +# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH +# pragma detect_mismatch( "boost__type_index__abi", "user defined type_index class is used: " BOOST_STRINGIZE(BOOST_TYPE_INDEX_USER_TYPEINDEX)) +# endif +#elif (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC) +# include +# if defined(BOOST_NO_RTTI) || defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY) +# include +# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH +# pragma detect_mismatch( "boost__type_index__abi", "RTTI is off - typeid() is used only for templates") +# endif +# else +# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH +# pragma detect_mismatch( "boost__type_index__abi", "RTTI is used") +# endif +# endif +#else +# include +# include +# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH +# pragma detect_mismatch( "boost__type_index__abi", "RTTI is off - using CTTI") +# endif +#endif + +#ifndef BOOST_TYPE_INDEX_REGISTER_CLASS +#define BOOST_TYPE_INDEX_REGISTER_CLASS +#endif + +namespace boost { namespace typeindex { + +#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED) + +/// \def BOOST_TYPE_INDEX_FUNCTION_SIGNATURE +/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is used by boost::typeindex::ctti_type_index class to +/// deduce the name of a type. If your compiler is not recognized +/// by the TypeIndex library and you wish to work with boost::typeindex::ctti_type_index, you may +/// define this macro by yourself. +/// +/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE must be defined to a compiler specific macro +/// that outputs the \b whole function signature \b including \b template \b parameters. +/// +/// If your compiler is not recognised and BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is not defined, +/// then a compile-time error will arise at any attempt to use boost::typeindex::ctti_type_index classes. +/// +/// See BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS and BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING +/// for an information of how to tune the implementation to make a nice pretty_name() output. +#define BOOST_TYPE_INDEX_FUNCTION_SIGNATURE BOOST_CURRENT_FUNCTION + +/// \def BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING +/// This is a helper macro for making correct pretty_names() with RTTI off. +/// +/// BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING macro may be defined to +/// '(begin_skip, end_skip, runtime_skip, runtime_skip_until)' with parameters for adding a +/// support for compilers, that by default are not recognized by TypeIndex library. +/// +/// \b Example: +/// +/// Imagine the situation when +/// \code boost::typeindex::ctti_type_index::type_id().pretty_name() \endcode +/// returns the following string: +/// \code "static const char *boost::detail::ctti::n() [T = int]" \endcode +/// and \code boost::typeindex::ctti_type_index::type_id().pretty_name() \endcode returns the following: +/// \code "static const char *boost::detail::ctti::n() [T = short]" \endcode +/// +/// As we may see first 39 characters are "static const char *boost::detail::ctti<" and they do not depend on +/// the type T. After first 39 characters we have a human readable type name which is duplicated at the end +/// of a string. String always ends on ']', which consumes 1 character. +/// +/// Now if we define `BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING` to +/// `(39, 1, false, "")` we'll be getting \code "int>::n() [T = int" \endcode +/// for `boost::typeindex::ctti_type_index::type_id().pretty_name()` and \code "short>::n() [T = short" \endcode +/// for `boost::typeindex::ctti_type_index::type_id().pretty_name()`. +/// +/// Now we need to take additional care of the characters that go before the last mention of our type. We'll +/// do that by telling the macro that we need to cut off everything that goes before the "T = " including the "T = " +/// itself: +/// +/// \code (39, 1, true, "T = ") \endcode +/// +/// In case of GCC or Clang command line we need to add the following line while compiling all the sources: +/// +/// \code +/// -DBOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING='(39, 1, true, "T = ")' +/// \endcode +/// \param begin_skip How many characters must be skipped at the beginning of the type holding string. +/// Must be a compile time constant. +/// \param end_skip How many characters must be skipped at the end of the type holding string. +/// Must be a compile time constant. +/// \param runtime_skip Do we need additional checks at runtime to cut off the more characters. +/// Must be `true` or `false`. +/// \param runtime_skip_until Skip all the characters before the following string (including the string itself). +/// Must be a compile time array of characters. +/// +/// See [RTTI emulation limitations](boost_typeindex/rtti_emulation_limitations.html) for more info. +#define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING (0, 0, false, "") + + + /// Depending on a compiler flags, optimal implementation of type_index will be used + /// as a default boost::typeindex::type_index. + /// + /// Could be a boost::typeindex::stl_type_index, boost::typeindex::ctti_type_index or + /// user defined type_index class. + /// + /// \b See boost::typeindex::type_index_facade for a full description of type_index functions. + typedef platform_specific type_index; +#elif defined(BOOST_TYPE_INDEX_USER_TYPEINDEX) + // Nothing to do +#elif (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC) + typedef boost::typeindex::stl_type_index type_index; +#else + typedef boost::typeindex::ctti_type_index type_index; +#endif + +/// Depending on a compiler flags, optimal implementation of type_info will be used +/// as a default boost::typeindex::type_info. +/// +/// Could be a std::type_info, boost::typeindex::detail::ctti_data or +/// some user defined class. +/// +/// type_info \b is \b not copyable or default constructible. It is \b not assignable too! +typedef type_index::type_info_t type_info; + +#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED) + +/// \def BOOST_TYPE_INDEX_USER_TYPEINDEX +/// BOOST_TYPE_INDEX_USER_TYPEINDEX can be defined to the path to header file +/// with user provided implementation of type_index. +/// +/// See [Making a custom type_index](boost_typeindex/making_a_custom_type_index.html) section +/// of documentation for usage example. +#define BOOST_TYPE_INDEX_USER_TYPEINDEX + + +/// \def BOOST_TYPE_INDEX_REGISTER_CLASS +/// BOOST_TYPE_INDEX_REGISTER_CLASS is used to help to emulate RTTI. +/// Put this macro into the public section of polymorphic class to allow runtime type detection. +/// +/// Depending on the typeid() availability this macro will expand to nothing or to virtual helper function +/// `virtual const type_info& boost_type_info_type_id_runtime_() const noexcept`. +/// +/// \b Example: +/// \code +/// class A { +/// public: +/// BOOST_TYPE_INDEX_REGISTER_CLASS +/// virtual ~A(){} +/// }; +/// +/// struct B: public A { +/// BOOST_TYPE_INDEX_REGISTER_CLASS +/// }; +/// +/// struct C: public B { +/// BOOST_TYPE_INDEX_REGISTER_CLASS +/// }; +/// +/// ... +/// +/// C c1; +/// A* pc1 = &c1; +/// assert(boost::typeindex::type_id() == boost::typeindex::type_id_runtime(*pc1)); +/// \endcode +#define BOOST_TYPE_INDEX_REGISTER_CLASS nothing-or-some-virtual-functions + +/// \def BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY +/// BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY is a helper macro that must be defined if mixing +/// RTTI on/off modules. See +/// [Mixing sources with RTTI on and RTTI off](boost_typeindex/mixing_sources_with_rtti_on_and_.html) +/// section of documentation for more info. +#define BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY + +#endif // defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED) + + +/// Function to get boost::typeindex::type_index for a type T. +/// Removes const, volatile && and & modifiers from T. +/// +/// \b Example: +/// \code +/// type_index ti = type_id(); +/// std::cout << ti.pretty_name(); // Outputs 'int' +/// \endcode +/// +/// \tparam T Type for which type_index must be created. +/// \throw Nothing. +/// \return boost::typeindex::type_index with information about the specified type T. +template +inline type_index type_id() BOOST_NOEXCEPT { + return type_index::type_id(); +} + +/// Function for constructing boost::typeindex::type_index instance for type T. +/// Does not remove const, volatile, & and && modifiers from T. +/// +/// If T has no const, volatile, & and && modifiers, then returns exactly +/// the same result as in case of calling `type_id()`. +/// +/// \b Example: +/// \code +/// type_index ti = type_id_with_cvr(); +/// std::cout << ti.pretty_name(); // Outputs 'int&' +/// \endcode +/// +/// \tparam T Type for which type_index must be created. +/// \throw Nothing. +/// \return boost::typeindex::type_index with information about the specified type T. +template +inline type_index type_id_with_cvr() BOOST_NOEXCEPT { + return type_index::type_id_with_cvr(); +} + +/// Function that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index. +/// +/// Returns runtime information about specified type. +/// +/// \b Requirements: RTTI available or Base and Derived classes must be marked with BOOST_TYPE_INDEX_REGISTER_CLASS. +/// +/// \b Example: +/// \code +/// struct Base { virtual ~Base(){} }; +/// struct Derived: public Base {}; +/// ... +/// Derived d; +/// Base& b = d; +/// type_index ti = type_id_runtime(b); +/// std::cout << ti.pretty_name(); // Outputs 'Derived' +/// \endcode +/// +/// \param runtime_val Variable which runtime type must be returned. +/// \throw Nothing. +/// \return boost::typeindex::type_index with information about the specified variable. +template +inline type_index type_id_runtime(const T& runtime_val) BOOST_NOEXCEPT { + return type_index::type_id_runtime(runtime_val); +} + +}} // namespace boost::typeindex + + + +#endif // BOOST_TYPE_INDEX_HPP + diff --git a/boost/type_index/ctti_type_index.hpp b/boost/type_index/ctti_type_index.hpp new file mode 100644 index 00000000..818545b8 --- /dev/null +++ b/boost/type_index/ctti_type_index.hpp @@ -0,0 +1,213 @@ +// +// Copyright 2013-2023 Antony Polukhin. +// +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP +#define BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP + +/// \file ctti_type_index.hpp +/// \brief Contains boost::typeindex::ctti_type_index class that is constexpr if C++14 constexpr is supported by compiler. +/// +/// boost::typeindex::ctti_type_index class can be used as a drop-in replacement +/// for std::type_index. +/// +/// It is used in situations when typeid() method is not available or +/// BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro is defined. + +#include +#include + +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +namespace boost { namespace typeindex { + +namespace detail { + +// That's the most trickiest part of the TypeIndex library: +// 1) we do not want to give user ability to manually construct and compare `struct-that-represents-type` +// 2) we need to distinguish between `struct-that-represents-type` and `const char*` +// 3) we need a thread-safe way to have references to instances `struct-that-represents-type` +// 4) we need a compile-time control to make sure that user does not copy or +// default construct `struct-that-represents-type` +// +// Solution would be the following: + +/// \class ctti_data +/// Standard-layout class with private constructors and assignment operators. +/// +/// You can not work with this class directly. The purpose of this class is to hold type info +/// \b when \b RTTI \b is \b off and allow ctti_type_index construction from itself. +/// +/// \b Example: +/// \code +/// const detail::ctti_data& foo(); +/// ... +/// type_index ti = type_index(foo()); +/// std::cout << ti.pretty_name(); +/// \endcode +class ctti_data { +#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS +public: + ctti_data() = delete; + ctti_data(const ctti_data&) = delete; + ctti_data& operator=(const ctti_data&) = delete; +#else +private: + ctti_data(); + ctti_data(const ctti_data&); + ctti_data& operator=(const ctti_data&); +#endif +}; + +} // namespace detail + +/// Helper method for getting detail::ctti_data of a template parameter T. +template +inline const detail::ctti_data& ctti_construct() BOOST_NOEXCEPT { + // Standard C++11, 5.2.10 Reinterpret cast: + // An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue + // v of type "pointer to T1" is converted to the type "pointer to cv T2", the result is static_cast(static_cast(v)) if both T1 and T2 are standard-layout types (3.9) and the alignment + // requirements of T2 are no stricter than those of T1, or if either type is void. Converting a prvalue of type + // "pointer to T1" to the type "pointer to T2" (where T1 and T2 are object types and where the alignment + // requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer + // value. + // + // Alignments are checked in `type_index_test_ctti_alignment.cpp` test. + return *reinterpret_cast(boost::detail::ctti::n()); +} + +/// \class ctti_type_index +/// This class is a wrapper that pretends to work exactly like stl_type_index, but does +/// not require RTTI support. \b For \b description \b of \b functions \b see type_index_facade. +/// +/// This class on C++14 compatible compilers has following functions marked as constexpr: +/// * default constructor +/// * copy constructors and assignemnt operations +/// * class methods: name(), before(const ctti_type_index& rhs), equal(const ctti_type_index& rhs) +/// * static methods type_id(), type_id_with_cvr() +/// * comparison operators +/// +/// This class produces slightly longer type names, so consider using stl_type_index +/// in situations when typeid() is working. +class ctti_type_index: public type_index_facade { + const char* data_; + + inline std::size_t get_raw_name_length() const BOOST_NOEXCEPT; + + BOOST_CXX14_CONSTEXPR inline explicit ctti_type_index(const char* data) BOOST_NOEXCEPT + : data_(data) + {} + +public: + typedef detail::ctti_data type_info_t; + + BOOST_CXX14_CONSTEXPR inline ctti_type_index() BOOST_NOEXCEPT + : data_(boost::detail::ctti::n()) + {} + + inline ctti_type_index(const type_info_t& data) BOOST_NOEXCEPT + : data_(reinterpret_cast(&data)) + {} + + inline const type_info_t& type_info() const BOOST_NOEXCEPT; + BOOST_CXX14_CONSTEXPR inline const char* raw_name() const BOOST_NOEXCEPT; + BOOST_CXX14_CONSTEXPR inline const char* name() const BOOST_NOEXCEPT; + inline std::string pretty_name() const; + inline std::size_t hash_code() const BOOST_NOEXCEPT; + + BOOST_CXX14_CONSTEXPR inline bool equal(const ctti_type_index& rhs) const BOOST_NOEXCEPT; + BOOST_CXX14_CONSTEXPR inline bool before(const ctti_type_index& rhs) const BOOST_NOEXCEPT; + + template + BOOST_CXX14_CONSTEXPR inline static ctti_type_index type_id() BOOST_NOEXCEPT; + + template + BOOST_CXX14_CONSTEXPR inline static ctti_type_index type_id_with_cvr() BOOST_NOEXCEPT; + + template + inline static ctti_type_index type_id_runtime(const T& variable) BOOST_NOEXCEPT; +}; + + +inline const ctti_type_index::type_info_t& ctti_type_index::type_info() const BOOST_NOEXCEPT { + return *reinterpret_cast(data_); +} + + +BOOST_CXX14_CONSTEXPR inline bool ctti_type_index::equal(const ctti_type_index& rhs) const BOOST_NOEXCEPT { + const char* const left = raw_name(); + const char* const right = rhs.raw_name(); + return /*left == right ||*/ !boost::typeindex::detail::constexpr_strcmp(left, right); +} + +BOOST_CXX14_CONSTEXPR inline bool ctti_type_index::before(const ctti_type_index& rhs) const BOOST_NOEXCEPT { + const char* const left = raw_name(); + const char* const right = rhs.raw_name(); + return /*left != right &&*/ boost::typeindex::detail::constexpr_strcmp(left, right) < 0; +} + + +template +BOOST_CXX14_CONSTEXPR inline ctti_type_index ctti_type_index::type_id() BOOST_NOEXCEPT { + typedef BOOST_DEDUCED_TYPENAME boost::remove_reference::type no_ref_t; + typedef BOOST_DEDUCED_TYPENAME boost::remove_cv::type no_cvr_t; + return ctti_type_index(boost::detail::ctti::n()); +} + + + +template +BOOST_CXX14_CONSTEXPR inline ctti_type_index ctti_type_index::type_id_with_cvr() BOOST_NOEXCEPT { + return ctti_type_index(boost::detail::ctti::n()); +} + + +template +inline ctti_type_index ctti_type_index::type_id_runtime(const T& variable) BOOST_NOEXCEPT { + return variable.boost_type_index_type_id_runtime_(); +} + + +BOOST_CXX14_CONSTEXPR inline const char* ctti_type_index::raw_name() const BOOST_NOEXCEPT { + return data_; +} + + +BOOST_CXX14_CONSTEXPR inline const char* ctti_type_index::name() const BOOST_NOEXCEPT { + return data_; +} + +inline std::size_t ctti_type_index::get_raw_name_length() const BOOST_NOEXCEPT { + return std::strlen(raw_name() + detail::ctti_skip_size_at_end); +} + + +inline std::string ctti_type_index::pretty_name() const { + std::size_t len = get_raw_name_length(); + while (raw_name()[len - 1] == ' ') --len; // MSVC sometimes adds whitespaces + return std::string(raw_name(), len); +} + + +inline std::size_t ctti_type_index::hash_code() const BOOST_NOEXCEPT { + return boost::hash_range(raw_name(), raw_name() + get_raw_name_length()); +} + + +}} // namespace boost::typeindex + +#endif // BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP + diff --git a/boost/type_index/detail/compile_time_type_info.hpp b/boost/type_index/detail/compile_time_type_info.hpp new file mode 100644 index 00000000..c8080841 --- /dev/null +++ b/boost/type_index/detail/compile_time_type_info.hpp @@ -0,0 +1,339 @@ +// +// Copyright 2012-2023 Antony Polukhin. +// +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP +#define BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP + +/// \file compile_time_type_info.hpp +/// \brief Contains helper macros and implementation details of boost::typeindex::ctti_type_index. +/// Not intended for inclusion from user's code. + +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +/// @cond +#if defined(__has_builtin) +#if __has_builtin(__builtin_constant_p) +#define BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x) +#endif +#if __has_builtin(__builtin_strcmp) +#define BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP(str1, str2) __builtin_strcmp(str1, str2) +#endif +#elif defined(__GNUC__) +#define BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x) +#define BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP(str1, str2) __builtin_strcmp(str1, str2) +#endif + +#define BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(begin_skip, end_skip, runtime_skip, runtime_skip_until) \ + namespace boost { namespace typeindex { namespace detail { \ + BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_begin = begin_skip; \ + BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_end = end_skip; \ + BOOST_STATIC_CONSTEXPR bool ctti_skip_more_at_runtime = runtime_skip; \ + BOOST_STATIC_CONSTEXPR char ctti_skip_until_runtime[] = runtime_skip_until; \ + }}} /* namespace boost::typeindex::detail */ \ + /**/ +/// @endcond + + +#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED) + /* Nothing to document. All the macro docs are moved to */ +#elif defined(BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING) +# include + BOOST_PP_EXPAND( BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING ) +#elif defined(_MSC_VER) && !defined(__clang__) && defined (BOOST_NO_CXX11_NOEXCEPT) + // sizeof("const char *__cdecl boost::detail::ctti<") - 1, sizeof(">::n(void)") - 1 + BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 10, false, "") +#elif defined(_MSC_VER) && !defined(__clang__) && !defined (BOOST_NO_CXX11_NOEXCEPT) + // sizeof("const char *__cdecl boost::detail::ctti<") - 1, sizeof(">::n(void) noexcept") - 1 + BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 19, 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 = ") +#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, "") +#elif defined(__clang__) && (__clang_major__ >= 4 || (__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 = ") +#elif defined(__EDG__) && !defined(BOOST_NO_CXX14_CONSTEXPR) + // sizeof("static cha boost::detail::ctti::s() [with I = 40U, T = ") - 1, sizeof("]") - 1 + // note: checked on 4.14 + BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(58, 1, false, "") +#elif defined(__EDG__) && defined(BOOST_NO_CXX14_CONSTEXPR) + // sizeof("static const char *boost::detail::ctti::n() [with T = ") - 1, sizeof("]") - 1 + // note: checked on 4.14 + BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "") +#elif defined(__GNUC__) && (__GNUC__ < 7) && !defined(BOOST_NO_CXX14_CONSTEXPR) + // sizeof("static constexpr char boost::detail::ctti::s() [with unsigned int I = 0u; T = ") - 1, sizeof("]") - 1 + BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(81, 1, false, "") +#elif defined(__GNUC__) && (__GNUC__ >= 7) && !defined(BOOST_NO_CXX14_CONSTEXPR) + // sizeof("static constexpr char boost::detail::ctti::s() [with unsigned int I = 0; T = ") - 1, sizeof("]") - 1 + BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(80, 1, false, "") +#elif defined(__GNUC__) && defined(BOOST_NO_CXX14_CONSTEXPR) + // sizeof("static const char* boost::detail::ctti::n() [with T = ") - 1, sizeof("]") - 1 + BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "") +#elif defined(__ghs__) + // sizeof("static const char *boost::detail::ctti::n() [with T = ") - 1, sizeof("]") - 1 + 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, "") +#endif + +#undef BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS + +namespace boost { namespace typeindex { namespace detail { + template + BOOST_CXX14_CONSTEXPR inline void assert_compile_time_legths() BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG( + Condition, + "TypeIndex library is misconfigured for your compiler. " + "Please define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct values. See section " + "'RTTI emulation limitations' of the documentation for more information." + ); + } + + template + BOOST_CXX14_CONSTEXPR inline void failed_to_get_function_name() BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG( + sizeof(T) && false, + "TypeIndex library could not detect your compiler. " + "Please make the BOOST_TYPE_INDEX_FUNCTION_SIGNATURE macro use " + "correct compiler macro for getting the whole function name. " + "Define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct value after that." + ); + } + +#if defined(BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT) + BOOST_CXX14_CONSTEXPR BOOST_FORCEINLINE bool is_constant_string(const char* str) BOOST_NOEXCEPT { + while (BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT(*str)) { + if (*str == '\0') + return true; + ++str; + } + return false; + } +#endif // defined(BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT) + + template + BOOST_CXX14_CONSTEXPR inline const char* skip_begining_runtime(const char* begin, boost::false_type) BOOST_NOEXCEPT { + return begin; + } + + template + BOOST_CXX14_CONSTEXPR inline ForwardIterator1 constexpr_search( + ForwardIterator1 first1, + ForwardIterator1 last1, + ForwardIterator2 first2, + ForwardIterator2 last2) BOOST_NOEXCEPT + { + if (first2 == last2) { + return first1; // specified in C++11 + } + + while (first1 != last1) { + ForwardIterator1 it1 = first1; + ForwardIterator2 it2 = first2; + + while (*it1 == *it2) { + ++it1; + ++it2; + if (it2 == last2) return first1; + if (it1 == last1) return last1; + } + + ++first1; + } + + return last1; + } + + BOOST_CXX14_CONSTEXPR inline int constexpr_strcmp_loop(const char *v1, const char *v2) BOOST_NOEXCEPT { + while (*v1 != '\0' && *v1 == *v2) { + ++v1; + ++v2; + } + + return static_cast(*v1) - *v2; + } + + BOOST_CXX14_CONSTEXPR inline int constexpr_strcmp(const char *v1, const char *v2) BOOST_NOEXCEPT { +#if !defined(BOOST_NO_CXX14_CONSTEXPR) && defined(BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT) && defined(BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP) + if (boost::typeindex::detail::is_constant_string(v1) && boost::typeindex::detail::is_constant_string(v2)) + return boost::typeindex::detail::constexpr_strcmp_loop(v1, v2); + return BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP(v1, v2); +#elif !defined(BOOST_NO_CXX14_CONSTEXPR) + return boost::typeindex::detail::constexpr_strcmp_loop(v1, v2); +#else + return std::strcmp(v1, v2); +#endif + } + + template + BOOST_CXX14_CONSTEXPR inline const char* skip_begining_runtime(const char* begin, boost::true_type) BOOST_NOEXCEPT { + const char* const it = constexpr_search( + begin, begin + ArrayLength, + ctti_skip_until_runtime, ctti_skip_until_runtime + sizeof(ctti_skip_until_runtime) - 1 + ); + return (it == begin + ArrayLength ? begin : it + sizeof(ctti_skip_until_runtime) - 1); + } + + template + BOOST_CXX14_CONSTEXPR inline const char* skip_begining(const char* begin) BOOST_NOEXCEPT { + assert_compile_time_legths<(ArrayLength > ctti_skip_size_at_begin + ctti_skip_size_at_end)>(); + return skip_begining_runtime( + begin + ctti_skip_size_at_begin, + boost::integral_constant() + ); + } + +#if !defined(__clang__) && defined(__GNUC__) && !defined(BOOST_NO_CXX14_CONSTEXPR) + template + struct index_seq {}; + + template + struct make_index_sequence_join; + + template + struct make_index_sequence_join, index_seq > { + typedef index_seq type; + }; + + template + struct make_index_seq_impl { + typedef typename make_index_sequence_join< + typename make_index_seq_impl::type, + typename make_index_seq_impl::type + >::type type; + }; + + template + struct make_index_seq_impl { + typedef index_seq<> type; + }; + + template + struct make_index_seq_impl { + typedef index_seq type; + }; + + template + struct cstring { + static constexpr unsigned int size_ = sizeof...(C); + static constexpr char data_[size_] = { C... }; + }; + + template + constexpr char cstring::data_[]; +#endif + +}}} // namespace boost::typeindex::detail + +namespace boost { namespace detail { + +/// Noncopyable type_info that does not require RTTI. +/// CTTI == Compile Time Type Info. +/// This name must be as short as possible, to avoid code bloat +template +struct ctti { + +#if !defined(__clang__) && defined(__GNUC__) && !defined(BOOST_NO_CXX14_CONSTEXPR) + //helper functions + template + constexpr static char s() BOOST_NOEXCEPT { // step + constexpr unsigned int offset = + (I >= 10u ? 1u : 0u) + + (I >= 100u ? 1u : 0u) + + (I >= 1000u ? 1u : 0u) + + (I >= 10000u ? 1u : 0u) + + (I >= 100000u ? 1u : 0u) + + (I >= 1000000u ? 1u : 0u) + ; + + #if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE) + return BOOST_TYPE_INDEX_FUNCTION_SIGNATURE[I + offset]; + #elif defined(__FUNCSIG__) + return __FUNCSIG__[I + offset]; + #else + return __PRETTY_FUNCTION__[I + offset]; + #endif + } + + template + constexpr static const char* impl(::boost::typeindex::detail::index_seq ) BOOST_NOEXCEPT { + return ::boost::typeindex::detail::cstring()...>::data_; + } + + template // `D` means `Dummy` + constexpr static const char* n() BOOST_NOEXCEPT { + #if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE) + constexpr unsigned int size = sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE); + #elif defined(__FUNCSIG__) + constexpr unsigned int size = sizeof(__FUNCSIG__); + #elif defined(__PRETTY_FUNCTION__) \ + || defined(__GNUC__) \ + || (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) \ + || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \ + || (defined(__ICC) && (__ICC >= 600)) \ + || defined(__ghs__) \ + || defined(__DMC__) + constexpr unsigned int size = sizeof(__PRETTY_FUNCTION__); + #else + boost::typeindex::detail::failed_to_get_function_name(); + #endif + + boost::typeindex::detail::assert_compile_time_legths< + (size > boost::typeindex::detail::ctti_skip_size_at_begin + boost::typeindex::detail::ctti_skip_size_at_end + sizeof("const *") - 1) + >(); + static_assert(!boost::typeindex::detail::ctti_skip_more_at_runtime, "Skipping for GCC in C++14 mode is unsupported"); + + typedef typename boost::typeindex::detail::make_index_seq_impl< + boost::typeindex::detail::ctti_skip_size_at_begin, + size - sizeof("const *") + 1 - boost::typeindex::detail::ctti_skip_size_at_begin + >::type idx_seq; + return impl(idx_seq()); + } +#else + /// Returns raw name. Must be as short, as possible, to avoid code bloat + BOOST_CXX14_CONSTEXPR static const char* n() BOOST_NOEXCEPT { + #if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE) + return boost::typeindex::detail::skip_begining< sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE) >(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE); + #elif defined(__FUNCSIG__) + return boost::typeindex::detail::skip_begining< sizeof(__FUNCSIG__) >(__FUNCSIG__); + #elif defined(__PRETTY_FUNCTION__) \ + || defined(__GNUC__) \ + || (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) \ + || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \ + || (defined(__ICC) && (__ICC >= 600)) \ + || defined(__ghs__) \ + || defined(__DMC__) \ + || defined(__clang__) + return boost::typeindex::detail::skip_begining< sizeof(__PRETTY_FUNCTION__) >(__PRETTY_FUNCTION__); + #else + boost::typeindex::detail::failed_to_get_function_name(); + return ""; + #endif + } +#endif +}; + +}} // namespace boost::detail + +#endif // BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP diff --git a/boost/type_index/detail/ctti_register_class.hpp b/boost/type_index/detail/ctti_register_class.hpp new file mode 100644 index 00000000..ba1f068a --- /dev/null +++ b/boost/type_index/detail/ctti_register_class.hpp @@ -0,0 +1,40 @@ +// +// Copyright 2013-2023 Antony Polukhin. +// +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP +#define BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP + +/// \file ctti_register_class.hpp +/// \brief Contains BOOST_TYPE_INDEX_REGISTER_CLASS macro implementation that uses boost::typeindex::ctti_type_index. +/// Not intended for inclusion from user's code. + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +namespace boost { namespace typeindex { namespace detail { + +template +inline const ctti_data& ctti_construct_typeid_ref(const T*) BOOST_NOEXCEPT { + return ctti_construct(); +} + +}}} // namespace boost::typeindex::detail + +/// @cond +#define BOOST_TYPE_INDEX_REGISTER_CLASS \ + virtual const boost::typeindex::detail::ctti_data& boost_type_index_type_id_runtime_() const BOOST_NOEXCEPT { \ + return boost::typeindex::detail::ctti_construct_typeid_ref(this); \ + } \ +/**/ +/// @endcond + +#endif // BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP + diff --git a/boost/type_index/detail/stl_register_class.hpp b/boost/type_index/detail/stl_register_class.hpp new file mode 100644 index 00000000..590fc96f --- /dev/null +++ b/boost/type_index/detail/stl_register_class.hpp @@ -0,0 +1,40 @@ +// +// Copyright 2013-2023 Antony Polukhin. +// +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP +#define BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP + +/// \file stl_register_class.hpp +/// \brief Contains BOOST_TYPE_INDEX_REGISTER_CLASS macro implementation that uses boost::typeindex::stl_type_index. +/// Not intended for inclusion from user's code. + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +namespace boost { namespace typeindex { namespace detail { + +template +inline const stl_type_index::type_info_t& stl_construct_typeid_ref(const T*) BOOST_NOEXCEPT { + return typeid(T); +} + +}}} // namespace boost::typeindex::detail + +/// @cond +#define BOOST_TYPE_INDEX_REGISTER_CLASS \ + virtual const boost::typeindex::stl_type_index::type_info_t& boost_type_index_type_id_runtime_() const BOOST_NOEXCEPT { \ + return boost::typeindex::detail::stl_construct_typeid_ref(this); \ + } \ +/**/ +/// @endcond + +#endif // BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP + diff --git a/boost/type_index/stl_type_index.hpp b/boost/type_index/stl_type_index.hpp new file mode 100644 index 00000000..06c3cac2 --- /dev/null +++ b/boost/type_index/stl_type_index.hpp @@ -0,0 +1,278 @@ +// +// Copyright 2013-2023 Antony Polukhin. +// +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP +#define BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP + +/// \file stl_type_index.hpp +/// \brief Contains boost::typeindex::stl_type_index class. +/// +/// boost::typeindex::stl_type_index class can be used as a drop-in replacement +/// for std::type_index. +/// +/// It is used in situations when RTTI is enabled or typeid() method is available. +/// When typeid() is disabled or BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro +/// is defined boost::typeindex::ctti is usually used instead of boost::typeindex::stl_type_index. + +#include + +// MSVC is capable of calling typeid(T) even when RTTI is off +#if defined(BOOST_NO_RTTI) && !defined(BOOST_MSVC) +#error "File boost/type_index/stl_type_index.ipp is not usable when typeid() is not available." +#endif + +#include +#include // std::strcmp, std::strlen, std::strstr +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if (defined(_MSC_VER) && _MSC_VER > 1600) \ + || (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__)) \ + || (defined(__GNUC__) && __GNUC__ > 4 && __cplusplus >= 201103) +# define BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE +#else +# include +#endif + +#if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \ + || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744) +# include +# include +# include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +namespace boost { namespace typeindex { + +/// \class stl_type_index +/// This class is a wrapper around std::type_info, that workarounds issues and provides +/// much more rich interface. \b For \b description \b of \b functions \b see type_index_facade. +/// +/// This class requires typeid() to work. For cases when RTTI is disabled see ctti_type_index. +class stl_type_index + : public type_index_facade< + stl_type_index, + #ifdef BOOST_NO_STD_TYPEINFO + type_info + #else + std::type_info + #endif + > +{ +public: +#ifdef BOOST_NO_STD_TYPEINFO + typedef type_info type_info_t; +#else + typedef std::type_info type_info_t; +#endif + +private: + const type_info_t* data_; + +public: + inline stl_type_index() BOOST_NOEXCEPT + : data_(&typeid(void)) + {} + + inline stl_type_index(const type_info_t& data) BOOST_NOEXCEPT + : data_(&data) + {} + + inline const type_info_t& type_info() const BOOST_NOEXCEPT; + + inline const char* raw_name() const BOOST_NOEXCEPT; + inline const char* name() const BOOST_NOEXCEPT; + inline std::string pretty_name() const; + + inline std::size_t hash_code() const BOOST_NOEXCEPT; + inline bool equal(const stl_type_index& rhs) const BOOST_NOEXCEPT; + inline bool before(const stl_type_index& rhs) const BOOST_NOEXCEPT; + + template + inline static stl_type_index type_id() BOOST_NOEXCEPT; + + template + inline static stl_type_index type_id_with_cvr() BOOST_NOEXCEPT; + + template + inline static stl_type_index type_id_runtime(const T& value) BOOST_NOEXCEPT; +}; + +inline const stl_type_index::type_info_t& stl_type_index::type_info() const BOOST_NOEXCEPT { + return *data_; +} + + +inline const char* stl_type_index::raw_name() const BOOST_NOEXCEPT { +#ifdef _MSC_VER + return data_->raw_name(); +#else + return data_->name(); +#endif +} + +inline const char* stl_type_index::name() const BOOST_NOEXCEPT { + return data_->name(); +} + +inline std::string stl_type_index::pretty_name() const { + static const char cvr_saver_name[] = "boost::typeindex::detail::cvr_saver<"; + static BOOST_CONSTEXPR_OR_CONST std::string::size_type cvr_saver_name_len = sizeof(cvr_saver_name) - 1; + + // In case of MSVC demangle() is a no-op, and name() already returns demangled name. + // In case of GCC and Clang (on non-Windows systems) name() returns mangled name and demangle() undecorates it. + const boost::core::scoped_demangled_name demangled_name(data_->name()); + + const char* begin = demangled_name.get(); + if (!begin) { + boost::throw_exception(std::runtime_error("Type name demangling failed")); + } + + const std::string::size_type len = std::strlen(begin); + const char* end = begin + len; + + if (len > cvr_saver_name_len) { + const char* b = std::strstr(begin, cvr_saver_name); + if (b) { + b += cvr_saver_name_len; + + // Trim leading spaces + while (*b == ' ') { // the string is zero terminated, we won't exceed the buffer size + ++ b; + } + + // Skip the closing angle bracket + const char* e = end - 1; + while (e > b && *e != '>') { + -- e; + } + + // Trim trailing spaces + while (e > b && *(e - 1) == ' ') { + -- e; + } + + if (b < e) { + // Parsing seems to have succeeded, the type name is not empty + begin = b; + end = e; + } + } + } + + return std::string(begin, end); +} + + +inline std::size_t stl_type_index::hash_code() const BOOST_NOEXCEPT { +#ifdef BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE + return data_->hash_code(); +#else + return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name())); +#endif +} + + +/// @cond + +// for this compiler at least, cross-shared-library type_info +// comparisons don't work, so we are using typeid(x).name() instead. +# if (defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5))) \ + || defined(_AIX) \ + || (defined(__sgi) && defined(__host_mips)) \ + || (defined(__hpux) && defined(__HP_aCC)) \ + || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC)) +# define BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES +# endif + +/// @endcond + +inline bool stl_type_index::equal(const stl_type_index& rhs) const BOOST_NOEXCEPT { +#ifdef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES + return raw_name() == rhs.raw_name() || !std::strcmp(raw_name(), rhs.raw_name()); +#else + return !!(*data_ == *rhs.data_); +#endif +} + +inline bool stl_type_index::before(const stl_type_index& rhs) const BOOST_NOEXCEPT { +#ifdef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES + return raw_name() != rhs.raw_name() && std::strcmp(raw_name(), rhs.raw_name()) < 0; +#else + return !!data_->before(*rhs.data_); +#endif +} + +#undef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES + + +template +inline stl_type_index stl_type_index::type_id() BOOST_NOEXCEPT { + typedef BOOST_DEDUCED_TYPENAME boost::remove_reference::type no_ref_t; + typedef BOOST_DEDUCED_TYPENAME boost::remove_cv::type no_cvr_prefinal_t; + + # if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \ + || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744) + + // Old EDG-based compilers seem to mistakenly distinguish 'integral' from 'signed integral' + // in typeid() expressions. Full template specialization for 'integral' fixes that issue: + typedef BOOST_DEDUCED_TYPENAME boost::conditional< + boost::is_signed::value, + boost::make_signed, + boost::type_identity + >::type no_cvr_prefinal_lazy_t; + + typedef BOOST_DEDUCED_TYPENAME no_cvr_prefinal_t::type no_cvr_t; + #else + typedef no_cvr_prefinal_t no_cvr_t; + #endif + + return typeid(no_cvr_t); +} + +namespace detail { + template class cvr_saver{}; +} + +template +inline stl_type_index stl_type_index::type_id_with_cvr() BOOST_NOEXCEPT { + typedef BOOST_DEDUCED_TYPENAME boost::conditional< + boost::is_reference::value || boost::is_const::value || boost::is_volatile::value, + detail::cvr_saver, + T + >::type type; + + return typeid(type); +} + + +template +inline stl_type_index stl_type_index::type_id_runtime(const T& value) BOOST_NOEXCEPT { +#ifdef BOOST_NO_RTTI + return value.boost_type_index_type_id_runtime_(); +#else + return typeid(value); +#endif +} + +}} // namespace boost::typeindex + +#undef BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE + +#endif // BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP diff --git a/boost/type_index/type_index_facade.hpp b/boost/type_index/type_index_facade.hpp new file mode 100644 index 00000000..4145aa4e --- /dev/null +++ b/boost/type_index/type_index_facade.hpp @@ -0,0 +1,297 @@ +// +// Copyright 2013-2023 Antony Polukhin. +// +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP +#define BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP + +#include +#include +#include +#include + +#if !defined(BOOST_NO_IOSTREAM) +#if !defined(BOOST_NO_IOSFWD) +#include // for std::basic_ostream +#else +#include +#endif +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +namespace boost { namespace typeindex { + +/// \class type_index_facade +/// +/// This class takes care about the comparison operators, hash functions and +/// ostream operators. Use this class as a public base class for defining new +/// type_info-conforming classes. +/// +/// \b Example: +/// \code +/// class stl_type_index: public type_index_facade +/// { +/// public: +/// typedef std::type_info type_info_t; +/// private: +/// const type_info_t* data_; +/// +/// public: +/// stl_type_index(const type_info_t& data) noexcept +/// : data_(&data) +/// {} +/// // ... +/// }; +/// \endcode +/// +/// \tparam Derived Class derived from type_index_facade. +/// \tparam TypeInfo Class that will be used as a base type_info class. +/// \note Take a look at the protected methods. They are \b not \b defined in type_index_facade. +/// Protected member functions raw_name() \b must be defined in Derived class. All the other +/// methods are mandatory. +/// \see 'Making a custom type_index' section for more information about +/// creating your own type_index using type_index_facade. +template +class type_index_facade { +private: + /// @cond + BOOST_CXX14_CONSTEXPR const Derived & derived() const BOOST_NOEXCEPT { + return *static_cast(this); + } + /// @endcond +public: + typedef TypeInfo type_info_t; + + /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw. + /// \return Name of a type. By default returns Derived::raw_name(). + inline const char* name() const BOOST_NOEXCEPT { + return derived().raw_name(); + } + + /// \b Override: This function \b may be redefined in Derived class. Overrides may throw. + /// \return Human readable type name. By default returns Derived::name(). + inline std::string pretty_name() const { + return derived().name(); + } + + /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw. + /// \return True if two types are equal. By default compares types by raw_name(). + inline bool equal(const Derived& rhs) const BOOST_NOEXCEPT { + const char* const left = derived().raw_name(); + const char* const right = rhs.raw_name(); + return left == right || !std::strcmp(left, right); + } + + /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw. + /// \return True if rhs is greater than this. By default compares types by raw_name(). + inline bool before(const Derived& rhs) const BOOST_NOEXCEPT { + const char* const left = derived().raw_name(); + const char* const right = rhs.raw_name(); + return left != right && std::strcmp(left, right) < 0; + } + + /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw. + /// \return Hash code of a type. By default hashes types by raw_name(). + /// \note Derived class header \b must include , \b unless this function is redefined in + /// Derived class to not use boost::hash_range(). + inline std::size_t hash_code() const BOOST_NOEXCEPT { + 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) +protected: + /// \b Override: This function \b must be redefined in Derived class. Overrides \b must not throw. + /// \return Pointer to unredable/raw type name. + inline const char* raw_name() const BOOST_NOEXCEPT; + + /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw. + /// \return Const reference to underlying low level type_info_t. + inline const type_info_t& type_info() const BOOST_NOEXCEPT; + + /// This is a factory method that is used to create instances of Derived classes. + /// boost::typeindex::type_id() will call this method, if Derived has same type as boost::typeindex::type_index. + /// + /// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw. + /// Overrides \b must remove const, volatile && and & modifiers from T. + /// \tparam T Type for which type_index must be created. + /// \return type_index for type T. + template + static Derived type_id() BOOST_NOEXCEPT; + + /// This is a factory method that is used to create instances of Derived classes. + /// boost::typeindex::type_id_with_cvr() will call this method, if Derived has same type as boost::typeindex::type_index. + /// + /// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw. + /// Overrides \b must \b not remove const, volatile && and & modifiers from T. + /// \tparam T Type for which type_index must be created. + /// \return type_index for type T. + template + static Derived type_id_with_cvr() BOOST_NOEXCEPT; + + /// This is a factory method that is used to create instances of Derived classes. + /// boost::typeindex::type_id_runtime(const T&) will call this method, if Derived has same type as boost::typeindex::type_index. + /// + /// \b Override: This function \b may be redefined and made public in Derived class. + /// \param variable Variable which runtime type will be stored in type_index. + /// \return type_index with runtime type of variable. + template + static Derived type_id_runtime(const T& variable) BOOST_NOEXCEPT; + +#endif + +}; + +/// @cond +template +BOOST_CXX14_CONSTEXPR inline bool operator == (const type_index_facade& lhs, const type_index_facade& rhs) BOOST_NOEXCEPT { + return static_cast(lhs).equal(static_cast(rhs)); +} + +template +BOOST_CXX14_CONSTEXPR inline bool operator < (const type_index_facade& lhs, const type_index_facade& rhs) BOOST_NOEXCEPT { + return static_cast(lhs).before(static_cast(rhs)); +} + + + +template +BOOST_CXX14_CONSTEXPR inline bool operator > (const type_index_facade& lhs, const type_index_facade& rhs) BOOST_NOEXCEPT { + return rhs < lhs; +} + +template +BOOST_CXX14_CONSTEXPR inline bool operator <= (const type_index_facade& lhs, const type_index_facade& rhs) BOOST_NOEXCEPT { + return !(lhs > rhs); +} + +template +BOOST_CXX14_CONSTEXPR inline bool operator >= (const type_index_facade& lhs, const type_index_facade& rhs) BOOST_NOEXCEPT { + return !(lhs < rhs); +} + +template +BOOST_CXX14_CONSTEXPR inline bool operator != (const type_index_facade& lhs, const type_index_facade& rhs) BOOST_NOEXCEPT { + return !(lhs == rhs); +} + +// ######################### COMPARISONS with Derived ############################ // +template +inline bool operator == (const TypeInfo& lhs, const type_index_facade& rhs) BOOST_NOEXCEPT { + return Derived(lhs) == rhs; +} + +template +inline bool operator < (const TypeInfo& lhs, const type_index_facade& rhs) BOOST_NOEXCEPT { + return Derived(lhs) < rhs; +} + +template +inline bool operator > (const TypeInfo& lhs, const type_index_facade& rhs) BOOST_NOEXCEPT { + return rhs < Derived(lhs); +} + +template +inline bool operator <= (const TypeInfo& lhs, const type_index_facade& rhs) BOOST_NOEXCEPT { + return !(Derived(lhs) > rhs); +} + +template +inline bool operator >= (const TypeInfo& lhs, const type_index_facade& rhs) BOOST_NOEXCEPT { + return !(Derived(lhs) < rhs); +} + +template +inline bool operator != (const TypeInfo& lhs, const type_index_facade& rhs) BOOST_NOEXCEPT { + return !(Derived(lhs) == rhs); +} + + +template +inline bool operator == (const type_index_facade& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT { + return lhs == Derived(rhs); +} + +template +inline bool operator < (const type_index_facade& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT { + return lhs < Derived(rhs); +} + +template +inline bool operator > (const type_index_facade& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT { + return Derived(rhs) < lhs; +} + +template +inline bool operator <= (const type_index_facade& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT { + return !(lhs > Derived(rhs)); +} + +template +inline bool operator >= (const type_index_facade& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT { + return !(lhs < Derived(rhs)); +} + +template +inline bool operator != (const type_index_facade& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT { + return !(lhs == Derived(rhs)); +} + +// ######################### COMPARISONS with Derived END ############################ // + +/// @endcond + +#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED) + +/// noexcept comparison operators for type_index_facade classes. +bool operator ==, !=, <, ... (const type_index_facade& lhs, const type_index_facade& rhs) noexcept; + +/// noexcept comparison operators for type_index_facade and it's TypeInfo classes. +bool operator ==, !=, <, ... (const type_index_facade& lhs, const TypeInfo& rhs) noexcept; + +/// noexcept comparison operators for type_index_facade's TypeInfo and type_index_facade classes. +bool operator ==, !=, <, ... (const TypeInfo& lhs, const type_index_facade& rhs) noexcept; + +#endif + +#ifndef BOOST_NO_IOSTREAM +#ifdef BOOST_NO_TEMPLATED_IOSTREAMS +/// @cond +/// Ostream operator that will output demangled name +template +inline std::ostream& operator<<(std::ostream& ostr, const type_index_facade& ind) { + ostr << static_cast(ind).pretty_name(); + return ostr; +} +/// @endcond +#else +/// Ostream operator that will output demangled name. +template +inline std::basic_ostream& operator<<( + std::basic_ostream& ostr, + const type_index_facade& ind) +{ + ostr << static_cast(ind).pretty_name(); + return ostr; +} +#endif // BOOST_NO_TEMPLATED_IOSTREAMS +#endif // BOOST_NO_IOSTREAM + +/// This free function is used by Boost's unordered containers. +/// \note has to be included if this function is used. +template +inline std::size_t hash_value(const type_index_facade& lhs) BOOST_NOEXCEPT { + return static_cast(lhs).hash_code(); +} + +}} // namespace boost::typeindex + +#endif // BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP + diff --git a/boost/type_traits/same_traits.hpp b/boost/type_traits/same_traits.hpp new file mode 100644 index 00000000..dab7dac7 --- /dev/null +++ b/boost/type_traits/same_traits.hpp @@ -0,0 +1,15 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. +// +// defines is_same: + +#ifndef BOOST_TT_SAME_TRAITS_HPP_INCLUDED +#define BOOST_TT_SAME_TRAITS_HPP_INCLUDED + +#include + +#endif // BOOST_TT_SAME_TRAITS_HPP_INCLUDED diff --git a/boost/url.hpp b/boost/url.hpp new file mode 100644 index 00000000..82ccb329 --- /dev/null +++ b/boost/url.hpp @@ -0,0 +1,70 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/url +// + +#ifndef BOOST_URL_HPP +#define BOOST_URL_HPP + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/boost/url/src.hpp b/boost/url/src.hpp deleted file mode 100644 index 22dd88e0..00000000 --- a/boost/url/src.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// -// Copyright (c) 2023 alandefreitas (alandefreitas@gmail.com) -// -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt -// - -#ifndef BOOST_URL_SRC_HPP -#define BOOST_URL_SRC_HPP - -/* - -This file used to be used as a form of library integration -to allow the library to be compiled as a single target. - -This form of integration is discontinued. - -Please refer to the following link for instructions: -https://www.boost.org/doc/libs/master/libs/url/doc/html/url/overview.html - -*/ -#error "src.hpp is discontinued and should not be used. Please use the compiled library instead." - -#endif \ No newline at end of file diff --git a/boost/url/string_view.hpp b/boost/url/string_view.hpp deleted file mode 100644 index 1a7ff0fb..00000000 --- a/boost/url/string_view.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/boostorg/url -// - -#ifndef BOOST_URL_STRING_VIEW_HPP -#define BOOST_URL_STRING_VIEW_HPP - -#include -#include - -namespace boost { -namespace urls { - -/** The type of string_view used by the library - - String views are used to pass character - buffers into or out of functions. Ownership - of the underlying character buffer is not - transferred; the caller is responsible for - ensuring that the lifetime of character - buffer extends until it is no longer - referenced. - - @note This alias is no longer supported and - should not be used in new code. Please use - `core::string_view` instead. - - This alias is included for backwards - compatibility with earlier versions of the - library. - - However, it will be removed in future releases, - and using it in new code is not recommended. - - Please use the updated version instead to - ensure compatibility with future versions of - the library. - -*/ -using string_view - BOOST_URL_DEPRECATED("Use core::string_view instead") = - boost::core::string_view; - -} // urls -} // boost - -#endif diff --git a/boost/url/url.natvis b/boost/url/url.natvis deleted file mode 100644 index c515ccfd..00000000 --- a/boost/url/url.natvis +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - { u_ } - - u_ - - - - - {(addr_>>24)}.{(addr_>>16)%256}.{(addr_>>8)%256}.{addr_%256} - - - - {p_,[n_]s} - {p_,[n_]s} ({dn_}) - - - - {key} - {key}={value} - - - - {key} - {key}={value} - - - - {key} - {key}={value} - - - - {s_} ({dn_}) - {s_} - - - - {cs_,[offset_[id_end]]s} - - - {cs_,[offset_[id_user]-1]s} {scheme_} - - - {cs_+offset_[id_user]+2,[offset_[id_pass]-offset_[id_user]-2]s} ({decoded_[id_user]}) - - - {cs_+offset_[id_user],[offset_[id_pass]-offset_[id_user]]s} ({decoded_[id_user]}) - - - {cs_+offset_[id_pass]+1,[offset_[id_host]-offset_[id_pass]-2]s} ({decoded_[id_pass]}) - - - {host_type_} - {cs_+offset_[id_host],[offset_[id_port]-offset_[id_host]]s} - - - {cs_+offset_[id_port]+1,[offset_[id_path]-offset_[id_port]-1]s} = {port_number_} - - - {cs_+offset_[id_path],[offset_[id_query]-offset_[id_path]]s} - - - {cs_+offset_[id_query]+1,[offset_[id_frag]-offset_[id_query]-1]s} - - - {cs_+offset_[id_frag]+1,[offset_[id_end]-offset_[id_frag]-1]s}) - - - - - - {*pi_} - - *pi_ - - - - - {s_} [{n_}] - - - - nullptr - {p_->t} - - - {p_->refs} - - - - - diff --git a/boost/variant.hpp b/boost/variant.hpp new file mode 100644 index 00000000..f179ccfe --- /dev/null +++ b/boost/variant.hpp @@ -0,0 +1,27 @@ +//----------------------------------------------------------------------------- +// boost variant.hpp header file +// See http://www.boost.org/libs/variant for documentation. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman, Itay Maman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_HPP +#define BOOST_VARIANT_HPP + +// variant "main" +#include +#include +#include + +// common applications +#include +#include +#include +#include + +#endif // BOOST_VARIANT_HPP diff --git a/boost/variant/apply_visitor.hpp b/boost/variant/apply_visitor.hpp new file mode 100644 index 00000000..6ad54fb7 --- /dev/null +++ b/boost/variant/apply_visitor.hpp @@ -0,0 +1,20 @@ +//----------------------------------------------------------------------------- +// boost variant/apply_visitor.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_APPLY_VISITOR_HPP +#define BOOST_VARIANT_APPLY_VISITOR_HPP + +#include +#include +#include + +#endif // BOOST_VARIANT_APPLY_VISITOR_HPP diff --git a/boost/variant/bad_visit.hpp b/boost/variant/bad_visit.hpp new file mode 100644 index 00000000..9396d086 --- /dev/null +++ b/boost/variant/bad_visit.hpp @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// boost variant/bad_visit.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002-2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_BAD_VISIT_HPP +#define BOOST_VARIANT_BAD_VISIT_HPP + +#include + +#include + +namespace boost { + +////////////////////////////////////////////////////////////////////////// +// class bad_visit +// +// Exception thrown when a visitation attempt via apply_visitor fails due +// to invalid visited subtype or contents. +// +struct BOOST_SYMBOL_VISIBLE bad_visit + : std::exception +{ +public: // std::exception interface + + const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE + { + return "boost::bad_visit: " + "failed visitation using boost::apply_visitor"; + } + +}; + +} // namespace boost + +#endif // BOOST_VARIANT_BAD_VISIT_HPP diff --git a/boost/variant/detail/apply_visitor_binary.hpp b/boost/variant/detail/apply_visitor_binary.hpp new file mode 100644 index 00000000..10c2403d --- /dev/null +++ b/boost/variant/detail/apply_visitor_binary.hpp @@ -0,0 +1,358 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/apply_visitor_binary.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002-2003 Eric Friedman +// Copyright (c) 2014-2023 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP +#define BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP + +#include + +#include + +#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) +# include +#endif + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +# include +# include +# include +# include // for boost::move, boost::forward +#endif + +namespace boost { + +////////////////////////////////////////////////////////////////////////// +// function template apply_visitor(visitor, visitable1, visitable2) +// +// Visits visitable1 and visitable2 such that their values (which we +// shall call x and y, respectively) are used as arguments in the +// expression visitor(x, y). +// + +namespace detail { namespace variant { + +template +class apply_visitor_binary_invoke +{ +public: // visitor typedefs + + typedef typename Visitor::result_type + result_type; + +private: // representation + + Visitor& visitor_; + Value1& value1_; + +public: // structors + + apply_visitor_binary_invoke(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT + : visitor_(visitor) + , value1_(value1) + { + } + +public: // visitor interfaces + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + + template + typename enable_if_c::value, result_type>::type + operator()(Value2&& value2) + { + return visitor_(::boost::move(value1_), ::boost::forward(value2)); + } + + template + typename disable_if_c::value, result_type>::type + operator()(Value2&& value2) + { + return visitor_(value1_, ::boost::forward(value2)); + } + +#else + + template + result_type + operator()(Value2& value2) + { + return visitor_(value1_, value2); + } + +#endif + +private: + apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&); +}; + +template +class apply_visitor_binary_unwrap +{ +public: // visitor typedefs + + typedef typename Visitor::result_type + result_type; + +private: // representation + + Visitor& visitor_; + Visitable2& visitable2_; + +public: // structors + + apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT + : visitor_(visitor) + , visitable2_(visitable2) + { + } + +public: // visitor interfaces + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + + template + typename enable_if_c::value, result_type>::type + operator()(Value1&& value1) + { + apply_visitor_binary_invoke< + Visitor + , Value1 + , ! ::boost::is_lvalue_reference::value + > invoker(visitor_, value1); + + return boost::apply_visitor(invoker, ::boost::move(visitable2_)); + } + + template + typename disable_if_c::value, result_type>::type + operator()(Value1&& value1) + { + apply_visitor_binary_invoke< + Visitor + , Value1 + , ! ::boost::is_lvalue_reference::value + > invoker(visitor_, value1); + + return boost::apply_visitor(invoker, visitable2_); + } + +#else + + template + result_type + operator()(Value1& value1) + { + apply_visitor_binary_invoke< + Visitor + , Value1 + , false + > invoker(visitor_, value1); + + return boost::apply_visitor(invoker, visitable2_); + } + +#endif + +private: + apply_visitor_binary_unwrap& operator=(const apply_visitor_binary_unwrap&); + +}; + +}} // namespace detail::variant + +// +// nonconst-visitor version: +// + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template +inline typename Visitor::result_type +apply_visitor( Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2) +{ + ::boost::detail::variant::apply_visitor_binary_unwrap< + Visitor, Visitable2, ! ::boost::is_lvalue_reference::value + > unwrapper(visitor, visitable2); + + return boost::apply_visitor(unwrapper, ::boost::forward(visitable1)); +} + +#else + +template +inline typename Visitor::result_type +apply_visitor( Visitor& visitor, Visitable1& visitable1, Visitable2& visitable2) +{ + ::boost::detail::variant::apply_visitor_binary_unwrap< + Visitor, Visitable2, false + > unwrapper(visitor, visitable2); + + return boost::apply_visitor(unwrapper, visitable1); +} + +#endif + +// +// const-visitor version: +// + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template +inline typename Visitor::result_type +apply_visitor( const Visitor& visitor , Visitable1&& visitable1 , Visitable2&& visitable2) +{ + ::boost::detail::variant::apply_visitor_binary_unwrap< + const Visitor, Visitable2, ! ::boost::is_lvalue_reference::value + > unwrapper(visitor, visitable2); + + return boost::apply_visitor(unwrapper, ::boost::forward(visitable1)); +} + +#else + +template +inline typename Visitor::result_type +apply_visitor( const Visitor& visitor , Visitable1& visitable1 , Visitable2& visitable2) +{ + ::boost::detail::variant::apply_visitor_binary_unwrap< + const Visitor, Visitable2, false + > unwrapper(visitor, visitable2); + + return boost::apply_visitor(unwrapper, visitable1); +} + +#endif + + +#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) + +////////////////////////////////////////////////////////////////////////// +// function template apply_visitor(visitor, visitable1, visitable2) +// +// C++14 part. +// + +namespace detail { namespace variant { + +template +class apply_visitor_binary_invoke_cpp14 +{ + Visitor& visitor_; + Value1& value1_; + +public: // structors + + apply_visitor_binary_invoke_cpp14(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT + : visitor_(visitor) + , value1_(value1) + { + } + +public: // visitor interfaces + + template + decltype(auto) operator()(Value2&& value2, typename enable_if_c::value, bool>::type = true) + { + return visitor_(::boost::move(value1_), ::boost::forward(value2)); + } + + template + decltype(auto) operator()(Value2&& value2, typename disable_if_c::value, bool>::type = true) + { + return visitor_(value1_, ::boost::forward(value2)); + } + +private: + apply_visitor_binary_invoke_cpp14& operator=(const apply_visitor_binary_invoke_cpp14&); +}; + +template +class apply_visitor_binary_unwrap_cpp14 +{ + Visitor& visitor_; + Visitable2& visitable2_; + +public: // structors + + apply_visitor_binary_unwrap_cpp14(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT + : visitor_(visitor) + , visitable2_(visitable2) + { + } + +public: // visitor interfaces + + template + decltype(auto) operator()(Value1&& value1, typename enable_if_c::value, bool>::type = true) + { + apply_visitor_binary_invoke_cpp14< + Visitor + , Value1 + , ! ::boost::is_lvalue_reference::value + > invoker(visitor_, value1); + + return boost::apply_visitor(invoker, ::boost::move(visitable2_)); + } + + template + decltype(auto) operator()(Value1&& value1, typename disable_if_c::value, bool>::type = true) + { + apply_visitor_binary_invoke_cpp14< + Visitor + , Value1 + , ! ::boost::is_lvalue_reference::value + > invoker(visitor_, value1); + + return boost::apply_visitor(invoker, visitable2_); + } + +private: + apply_visitor_binary_unwrap_cpp14& operator=(const apply_visitor_binary_unwrap_cpp14&); +}; + +}} // namespace detail::variant + +template +inline decltype(auto) apply_visitor(Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2, + typename boost::disable_if< + boost::detail::variant::has_result_type, + bool + >::type = true) +{ + ::boost::detail::variant::apply_visitor_binary_unwrap_cpp14< + Visitor, Visitable2, ! ::boost::is_lvalue_reference::value + > unwrapper(visitor, visitable2); + + return boost::apply_visitor(unwrapper, ::boost::forward(visitable1)); +} + +template +inline decltype(auto) apply_visitor(const Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2, + typename boost::disable_if< + boost::detail::variant::has_result_type, + bool + >::type = true) +{ + ::boost::detail::variant::apply_visitor_binary_unwrap_cpp14< + const Visitor, Visitable2, ! ::boost::is_lvalue_reference::value + > unwrapper(visitor, visitable2); + + return boost::apply_visitor(unwrapper, ::boost::forward(visitable1)); +} + + +#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) + +} // namespace boost + +#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP diff --git a/boost/variant/detail/apply_visitor_delayed.hpp b/boost/variant/detail/apply_visitor_delayed.hpp new file mode 100644 index 00000000..0a900629 --- /dev/null +++ b/boost/variant/detail/apply_visitor_delayed.hpp @@ -0,0 +1,146 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/apply_visitor_delayed.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002-2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_DELAYED_HPP +#define BOOST_VARIANT_DETAIL_APPLY_VISITOR_DELAYED_HPP + +#include +#include +#include // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES + + +#include +#include + +namespace boost { + +////////////////////////////////////////////////////////////////////////// +// function template apply_visitor(visitor) +// +// Returns a function object, overloaded for unary and binary usage, that +// visits its arguments using visitor (or a copy of visitor) via +// * apply_visitor( visitor, [argument] ) +// under unary invocation, or +// * apply_visitor( visitor, [argument1], [argument2] ) +// under binary invocation. +// +// NOTE: Unlike other apply_visitor forms, the visitor object must be +// non-const; this prevents user from giving temporary, to disastrous +// effect (i.e., returned function object would have dead reference). +// + +template +class apply_visitor_delayed_t +{ +public: // visitor typedefs + + typedef typename Visitor::result_type + result_type; + +private: // representation + + Visitor& visitor_; + +public: // structors + + explicit apply_visitor_delayed_t(Visitor& visitor) BOOST_NOEXCEPT + : visitor_(visitor) + { + } + +#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) + +public: // N-ary visitor interface + template + result_type operator()(Visitables&... visitables) const + { + return apply_visitor(visitor_, visitables...); + } + +#else // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) + +public: // unary visitor interface + + template + result_type operator()(Visitable& visitable) const + { + return apply_visitor(visitor_, visitable); + } + +public: // binary visitor interface + + template + result_type operator()(Visitable1& visitable1, Visitable2& visitable2) const + { + return apply_visitor(visitor_, visitable1, visitable2); + } + +#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) + +private: + apply_visitor_delayed_t& operator=(const apply_visitor_delayed_t&); + +}; + +template +inline typename boost::enable_if< + boost::detail::variant::has_result_type, + apply_visitor_delayed_t + >::type apply_visitor(Visitor& visitor) +{ + return apply_visitor_delayed_t(visitor); +} + +#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) \ + && !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) + +template +class apply_visitor_delayed_cpp14_t +{ +private: // representation + Visitor& visitor_; + +public: // structors + + explicit apply_visitor_delayed_cpp14_t(Visitor& visitor) BOOST_NOEXCEPT + : visitor_(visitor) + { + } + +public: // N-ary visitor interface + template + decltype(auto) operator()(Visitables&... visitables) const + { + return apply_visitor(visitor_, visitables...); + } + +private: + apply_visitor_delayed_cpp14_t& operator=(const apply_visitor_delayed_cpp14_t&); + +}; + +template +inline typename boost::disable_if< + boost::detail::variant::has_result_type, + apply_visitor_delayed_cpp14_t + >::type apply_visitor(Visitor& visitor) +{ + return apply_visitor_delayed_cpp14_t(visitor); +} + +#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) + // && !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) + + +} // namespace boost + +#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_DELAYED_HPP diff --git a/boost/variant/detail/apply_visitor_unary.hpp b/boost/variant/detail/apply_visitor_unary.hpp new file mode 100644 index 00000000..7574b44e --- /dev/null +++ b/boost/variant/detail/apply_visitor_unary.hpp @@ -0,0 +1,145 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/apply_visitor_unary.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002-2003 Eric Friedman +// Copyright (c) 2014-2023 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP +#define BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP + +#include +#include + +#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +namespace boost { + +////////////////////////////////////////////////////////////////////////// +// function template apply_visitor(visitor, visitable) +// +// Visits visitable with visitor. +// + +// +// nonconst-visitor version: +// + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +template +inline typename Visitor::result_type +apply_visitor(Visitor& visitor, Visitable&& visitable) +{ + return ::boost::forward(visitable).apply_visitor(visitor); +} +#else +template +inline typename Visitor::result_type +apply_visitor(Visitor& visitor, Visitable& visitable) +{ + return visitable.apply_visitor(visitor); +} +#endif + +// +// const-visitor version: +// + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +template +inline typename Visitor::result_type +apply_visitor(const Visitor& visitor, Visitable&& visitable) +{ + return ::boost::forward(visitable).apply_visitor(visitor); +} +#else +template +inline typename Visitor::result_type +apply_visitor(const Visitor& visitor, Visitable& visitable) +{ + return visitable.apply_visitor(visitor); +} +#endif + + +#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) +#define BOOST_VARIANT_HAS_DECLTYPE_APPLY_VISITOR_RETURN_TYPE + +// C++14 +namespace detail { namespace variant { + +// This class serves only metaprogramming purposes. none of its methods must be called at runtime! +template +struct result_multideduce1 { + typedef typename remove_reference::type::types types; + typedef typename boost::mpl::begin::type begin_it; + typedef typename boost::mpl::advance< + begin_it, boost::mpl::int_::type::value - 1> + >::type last_it; + + template // avoid explicit specialization in class scope + struct deduce_impl { + typedef typename boost::mpl::next::type next_t; + typedef typename boost::mpl::deref::type value_t; + typedef decltype(true ? boost::declval< Visitor& >()( boost::declval< copy_cv_ref_t< value_t, Variant > >() ) + : boost::declval< typename deduce_impl::type >()) type; + }; + + template + struct deduce_impl { + typedef typename boost::mpl::deref::type value_t; + typedef decltype(boost::declval< Visitor& >()( boost::declval< copy_cv_ref_t< value_t, Variant > >() )) type; + }; + + typedef typename deduce_impl::type type; +}; + +template +struct result_wrapper1 +{ + typedef typename result_multideduce1::type result_type; + + Visitor&& visitor_; + explicit result_wrapper1(Visitor&& visitor) BOOST_NOEXCEPT + : visitor_(::boost::forward(visitor)) + {} + + template + result_type operator()(T&& val) const { + return visitor_(::boost::forward(val)); + } +}; + +}} // namespace detail::variant + +template +inline decltype(auto) apply_visitor(Visitor&& visitor, Visitable&& visitable, + typename boost::disable_if< + boost::detail::variant::has_result_type, + bool + >::type = true) +{ + boost::detail::variant::result_wrapper1 cpp14_vis(::boost::forward(visitor)); + return ::boost::forward(visitable).apply_visitor(cpp14_vis); +} + +#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) + +} // namespace boost + +#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP diff --git a/boost/variant/detail/backup_holder.hpp b/boost/variant/detail/backup_holder.hpp new file mode 100644 index 00000000..c11f12cf --- /dev/null +++ b/boost/variant/detail/backup_holder.hpp @@ -0,0 +1,95 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/backup_holder.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP +#define BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP + +#include +#include + +namespace boost { +namespace detail { namespace variant { + +template +class backup_holder +{ +private: // representation + + T* backup_; + +public: // structors + + ~backup_holder() BOOST_NOEXCEPT + { + delete backup_; + } + + explicit backup_holder(T* backup) BOOST_NOEXCEPT + : backup_(backup) + { + } + + backup_holder(const backup_holder&); + +public: // modifiers + + backup_holder& operator=(const backup_holder& rhs) + { + *backup_ = rhs.get(); + return *this; + } + + backup_holder& operator=(const T& rhs) + { + *backup_ = rhs; + return *this; + } + + void swap(backup_holder& rhs) BOOST_NOEXCEPT + { + T* tmp = rhs.backup_; + rhs.backup_ = this->backup_; + this->backup_ = tmp; + } + +public: // queries + + T& get() BOOST_NOEXCEPT + { + return *backup_; + } + + const T& get() const BOOST_NOEXCEPT + { + return *backup_; + } + +}; + +template +backup_holder::backup_holder(const backup_holder&) + : backup_(0) +{ + // not intended for copy, but do not want to prohibit syntactically + BOOST_ASSERT(false); +} + +template +void swap(backup_holder& lhs, backup_holder& rhs) BOOST_NOEXCEPT +{ + lhs.swap(rhs); +} + +}} // namespace detail::variant +} // namespace boost + +#endif // BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP diff --git a/boost/variant/detail/cast_storage.hpp b/boost/variant/detail/cast_storage.hpp new file mode 100644 index 00000000..0320278c --- /dev/null +++ b/boost/variant/detail/cast_storage.hpp @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/cast_storage.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_CAST_STORAGE_HPP +#define BOOST_VARIANT_DETAIL_CAST_STORAGE_HPP + +#include + +namespace boost { +namespace detail { namespace variant { + +/////////////////////////////////////////////////////////////////////////////// +// (detail) function template cast_storage +// +// Casts the given storage to the specified type, but with qualification. +// + +template +inline T& cast_storage(void* storage) +{ + return *static_cast(storage); +} + +template +inline const T& cast_storage(const void* storage) +{ + return *static_cast(storage); +} + +}} // namespace detail::variant +} // namespace boost + +#endif // BOOST_VARIANT_DETAIL_CAST_STORAGE_HPP diff --git a/boost/variant/detail/config.hpp b/boost/variant/detail/config.hpp new file mode 100644 index 00000000..efc48a5c --- /dev/null +++ b/boost/variant/detail/config.hpp @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/config.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 Eric Friedman +// Copyright (c) 2016-2023 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_CONFIG_HPP +#define BOOST_VARIANT_DETAIL_CONFIG_HPP + +#include +#include + +#include +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \ + defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) || \ + defined(BOOST_NO_CXX11_CONSTEXPR) || \ + defined(BOOST_NO_CXX11_NULLPTR) || \ + defined(BOOST_NO_CXX11_NOEXCEPT) || \ + defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || \ + defined(BOOST_NO_CXX11_FINAL) || \ + defined(BOOST_NO_CXX11_ALIGNOF) || \ + defined(BOOST_NO_CXX11_STATIC_ASSERT) || \ + defined(BOOST_NO_CXX11_SMART_PTR) || \ + defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) || \ + defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + +BOOST_PRAGMA_MESSAGE("C++03 support is deprecated in Boost.Variant 1.82 and will be removed in Boost.Variant 1.84.") + +#endif + +#endif // BOOST_VARIANT_DETAIL_CONFIG_HPP diff --git a/boost/variant/detail/element_index.hpp b/boost/variant/detail/element_index.hpp new file mode 100644 index 00000000..06cf06d7 --- /dev/null +++ b/boost/variant/detail/element_index.hpp @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/element_index.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2014-2023 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_ELEMENT_INDEX_HPP +#define BOOST_VARIANT_DETAIL_ELEMENT_INDEX_HPP + +#include +#include +#include + +#include +#include +#include + +namespace boost { namespace detail { namespace variant { + +template +struct variant_element_functor : + boost::mpl::or_< + boost::is_same, + boost::is_same >, + boost::is_same + > +{}; + +template +struct element_iterator_impl : + boost::mpl::find_if< + Types, + boost::mpl::or_< + variant_element_functor, + variant_element_functor::type > + > + > +{}; + +template +struct element_iterator : + element_iterator_impl< typename Variant::types, typename boost::remove_reference::type > +{}; + +template +struct holds_element : + boost::mpl::not_< + boost::is_same< + typename boost::mpl::end::type, + typename element_iterator::type + > + > +{}; + + +}}} // namespace boost::detail::variant + +#endif // BOOST_VARIANT_DETAIL_ELEMENT_INDEX_HPP diff --git a/boost/variant/detail/enable_recursive.hpp b/boost/variant/detail/enable_recursive.hpp new file mode 100644 index 00000000..757e0df5 --- /dev/null +++ b/boost/variant/detail/enable_recursive.hpp @@ -0,0 +1,133 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/enable_recursive.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_HPP +#define BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_HPP + +#include +#include + +#if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT) +# include +# include +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace detail { namespace variant { + +#if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) + +# define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL(T,Dest,Source) \ + substitute< T , Dest , Source > \ + /**/ + +#else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class template rebind1 +// +// Limited workaround in case 'substitute' metafunction unavailable. +// + +template +struct rebind1 +{ +private: + typedef typename mpl::lambda< + mpl::identity + >::type le_; + +public: + typedef typename mpl::eval_if< + is_same< le_, mpl::identity > + , le_ // identity + , mpl::apply1 + >::type type; +}; + +# define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL(T,Dest,Source) \ + rebind1< T , Dest > \ + /**/ + +#endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction enable_recursive +// +// See boost/variant/detail/enable_recursive_fwd.hpp for more information. +// + + +template +struct enable_recursive + : BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL( + T, RecursiveVariant, ::boost::recursive_variant_ + ) +{ +}; + +template +struct enable_recursive< T,RecursiveVariant,mpl::false_ > +{ +private: // helpers, for metafunction result (below) + + typedef typename BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL( + T, RecursiveVariant, ::boost::recursive_variant_ + )::type t_; + +public: // metafunction result + + // [Wrap with recursive_wrapper only if rebind really changed something:] + typedef typename mpl::if_< + mpl::or_< + is_same< t_,T > + , is_reference + , is_pointer + > + , t_ + , boost::recursive_wrapper + >::type type; + +}; + + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction class quoted_enable_recursive +// +// Same behavior as enable_recursive metafunction (see above). +// +template +struct quoted_enable_recursive +{ + template + struct apply + : enable_recursive + { + }; +}; + +}} // namespace detail::variant +} // namespace boost + +#endif // BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_HPP diff --git a/boost/variant/detail/enable_recursive_fwd.hpp b/boost/variant/detail/enable_recursive_fwd.hpp new file mode 100644 index 00000000..cac156b1 --- /dev/null +++ b/boost/variant/detail/enable_recursive_fwd.hpp @@ -0,0 +1,87 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/enable_recursive_fwd.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_FWD_HPP +#define BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_FWD_HPP + +#include + +#include + +# include + +namespace boost { +namespace detail { namespace variant { + +/////////////////////////////////////////////////////////////////////////////// +// (detail) tag recursive_flag +// +// Signifies that the variant should perform recursive substituion. +// + + +template +struct recursive_flag +{ + typedef T type; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction is_recursive_flag +// +// Signifies that the variant should perform recursive substituion. +// + + +template +struct is_recursive_flag + : mpl::false_ +{ +}; + +template +struct is_recursive_flag< recursive_flag > + : mpl::true_ +{ +}; + + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction enable_recursive +// +// Attempts recursive_variant_ tag substitution, wrapping with +// boost::recursive_wrapper if substituion occurs w/ non-indirect result +// (i.e., not a reference or pointer) *and* NoWrapper is false_. +// +template < + typename T + , typename RecursiveVariant + , typename NoWrapper = mpl::false_ + > +struct enable_recursive; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction class quoted_enable_recursive +// +// Same behavior as enable_recursive metafunction (see above). +// +template < + typename RecursiveVariant + , typename NoWrapper = mpl::false_ + > +struct quoted_enable_recursive; + +}} // namespace detail::variant +} // namespace boost + +#endif // BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_FWD_HPP diff --git a/boost/variant/detail/forced_return.hpp b/boost/variant/detail/forced_return.hpp new file mode 100644 index 00000000..6d8911b1 --- /dev/null +++ b/boost/variant/detail/forced_return.hpp @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/forced_return.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 Eric Friedman +// Copyright (c) 2015-2023 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_FORCED_RETURN_HPP +#define BOOST_VARIANT_DETAIL_FORCED_RETURN_HPP + +#include +#include + + +#ifdef BOOST_MSVC +# pragma warning( push ) +# pragma warning( disable : 4702 ) // unreachable code +#endif + +namespace boost { namespace detail { namespace variant { + +/////////////////////////////////////////////////////////////////////////////// +// (detail) function template forced_return +// +// Logical error to permit invocation at runtime, but (artificially) satisfies +// compile-time requirement of returning a result value. +// +template +BOOST_NORETURN inline T +forced_return() +{ + // logical error: should never be here! (see above) + BOOST_ASSERT(false); + + T (*dummy)() = 0; + (void)dummy; + BOOST_UNREACHABLE_RETURN(dummy()); +} + +}}} // namespace boost::detail::variant + + +#ifdef BOOST_MSVC +# pragma warning( pop ) +#endif + +#endif // BOOST_VARIANT_DETAIL_FORCED_RETURN_HPP diff --git a/boost/variant/detail/has_result_type.hpp b/boost/variant/detail/has_result_type.hpp new file mode 100644 index 00000000..e1ca5b40 --- /dev/null +++ b/boost/variant/detail/has_result_type.hpp @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/has_result_type.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2014-2023 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_HAS_RESULT_TYPE_HPP +#define BOOST_VARIANT_DETAIL_HAS_RESULT_TYPE_HPP + +#include +#include + + +namespace boost { namespace detail { namespace variant { + +template +struct has_result_type { +private: + typedef char yes; + typedef struct { char array[2]; } no; + + template static yes test(typename boost::remove_reference::type*); + template static no test(...); + +public: + BOOST_STATIC_CONSTANT(bool, value = sizeof(test(0)) == sizeof(yes)); +}; + +}}} // namespace boost::detail::variant + +#endif // BOOST_VARIANT_DETAIL_HAS_RESULT_TYPE_HPP + diff --git a/boost/variant/detail/hash_variant.hpp b/boost/variant/detail/hash_variant.hpp new file mode 100644 index 00000000..4eb83772 --- /dev/null +++ b/boost/variant/detail/hash_variant.hpp @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/hash_variant.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2011-2023 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef BOOST_HASH_VARIANT_FUNCTION_HPP +#define BOOST_HASH_VARIANT_FUNCTION_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include + +namespace boost { + + namespace detail { namespace variant { + struct variant_hasher: public boost::static_visitor { + template + std::size_t operator()(T const& val) const { + boost::hash hasher; + return hasher(val); + } + }; + }} + + template < BOOST_VARIANT_ENUM_PARAMS(typename T) > + std::size_t hash_value(variant< BOOST_VARIANT_ENUM_PARAMS(T) > const& val) { + std::size_t seed = boost::apply_visitor(detail::variant::variant_hasher(), val); + hash_combine(seed, val.which()); + return seed; + } +} + +#endif + diff --git a/boost/variant/detail/initializer.hpp b/boost/variant/detail/initializer.hpp new file mode 100644 index 00000000..4a54c273 --- /dev/null +++ b/boost/variant/detail/initializer.hpp @@ -0,0 +1,249 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/initializer.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002-2003 +// Eric Friedman, Itay Maman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_INITIALIZER_HPP +#define BOOST_VARIANT_DETAIL_INITIALIZER_HPP + +#include // for placement new + +#include + +#include +#include +#include +#include + +#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) +# include +# include +# include +# include +# include +# include +# include +#else +# include +# include +# include +# include +#endif + +namespace boost { +namespace detail { namespace variant { + +/////////////////////////////////////////////////////////////////////////////// +// (detail) support to simulate standard overload resolution rules +// +// The below initializers allows variant to follow standard overload +// resolution rules over the specified set of bounded types. +// +// On compilers where using declarations in class templates can correctly +// avoid name hiding, use an optimal solution based on the variant's typelist. +// +// Otherwise, use a preprocessor workaround based on knowledge of the fixed +// size of the variant's psuedo-variadic template parameter list. +// + +#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) + +// (detail) quoted metafunction make_initializer_node +// +// Exposes a pair whose first type is a node in the initializer hierarchy. +// +struct make_initializer_node +{ + template + struct apply + { + private: // helpers, for metafunction result (below) + + typedef typename BaseIndexPair::first + base; + typedef typename BaseIndexPair::second + index; + + class initializer_node + : public base + { + private: // helpers, for static functions (below) + + typedef typename mpl::deref::type + recursive_enabled_T; + typedef typename unwrap_recursive::type + public_T; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + typedef boost::is_reference + is_reference_content_t; + + typedef typename boost::mpl::if_::type + param_T; + + template struct disable_overload{}; + + typedef typename boost::mpl::if_, public_T&& >::type + param2_T; +#else + typedef typename call_traits::param_type + param_T; +#endif + + public: // static functions + + using base::initialize; + + static int initialize(void* dest, param_T operand) + { + typedef typename boost::detail::make_reference_content< + recursive_enabled_T + >::type internal_T; + + new(dest) internal_T(operand); + return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + static int initialize(void* dest, param2_T operand) + { + // This assert must newer trigger, because all the reference contents are + // handled by the initilize(void* dest, param_T operand) function above + BOOST_ASSERT(!is_reference_content_t::value); + + typedef typename boost::mpl::if_::type value_T; + new(dest) value_T( boost::detail::variant::move(operand) ); + return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which + } +#endif + }; + + friend class initializer_node; + + public: // metafunction result + + typedef mpl::pair< + initializer_node + , typename mpl::next< index >::type + > type; + + }; +}; + +// (detail) class initializer_root +// +// Every level of the initializer hierarchy must expose the name +// "initialize," so initializer_root provides a dummy function: +// +class initializer_root +{ +public: // static functions + + static void initialize(); + +}; + +#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) + + // Obsolete. Remove. + #define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_PARAMS \ + BOOST_VARIANT_ENUM_PARAMS(typename recursive_enabled_T) \ + /**/ + + // Obsolete. Remove. + #define BOOST_VARIANT_AUX_PP_INITIALIZER_DEFINE_PARAM_T(N) \ + typedef typename unwrap_recursive< \ + BOOST_PP_CAT(recursive_enabled_T,N) \ + >::type BOOST_PP_CAT(public_T,N); \ + typedef typename call_traits< \ + BOOST_PP_CAT(public_T,N) \ + >::param_type BOOST_PP_CAT(param_T,N); \ + /**/ + +template < BOOST_VARIANT_ENUM_PARAMS(typename recursive_enabled_T) > +struct preprocessor_list_initializer +{ +public: // static functions + + #define BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION(z,N,_) \ + typedef typename unwrap_recursive< \ + BOOST_PP_CAT(recursive_enabled_T,N) \ + >::type BOOST_PP_CAT(public_T,N); \ + typedef typename call_traits< \ + BOOST_PP_CAT(public_T,N) \ + >::param_type BOOST_PP_CAT(param_T,N); \ + static int initialize( \ + void* dest \ + , BOOST_PP_CAT(param_T,N) operand \ + ) \ + { \ + typedef typename boost::detail::make_reference_content< \ + BOOST_PP_CAT(recursive_enabled_T,N) \ + >::type internal_T; \ + \ + new(dest) internal_T(operand); \ + return (N); /*which*/ \ + } \ + /**/ + + BOOST_PP_REPEAT( + BOOST_VARIANT_LIMIT_TYPES + , BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION + , _ + ) + + #undef BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION + +}; + +#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround + +}} // namespace detail::variant +} // namespace boost + +/////////////////////////////////////////////////////////////////////////////// +// macro BOOST_VARIANT_AUX_INITIALIZER_T +// +// Given both the variant's typelist and a basename for forming the list of +// bounded types (i.e., T becomes T1, T2, etc.), exposes the initializer +// most appropriate to the current compiler. +// + +#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) + +#define BOOST_VARIANT_AUX_INITIALIZER_T( mpl_seq, typename_base ) \ + ::boost::mpl::iter_fold< \ + mpl_seq \ + , ::boost::mpl::pair< \ + ::boost::detail::variant::initializer_root \ + , ::boost::mpl::int_<0> \ + > \ + , ::boost::mpl::protect< \ + ::boost::detail::variant::make_initializer_node \ + > \ + >::type::first \ + /**/ + +#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) + + // Obsolete. Remove. + #define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_ARGS(typename_base) \ + BOOST_VARIANT_ENUM_PARAMS(typename_base) \ + /**/ + +#define BOOST_VARIANT_AUX_INITIALIZER_T( mpl_seq, typename_base ) \ + ::boost::detail::variant::preprocessor_list_initializer< \ + BOOST_VARIANT_ENUM_PARAMS(typename_base) \ + > \ + /**/ + +#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround + +#endif // BOOST_VARIANT_DETAIL_INITIALIZER_HPP diff --git a/boost/variant/detail/make_variant_list.hpp b/boost/variant/detail/make_variant_list.hpp new file mode 100644 index 00000000..bd786158 --- /dev/null +++ b/boost/variant/detail/make_variant_list.hpp @@ -0,0 +1,73 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/make_variant_list.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002-2003 Eric Friedman, Itay Maman +// Copyright (c) 2013-2023 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_MAKE_VARIANT_LIST_HPP +#define BOOST_VARIANT_DETAIL_MAKE_VARIANT_LIST_HPP + +#include + +#include +#include +#include + +namespace boost { +namespace detail { namespace variant { + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction make_variant_list +// +// Provides a MPL-compatible sequence with the specified non-void types +// as arguments. +// +// Rationale: see class template convert_void (variant_fwd.hpp) and using- +// declaration workaround (below). +// + +#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) + +template < typename... T > +struct make_variant_list +{ + typedef typename mpl::list< T... >::type type; +}; + +#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) + +template < BOOST_VARIANT_ENUM_PARAMS(typename T) > +struct make_variant_list +{ +public: // metafunction result + + // [Define a macro to convert any void(NN) tags to mpl::void...] +# define BOOST_VARIANT_AUX_CONVERT_VOID(z, N,_) \ + typename convert_void< BOOST_PP_CAT(T,N) >::type + + // [...so that the specified types can be passed to mpl::list...] + typedef typename mpl::list< + BOOST_PP_ENUM( + BOOST_VARIANT_LIMIT_TYPES + , BOOST_VARIANT_AUX_CONVERT_VOID + , _ + ) + >::type type; + + // [...and, finally, the conversion macro can be undefined:] +# undef BOOST_VARIANT_AUX_CONVERT_VOID + +}; + +#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround + +}} // namespace detail::variant +} // namespace boost + +#endif // BOOST_VARIANT_DETAIL_MAKE_VARIANT_LIST_HPP diff --git a/boost/variant/detail/move.hpp b/boost/variant/detail/move.hpp new file mode 100644 index 00000000..58661383 --- /dev/null +++ b/boost/variant/detail/move.hpp @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/move.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002-2003 Eric Friedman +// Copyright (c) 2002 by Andrei Alexandrescu +// Copyright (c) 2013-2023 Antony Polukhin +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// This file derivative of MoJO. Much thanks to Andrei for his initial work. +// See for information on MOJO. +// Re-issued here under the Boost Software License, with permission of the original +// author (Andrei Alexandrescu). + + +#ifndef BOOST_VARIANT_DETAIL_MOVE_HPP +#define BOOST_VARIANT_DETAIL_MOVE_HPP + +#include +#include +#include // for boost::move +#include + +namespace boost { namespace detail { namespace variant { + +using boost::move; + +////////////////////////////////////////////////////////////////////////// +// function template move_swap +// +// Swaps using Koenig lookup but falls back to move-swap for primitive +// types and on non-conforming compilers. +// + +template +inline void move_swap(T& lhs, T& rhs) +{ + ::boost::adl_move_swap(lhs, rhs); +} + +}}} // namespace boost::detail::variant + +#endif // BOOST_VARIANT_DETAIL_MOVE_HPP + + + diff --git a/boost/variant/detail/over_sequence.hpp b/boost/variant/detail/over_sequence.hpp new file mode 100644 index 00000000..48394f07 --- /dev/null +++ b/boost/variant/detail/over_sequence.hpp @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/over_sequence.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Portions Copyright (C) 2002 David Abrahams +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_OVER_SEQUENCE_HPP +#define BOOST_VARIANT_DETAIL_OVER_SEQUENCE_HPP + +#include + + +namespace boost { +namespace detail { namespace variant { + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class over_sequence +// +// Wrapper used to indicate bounded types for variant are from type sequence. +// +template +struct over_sequence +{ + typedef Types type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction is_over_sequence (modeled on code by David Abrahams) +// +// Indicates whether the specified type is of form over_sequence<...> or not. +// + + +template +struct is_over_sequence + : mpl::false_ +{ +}; + +template +struct is_over_sequence< over_sequence > + : mpl::true_ +{ +}; + + +}} // namespace detail::variant +} // namespace boost + +#endif // BOOST_VARIANT_DETAIL_OVER_SEQUENCE_HPP diff --git a/boost/variant/detail/std_hash.hpp b/boost/variant/detail/std_hash.hpp new file mode 100644 index 00000000..3e05c5c9 --- /dev/null +++ b/boost/variant/detail/std_hash.hpp @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/std_hash.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2018-2023 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef BOOST_VARIANT_DETAIL_STD_HASH_HPP +#define BOOST_VARIANT_DETAIL_STD_HASH_HPP + +#include +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +// macro BOOST_VARIANT_DO_NOT_SPECIALIZE_STD_HASH +// +// Define this macro if you do not wish to have a std::hash specialization for +// boost::variant. + +#if !defined(BOOST_VARIANT_DO_NOT_SPECIALIZE_STD_HASH) && !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) + +#include // for std::hash + +namespace std { + template < BOOST_VARIANT_ENUM_PARAMS(typename T) > + struct hash > { + std::size_t operator()(const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& val) const { + return ::boost::hash_value(val); + } + }; +} + +#endif // #if !defined(BOOST_VARIANT_DO_NOT_SPECIALIZE_STD_HASH) && !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) + +#endif // BOOST_VARIANT_DETAIL_STD_HASH_HPP + diff --git a/boost/variant/detail/substitute.hpp b/boost/variant/detail/substitute.hpp new file mode 100644 index 00000000..f9d29a50 --- /dev/null +++ b/boost/variant/detail/substitute.hpp @@ -0,0 +1,279 @@ + +#if !defined(BOOST_PP_IS_ITERATING) + +///// header body + +//----------------------------------------------------------------------------- +// boost variant/detail/substitute.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP +#define BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP + +#include + +#include +#include // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace detail { namespace variant { + +#if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction substitute +// +// Substitutes one type for another in the given type expression. +// + +// +// primary template +// +template < + typename T, typename Dest, typename Source + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM( + typename Arity /* = ... (see substitute_fwd.hpp) */ + ) + > +struct substitute +{ + typedef T type; +}; + +// +// tag substitution specializations +// + +#define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(CV_) \ + template \ + struct substitute< \ + CV_ Source \ + , Dest \ + , Source \ + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) \ + > \ + { \ + typedef CV_ Dest type; \ + }; \ + /**/ + +BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG( BOOST_PP_EMPTY() ) +BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(const) +BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(volatile) +BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(const volatile) + +#undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG + +// +// pointer specializations +// +#define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(CV_) \ + template \ + struct substitute< \ + T * CV_ \ + , Dest \ + , Source \ + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) \ + > \ + { \ + typedef typename substitute< \ + T, Dest, Source \ + >::type * CV_ type; \ + }; \ + /**/ + +BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER( BOOST_PP_EMPTY() ) +BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(const) +BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(volatile) +BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(const volatile) + +#undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER + +// +// reference specializations +// +template +struct substitute< + T& + , Dest + , Source + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) + > +{ + typedef typename substitute< + T, Dest, Source + >::type & type; +}; + +// +// template expression (i.e., F<...>) specializations +// + +#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) +template < + template class F + , typename... Ts + , typename Dest + , typename Source + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity) + > +struct substitute< + F + , Dest + , Source + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity) + > +{ + typedef F::type...> type; +}; + +// +// function specializations +// +template < + typename R + , typename... A + , typename Dest + , typename Source + > +struct substitute< + R (*)(A...) + , Dest + , Source + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) + > +{ +private: + typedef typename substitute< R, Dest, Source >::type r; + +public: + typedef r (*type)(typename substitute< + A, Dest, Source + >::type...); +}; +#else + +#define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL(N) \ + typedef typename substitute< \ + BOOST_PP_CAT(U,N), Dest, Source \ + >::type BOOST_PP_CAT(u,N); \ + /**/ + +#define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF(z, N, _) \ + BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL( BOOST_PP_INC(N) ) \ + /**/ + +#define BOOST_PP_ITERATION_LIMITS (0,BOOST_MPL_LIMIT_METAFUNCTION_ARITY) +#define BOOST_PP_FILENAME_1 +#include BOOST_PP_ITERATE() + +#undef BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL +#undef BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF + +#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) +#endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) + +}} // namespace detail::variant +} // namespace boost + +#endif // BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP + +///// iteration, depth == 1 + +#elif BOOST_PP_ITERATION_DEPTH() == 1 +#define i BOOST_PP_FRAME_ITERATION(1) + +#if i > 0 + +// +// template specializations +// +template < + template < BOOST_MPL_PP_PARAMS(i,typename P) > class T + , BOOST_MPL_PP_PARAMS(i,typename U) + , typename Dest + , typename Source + > +struct substitute< + T< BOOST_MPL_PP_PARAMS(i,U) > + , Dest + , Source + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<( i )>) + > +{ +private: + BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF, _) + +public: + typedef T< BOOST_MPL_PP_PARAMS(i,u) > type; +}; + +// +// function specializations +// +template < + typename R + , BOOST_MPL_PP_PARAMS(i,typename U) + , typename Dest + , typename Source + > +struct substitute< + R (*)( BOOST_MPL_PP_PARAMS(i,U) ) + , Dest + , Source + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) + > +{ +private: + typedef typename substitute< R, Dest, Source >::type r; + BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF, _) + +public: + typedef r (*type)( BOOST_MPL_PP_PARAMS(i,u) ); +}; + +#elif i == 0 + +// +// zero-arg function specialization +// +template < + typename R, typename Dest, typename Source + > +struct substitute< + R (*)( void ) + , Dest + , Source + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) + > +{ +private: + typedef typename substitute< R, Dest, Source >::type r; + +public: + typedef r (*type)( void ); +}; + +#endif // i + +#undef i +#endif // BOOST_PP_IS_ITERATING diff --git a/boost/variant/detail/substitute_fwd.hpp b/boost/variant/detail/substitute_fwd.hpp new file mode 100644 index 00000000..cc490744 --- /dev/null +++ b/boost/variant/detail/substitute_fwd.hpp @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/substitute_fwd.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_SUBSTITUTE_FWD_HPP +#define BOOST_VARIANT_DETAIL_SUBSTITUTE_FWD_HPP + +#include +#include +#include + + +/////////////////////////////////////////////////////////////////////////////// +// BOOST_VARIANT_DETAIL_NO_SUBSTITUTE +// +// Defined if 'substitute' is not implementable on the current compiler. +// + +#include +#include + +#if defined(BOOST_NO_TEMPLATE_TEMPLATE_PARAMETERS) \ + && !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) +# define BOOST_VARIANT_DETAIL_NO_SUBSTITUTE +#endif + +namespace boost { +namespace detail { namespace variant { + +#if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) + +/////////////////////////////////////////////////////////////////////////////// +// metafunction substitute +// +// Substitutes one type for another in the given type expression. +// +template < + typename T, typename Dest, typename Source + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM( + typename Arity = mpl::int_< mpl::aux::template_arity::value > + ) + > +struct substitute; + +#endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) + +}} // namespace detail::variant +} // namespace boost + +#endif // BOOST_VARIANT_DETAIL_SUBSTITUTE_FWD_HPP diff --git a/boost/variant/detail/variant_io.hpp b/boost/variant/detail/variant_io.hpp new file mode 100644 index 00000000..63df74f2 --- /dev/null +++ b/boost/variant/detail/variant_io.hpp @@ -0,0 +1,95 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/variant_io.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002-2003 +// Eric Friedman, Itay Maman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_VARIANT_IO_HPP +#define BOOST_VARIANT_DETAIL_VARIANT_IO_HPP + +#include // for std::basic_ostream forward declare + +#include + +#include +#include + +namespace boost { + +/////////////////////////////////////////////////////////////////////////////// +// function template operator<< +// +// Outputs the content of the given variant to the given ostream. +// + +// forward declare (allows output of embedded variant< variant< ... >, ... >) +template < + BOOST_TEMPLATED_STREAM_ARGS(E,T) + BOOST_TEMPLATED_STREAM_COMMA + BOOST_VARIANT_ENUM_PARAMS(typename U) + > +inline BOOST_TEMPLATED_STREAM(ostream, E,T)& operator<<( + BOOST_TEMPLATED_STREAM(ostream, E,T)& out + , const variant< BOOST_VARIANT_ENUM_PARAMS(U) >& rhs + ); + +namespace detail { namespace variant { + +template +class printer + : public boost::static_visitor<> +{ +private: // representation + + OStream& out_; + +public: // structors + + explicit printer(OStream& out) + : out_( out ) + { + } + +public: // visitor interface + + template + void operator()(const T& operand) const + { + out_ << operand; + } + +private: + printer& operator=(const printer&); + +}; + +}} // namespace detail::variant + +template < + BOOST_TEMPLATED_STREAM_ARGS(E,T) + BOOST_TEMPLATED_STREAM_COMMA + BOOST_VARIANT_ENUM_PARAMS(typename U) + > +inline BOOST_TEMPLATED_STREAM(ostream, E,T)& operator<<( + BOOST_TEMPLATED_STREAM(ostream, E,T)& out + , const variant< BOOST_VARIANT_ENUM_PARAMS(U) >& rhs + ) +{ + detail::variant::printer< + BOOST_TEMPLATED_STREAM(ostream, E,T) + > visitor(out); + + rhs.apply_visitor(visitor); + + return out; +} + +} // namespace boost + +#endif // BOOST_VARIANT_DETAIL_VARIANT_IO_HPP diff --git a/boost/variant/detail/visitation_impl.hpp b/boost/variant/detail/visitation_impl.hpp new file mode 100644 index 00000000..c3d91b81 --- /dev/null +++ b/boost/variant/detail/visitation_impl.hpp @@ -0,0 +1,277 @@ +//----------------------------------------------------------------------------- +// boost variant/detail/visitation_impl.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP +#define BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP + +#include + +#include +#include +#include +#include // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +# pragma warning (push) +# pragma warning (disable : 4702) //unreachable code +#endif + +/////////////////////////////////////////////////////////////////////////////// +// BOOST_VARIANT_VISITATION_UNROLLING_LIMIT +// +// Unrolls variant's visitation mechanism to reduce template instantiation +// and potentially increase runtime performance. (TODO: Investigate further.) +// +#if !defined(BOOST_VARIANT_VISITATION_UNROLLING_LIMIT) + +#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES +# include +# define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT \ + BOOST_MPL_LIMIT_LIST_SIZE +#else +# define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT \ + BOOST_VARIANT_LIMIT_TYPES +#endif + +#endif + +// Define a compiler generic null pointer value +#if defined(BOOST_NO_CXX11_NULLPTR) +#define BOOST_VARIANT_NULL 0 +#else +#define BOOST_VARIANT_NULL nullptr +#endif + +namespace boost { +namespace detail { namespace variant { + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class apply_visitor_unrolled +// +// Tag type indicates when visitation_impl is unrolled. +// +struct apply_visitor_unrolled {}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class template visitation_impl_step +// +// "Never ending" iterator range facilitates visitation_impl unrolling. +// + + +template +struct visitation_impl_step +{ + typedef typename mpl::deref::type type; + + typedef typename mpl::next::type next_iter; + typedef visitation_impl_step< + next_iter, LastIter + > next; +}; + +template +struct visitation_impl_step< LastIter,LastIter > +{ + typedef apply_visitor_unrolled type; + typedef visitation_impl_step next; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// (detail) function template visitation_impl_invoke +// +// Invokes the given visitor on the specified type in the given storage. +// + +template +inline typename Visitor::result_type +visitation_impl_invoke_impl( + int, Visitor& visitor, VoidPtrCV storage, T* + , mpl::true_// never_uses_backup + ) +{ + return visitor.internal_visit( + cast_storage(storage), 1L + ); +} + +template +inline typename Visitor::result_type +visitation_impl_invoke_impl( + int internal_which, Visitor& visitor, VoidPtrCV storage, T* + , mpl::false_// never_uses_backup + ) +{ + if (internal_which >= 0) + { + return visitor.internal_visit( + cast_storage(storage), 1L + ); + } + else + { + return visitor.internal_visit( + cast_storage< backup_holder >(storage), 1L + ); + } +} + +template +inline typename Visitor::result_type +visitation_impl_invoke( + int internal_which, Visitor& visitor, VoidPtrCV storage, T* t + , NoBackupFlag + , int + ) +{ + typedef typename mpl::or_< + NoBackupFlag + , is_nothrow_move_constructible + , has_nothrow_copy + >::type never_uses_backup; + + return (visitation_impl_invoke_impl)( + internal_which, visitor, storage, t + , never_uses_backup() + ); +} + +template +inline typename Visitor::result_type +visitation_impl_invoke(int, Visitor&, VoidPtrCV, apply_visitor_unrolled*, NBF, long) +{ + // should never be here at runtime! + typedef typename Visitor::result_type result_type; + return ::boost::detail::variant::forced_return< result_type >(); +} + +/////////////////////////////////////////////////////////////////////////////// +// (detail) function template visitation_impl +// +// Invokes the given visitor on the type in the given variant storage. +// + +template < + typename W, typename S + , typename Visitor, typename VPCV + , typename NBF + > +inline typename Visitor::result_type +visitation_impl( + int, int, Visitor&, VPCV + , mpl::true_ // is_apply_visitor_unrolled + , NBF, W* = BOOST_VARIANT_NULL, S* = BOOST_VARIANT_NULL + ) +{ + // should never be here at runtime! + typedef typename Visitor::result_type result_type; + return ::boost::detail::variant::forced_return< result_type >(); +} + +template < + typename Which, typename step0 + , typename Visitor, typename VoidPtrCV + , typename NoBackupFlag + > +BOOST_FORCEINLINE typename Visitor::result_type +visitation_impl( + const int internal_which, const int logical_which + , Visitor& visitor, VoidPtrCV storage + , mpl::false_ // is_apply_visitor_unrolled + , NoBackupFlag no_backup_flag + , Which* = BOOST_VARIANT_NULL, step0* = BOOST_VARIANT_NULL + ) +{ + // Typedef apply_visitor_unrolled steps and associated types... +# define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF(z, N, _) \ + typedef typename BOOST_PP_CAT(step,N)::type BOOST_PP_CAT(T,N); \ + typedef typename BOOST_PP_CAT(step,N)::next \ + BOOST_PP_CAT(step, BOOST_PP_INC(N)); \ + /**/ + + BOOST_PP_REPEAT( + BOOST_VARIANT_VISITATION_UNROLLING_LIMIT + , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF + , _ + ) + +# undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF + + // ...switch on the target which-index value... + switch (logical_which) + { + + // ...applying the appropriate case: +# define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE(z, N, _) \ + case (Which::value + (N)): \ + return (visitation_impl_invoke)( \ + internal_which, visitor, storage \ + , static_cast(0) \ + , no_backup_flag, 1L \ + ); \ + /**/ + + BOOST_PP_REPEAT( + BOOST_VARIANT_VISITATION_UNROLLING_LIMIT + , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE + , _ + ) + +# undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE + + default: break; + } + + // If not handled in this iteration, continue unrolling: + typedef mpl::int_< + Which::value + (BOOST_VARIANT_VISITATION_UNROLLING_LIMIT) + > next_which; + + typedef BOOST_PP_CAT(step, BOOST_VARIANT_VISITATION_UNROLLING_LIMIT) + next_step; + + typedef typename next_step::type next_type; + typedef typename is_same< next_type,apply_visitor_unrolled >::type + is_apply_visitor_unrolled; + + return detail::variant::visitation_impl( + internal_which, logical_which + , visitor, storage + , is_apply_visitor_unrolled() + , no_backup_flag + , static_cast(0), static_cast(0) + ); +} + +}} // namespace detail::variant +} // namespace boost + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +# pragma warning(pop) +#endif + +#endif // BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP diff --git a/boost/variant/get.hpp b/boost/variant/get.hpp new file mode 100644 index 00000000..62fca60c --- /dev/null +++ b/boost/variant/get.hpp @@ -0,0 +1,388 @@ +//----------------------------------------------------------------------------- +// boost variant/get.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 Eric Friedman, Itay Maman +// Copyright (c) 2014-2023 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_GET_HPP +#define BOOST_VARIANT_GET_HPP + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { + +#if defined(BOOST_CLANG) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wweak-vtables" +#endif +////////////////////////////////////////////////////////////////////////// +// class bad_get +// +// The exception thrown in the event of a failed get of a value. +// +class BOOST_SYMBOL_VISIBLE bad_get + : public std::exception +{ +public: // std::exception implementation + + const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE + { + return "boost::bad_get: " + "failed value get using boost::get"; + } + +}; +#if defined(BOOST_CLANG) +# pragma clang diagnostic pop +#endif + + +////////////////////////////////////////////////////////////////////////// +// function template get +// +// Retrieves content of given variant object if content is of type T. +// Otherwise: pointer ver. returns 0; reference ver. throws bad_get. +// + +namespace detail { namespace variant { + +// (detail) class template get_visitor +// +// Generic static visitor that: if the value is of the specified type, +// returns a pointer to the value it visits; else a null pointer. +// +template +struct get_visitor +{ +private: // private typedefs + + typedef typename add_pointer::type pointer; + typedef typename add_reference::type reference; + +public: // visitor typedefs + + typedef pointer result_type; + +public: // visitor interfaces + + pointer operator()(reference operand) const BOOST_NOEXCEPT + { + return boost::addressof(operand); + } + + template + pointer operator()(const U&) const BOOST_NOEXCEPT + { + return static_cast(0); + } +}; + +}} // namespace detail::variant + +#ifndef BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE +# if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0551)) +# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) +# else +# if defined(BOOST_NO_CXX11_NULLPTR) +# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \ + , t* = 0 +# else +# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \ + , t* = nullptr +# endif +# endif +#endif + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +// relaxed_get(variant) methods +// +template +inline + typename add_pointer::type +relaxed_get( + boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) BOOST_NOEXCEPT +{ + typedef typename add_pointer::type U_ptr; + if (!operand) return static_cast(0); + + detail::variant::get_visitor v; + return operand->apply_visitor(v); +} + +template +inline + typename add_pointer::type +relaxed_get( + const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) BOOST_NOEXCEPT +{ + typedef typename add_pointer::type U_ptr; + if (!operand) return static_cast(0); + + detail::variant::get_visitor v; + return operand->apply_visitor(v); +} + +template +inline + typename add_reference::type +relaxed_get( + boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) +{ + typedef typename add_pointer::type U_ptr; + U_ptr result = relaxed_get(boost::addressof(operand)); + + if (!result) + boost::throw_exception(bad_get()); + return *result; +} + +template +inline + typename add_reference::type +relaxed_get( + const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) +{ + typedef typename add_pointer::type U_ptr; + U_ptr result = relaxed_get(boost::addressof(operand)); + + if (!result) + boost::throw_exception(bad_get()); + return *result; +} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +#if defined(BOOST_MSVC) && (_MSC_VER < 1900) // MSVC-2014 has fixed the incorrect diagnostics. +# pragma warning(push) +# pragma warning(disable: 4172) // returning address of local variable or temporary +#endif + +template +inline + U&& +relaxed_get( + boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >&& operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) +{ + typedef typename add_pointer::type U_ptr; + U_ptr result = relaxed_get(boost::addressof(operand)); + + if (!result) + boost::throw_exception(bad_get()); + return static_cast(*result); +} + +#if defined(BOOST_MSVC) && (_MSC_VER < 1900) +# pragma warning(pop) +#endif + +#endif + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +// strict_get(variant) methods +// +template +inline + typename add_pointer::type +strict_get( + boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT_MSG( + (boost::detail::variant::holds_element, U >::value), + "boost::variant does not contain specified type U, " + "call to boost::get(boost::variant*) will always return NULL" + ); + + return relaxed_get(operand); +} + +template +inline + typename add_pointer::type +strict_get( + const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT_MSG( + (boost::detail::variant::holds_element, const U >::value), + "boost::variant does not contain specified type U, " + "call to boost::get(const boost::variant*) will always return NULL" + ); + + return relaxed_get(operand); +} + +template +inline + typename add_reference::type +strict_get( + boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) +{ + BOOST_STATIC_ASSERT_MSG( + (boost::detail::variant::holds_element, U >::value), + "boost::variant does not contain specified type U, " + "call to boost::get(boost::variant&) will always throw boost::bad_get exception" + ); + + return relaxed_get(operand); +} + +template +inline + typename add_reference::type +strict_get( + const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) +{ + BOOST_STATIC_ASSERT_MSG( + (boost::detail::variant::holds_element, const U >::value), + "boost::variant does not contain specified type U, " + "call to boost::get(const boost::variant&) will always throw boost::bad_get exception" + ); + + return relaxed_get(operand); +} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +template +inline + U&& +strict_get( + boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >&& operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) +{ + BOOST_STATIC_ASSERT_MSG( + (!boost::is_lvalue_reference::value), + "remove ampersand '&' from template type U in boost::get(boost::variant&&) " + ); + + BOOST_STATIC_ASSERT_MSG( + (boost::detail::variant::holds_element, U >::value), + "boost::variant does not contain specified type U, " + "call to boost::get(const boost::variant&) will always throw boost::bad_get exception" + ); + + return relaxed_get(detail::variant::move(operand)); +} +#endif + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +// get(variant) methods +// + +template +inline + typename add_pointer::type +get( + boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) BOOST_NOEXCEPT +{ +#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT + return relaxed_get(operand); +#else + return strict_get(operand); +#endif + +} + +template +inline + typename add_pointer::type +get( + const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) BOOST_NOEXCEPT +{ +#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT + return relaxed_get(operand); +#else + return strict_get(operand); +#endif +} + +template +inline + typename add_reference::type +get( + boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) +{ +#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT + return relaxed_get(operand); +#else + return strict_get(operand); +#endif +} + +template +inline + typename add_reference::type +get( + const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) +{ +#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT + return relaxed_get(operand); +#else + return strict_get(operand); +#endif +} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +template +inline + U&& +get( + boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >&& operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) +{ +#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT + return relaxed_get(detail::variant::move(operand)); +#else + return strict_get(detail::variant::move(operand)); +#endif +} +#endif + +} // namespace boost + +#endif // BOOST_VARIANT_GET_HPP diff --git a/boost/variant/recursive_variant.hpp b/boost/variant/recursive_variant.hpp new file mode 100644 index 00000000..6248dc10 --- /dev/null +++ b/boost/variant/recursive_variant.hpp @@ -0,0 +1,209 @@ +//----------------------------------------------------------------------------- +// boost variant/recursive_variant.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 Eric Friedman +// Copyright (c) 2013-2023 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_RECURSIVE_VARIANT_HPP +#define BOOST_VARIANT_RECURSIVE_VARIANT_HPP + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { + +namespace detail { namespace variant { + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction specialization substitute +// +// Handles embedded variant types when substituting for recursive_variant_. +// + +#if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) + +template < + BOOST_VARIANT_ENUM_PARAMS(typename T) + , typename RecursiveVariant + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity) + > +struct substitute< + ::boost::variant< + recursive_flag< T0 > + , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T) + > + , RecursiveVariant + , ::boost::recursive_variant_ + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity) + > +{ + typedef ::boost::variant< + recursive_flag< T0 > + , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T) + > type; +}; + +template < + BOOST_VARIANT_ENUM_PARAMS(typename T) + , typename RecursiveVariant + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity) + > +struct substitute< + ::boost::variant< + ::boost::detail::variant::over_sequence< T0 > + , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T) + > + , RecursiveVariant + , ::boost::recursive_variant_ + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity) + > +{ +private: + + typedef T0 initial_types; + + typedef typename mpl::transform< + initial_types + , mpl::protect< quoted_enable_recursive > + >::type types; + +public: + + typedef typename mpl::if_< + mpl::equal > + , ::boost::variant< + ::boost::detail::variant::over_sequence< T0 > + , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T) + > + , ::boost::variant< over_sequence > + >::type type; +}; + +template < + BOOST_VARIANT_ENUM_PARAMS(typename T) + , typename RecursiveVariant + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity) + > +struct substitute< + ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) > + , RecursiveVariant + , ::boost::recursive_variant_ + BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity) + > +{ +#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) + + typedef ::boost::variant< + typename enable_recursive< + T0 + , RecursiveVariant + , mpl::true_ + >::type, + typename enable_recursive< + TN + , RecursiveVariant + , mpl::true_ + >::type... + > type; + +#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) + +private: // helpers, for metafunction result (below) + + #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \ + typedef typename enable_recursive< \ + BOOST_PP_CAT(T,N) \ + , RecursiveVariant \ + , mpl::true_ \ + >::type BOOST_PP_CAT(wknd_T,N); \ + /**/ + + BOOST_PP_REPEAT( + BOOST_VARIANT_LIMIT_TYPES + , BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS + , _ + ) + + #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS + +public: // metafunction result + + typedef ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(wknd_T) > type; +#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround +}; + +#else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) + +// +// no specializations: embedded variants unsupported on these compilers! +// + +#endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) + +}} // namespace detail::variant + +/////////////////////////////////////////////////////////////////////////////// +// metafunction make_recursive_variant +// +// See docs and boost/variant/variant_fwd.hpp for more information. +// +template < BOOST_VARIANT_ENUM_PARAMS(typename T) > +struct make_recursive_variant +{ +public: // metafunction result + + typedef boost::variant< + detail::variant::recursive_flag< T0 > + , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T) + > type; + +}; + +/////////////////////////////////////////////////////////////////////////////// +// metafunction make_recursive_variant_over +// +// See docs and boost/variant/variant_fwd.hpp for more information. +// +template +struct make_recursive_variant_over +{ +private: // precondition assertions + + BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence::value )); + +public: // metafunction result + + typedef typename make_recursive_variant< + detail::variant::over_sequence< Types > + >::type type; + +}; + +} // namespace boost + +#endif // BOOST_VARIANT_RECURSIVE_VARIANT_HPP diff --git a/boost/variant/recursive_wrapper.hpp b/boost/variant/recursive_wrapper.hpp new file mode 100644 index 00000000..f11418d2 --- /dev/null +++ b/boost/variant/recursive_wrapper.hpp @@ -0,0 +1,158 @@ +//----------------------------------------------------------------------------- +// boost variant/recursive_wrapper.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002-2003 +// Eric Friedman, Itay Maman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_RECURSIVE_WRAPPER_HPP +#define BOOST_VARIANT_RECURSIVE_WRAPPER_HPP + +#include +#include +#include + +namespace boost { + +////////////////////////////////////////////////////////////////////////// +// class template recursive_wrapper +// +// See docs and recursive_wrapper_fwd.hpp for more information. +// + +template +class recursive_wrapper +{ +public: // typedefs + + typedef T type; + +private: // representation + + T* p_; + +public: // structors + + ~recursive_wrapper(); + recursive_wrapper(); + + recursive_wrapper(const recursive_wrapper& operand); + recursive_wrapper(const T& operand); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + recursive_wrapper(recursive_wrapper&& operand); + recursive_wrapper(T&& operand); +#endif + +private: // helpers, for modifiers (below) + + void assign(const T& rhs); + +public: // modifiers + + recursive_wrapper& operator=(const recursive_wrapper& rhs) + { + assign( rhs.get() ); + return *this; + } + + recursive_wrapper& operator=(const T& rhs) + { + assign( rhs ); + return *this; + } + + void swap(recursive_wrapper& operand) BOOST_NOEXCEPT + { + T* temp = operand.p_; + operand.p_ = p_; + p_ = temp; + } + + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + recursive_wrapper& operator=(recursive_wrapper&& rhs) BOOST_NOEXCEPT + { + swap(rhs); + return *this; + } + + recursive_wrapper& operator=(T&& rhs) + { + get() = detail::variant::move(rhs); + return *this; + } +#endif + +public: // queries + + T& get() { return *get_pointer(); } + const T& get() const { return *get_pointer(); } + + T* get_pointer() { return p_; } + const T* get_pointer() const { return p_; } + +}; + +template +recursive_wrapper::~recursive_wrapper() +{ + boost::checked_delete(p_); +} + +template +recursive_wrapper::recursive_wrapper() + : p_(new T) +{ +} + +template +recursive_wrapper::recursive_wrapper(const recursive_wrapper& operand) + : p_(new T( operand.get() )) +{ +} + +template +recursive_wrapper::recursive_wrapper(const T& operand) + : p_(new T(operand)) +{ +} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +template +recursive_wrapper::recursive_wrapper(recursive_wrapper&& operand) + : p_(new T( detail::variant::move(operand.get()) )) +{ +} + +template +recursive_wrapper::recursive_wrapper(T&& operand) + : p_(new T( detail::variant::move(operand) )) +{ +} +#endif + +template +void recursive_wrapper::assign(const T& rhs) +{ + this->get() = rhs; +} + +// function template swap +// +// Swaps two recursive_wrapper objects of the same type T. +// +template +inline void swap(recursive_wrapper& lhs, recursive_wrapper& rhs) BOOST_NOEXCEPT +{ + lhs.swap(rhs); +} + +} // namespace boost + +#endif // BOOST_VARIANT_RECURSIVE_WRAPPER_HPP diff --git a/boost/variant/recursive_wrapper_fwd.hpp b/boost/variant/recursive_wrapper_fwd.hpp new file mode 100644 index 00000000..b5d7e719 --- /dev/null +++ b/boost/variant/recursive_wrapper_fwd.hpp @@ -0,0 +1,130 @@ +//----------------------------------------------------------------------------- +// boost variant/recursive_wrapper_fwd.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002 Eric Friedman, Itay Maman +// Copyright (c) 2016-2023 Antony Polukhin +// +// Portions Copyright (C) 2002 David Abrahams +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP +#define BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { + +////////////////////////////////////////////////////////////////////////// +// class template recursive_wrapper +// +// Enables recursive types in templates by breaking cyclic dependencies. +// +// For example: +// +// class my; +// +// typedef variant< int, recursive_wrapper > var; +// +// class my { +// var var_; +// ... +// }; +// +template class recursive_wrapper; + + +/////////////////////////////////////////////////////////////////////////////// +// metafunction is_constructible partial specializations. +// +// recursive_wrapper is constructible only from T and recursive_wrapper. +// +template struct is_constructible, T> : boost::true_type{}; +template struct is_constructible, const T> : boost::true_type{}; +template struct is_constructible, T&> : boost::true_type{}; +template struct is_constructible, const T&> : boost::true_type{}; +template struct is_constructible, recursive_wrapper > : boost::true_type{}; +template struct is_constructible, const recursive_wrapper > : boost::true_type{}; +template struct is_constructible, recursive_wrapper& > : boost::true_type{}; +template struct is_constructible, const recursive_wrapper& > : boost::true_type{}; + +template struct is_constructible, U > : boost::false_type{}; +template struct is_constructible, const U > : boost::false_type{}; +template struct is_constructible, U& > : boost::false_type{}; +template struct is_constructible, const U& > : boost::false_type{}; +template struct is_constructible, recursive_wrapper > : boost::false_type{}; +template struct is_constructible, const recursive_wrapper > : boost::false_type{}; +template struct is_constructible, recursive_wrapper& > : boost::false_type{}; +template struct is_constructible, const recursive_wrapper& > : boost::false_type{}; + +// recursive_wrapper is not nothrow move constructible, because it's constructor does dynamic memory allocation. +// This specialisation is required to workaround GCC6 issue: https://svn.boost.org/trac/boost/ticket/12680 +template struct is_nothrow_move_constructible > : boost::false_type{}; + +/////////////////////////////////////////////////////////////////////////////// +// metafunction is_recursive_wrapper (modeled on code by David Abrahams) +// +// True if specified type matches recursive_wrapper. +// + +namespace detail { + + +template +struct is_recursive_wrapper_impl + : mpl::false_ +{ +}; + +template +struct is_recursive_wrapper_impl< recursive_wrapper > + : mpl::true_ +{ +}; + + +} // namespace detail + +template< typename T > struct is_recursive_wrapper + : public ::boost::integral_constant::value)> +{ +public: + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_recursive_wrapper,(T)) +}; + +/////////////////////////////////////////////////////////////////////////////// +// metafunction unwrap_recursive +// +// If specified type T matches recursive_wrapper, then U; else T. +// + + +template +struct unwrap_recursive +{ + typedef T type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,unwrap_recursive,(T)) +}; + +template +struct unwrap_recursive< recursive_wrapper > +{ + typedef T type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(1,unwrap_recursive,(T)) +}; + + +} // namespace boost + +#endif // BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP diff --git a/boost/variant/static_visitor.hpp b/boost/variant/static_visitor.hpp new file mode 100644 index 00000000..ee40fecf --- /dev/null +++ b/boost/variant/static_visitor.hpp @@ -0,0 +1,93 @@ +//----------------------------------------------------------------------------- +// boost variant/static_visitor.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002-2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_STATIC_VISITOR_HPP +#define BOOST_VARIANT_STATIC_VISITOR_HPP + +#include +#include + +#include +#include + +#include +#include + +namespace boost { + +////////////////////////////////////////////////////////////////////////// +// class template static_visitor +// +// An empty base class that typedefs the return type of a deriving static +// visitor. The class is analogous to std::unary_function in this role. +// + +namespace detail { + + struct is_static_visitor_tag { }; + + typedef void static_visitor_default_return; + +} // namespace detail + +template +class static_visitor + : public detail::is_static_visitor_tag +{ +public: // typedefs + + typedef R result_type; + +protected: // for use as base class only +#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS) + static_visitor() = default; +#else + static_visitor() BOOST_NOEXCEPT { } +#endif +}; + +////////////////////////////////////////////////////////////////////////// +// metafunction is_static_visitor +// +// Value metafunction indicates whether the specified type derives from +// static_visitor<...>. +// +// NOTE #1: This metafunction does NOT check whether the specified type +// fulfills the requirements of the StaticVisitor concept. +// +// NOTE #2: This template never needs to be specialized! +// + +namespace detail { + +template +struct is_static_visitor_impl +{ + BOOST_STATIC_CONSTANT(bool, value = + (::boost::is_base_and_derived< + detail::is_static_visitor_tag, + T + >::value)); +}; + +} // namespace detail + +template< typename T > struct is_static_visitor + : public ::boost::integral_constant::value)> +{ +public: + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_static_visitor,(T)) +}; + +} // namespace boost + +#endif // BOOST_VARIANT_STATIC_VISITOR_HPP diff --git a/boost/variant/variant.hpp b/boost/variant/variant.hpp new file mode 100644 index 00000000..9a79264a --- /dev/null +++ b/boost/variant/variant.hpp @@ -0,0 +1,2457 @@ +//----------------------------------------------------------------------------- +// boost variant/variant.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002-2003 Eric Friedman, Itay Maman +// Copyright (c) 2012-2023 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Thanks to Adam Romanek for providing patches for exception-disabled env. + +#ifndef BOOST_VARIANT_VARIANT_HPP +#define BOOST_VARIANT_VARIANT_HPP + +#include // for std::size_t +#include // for placement new + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +// Implementation Macros: +// +// BOOST_VARIANT_VISITATION_UNROLLING_LIMIT +// Defined in boost/variant/detail/visitation_impl.hpp. +// +// BOOST_VARIANT_MINIMIZE_SIZE +// When #defined, implementation employs all known means to minimize the +// size of variant obje cts. However, often unsuccessful due to alignment +// issues, and potentially harmful to runtime speed, so not enabled by +// default. (TODO: Investigate further.) + +#if defined(BOOST_VARIANT_MINIMIZE_SIZE) +# include // for SCHAR_MAX +# include +# include +# include +# include +# include +# include +# include +# include +#endif + + +namespace boost { + +namespace detail { namespace variant { + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction max_value +// +// Finds the maximum value of the unary metafunction F over Sequence. +// +template +struct max_value +{ +private: // helpers, for metafunction result (below) + + typedef typename mpl::transform1::type transformed_; + typedef typename mpl::max_element::type max_it; + +public: // metafunction result + + typedef typename mpl::deref::type + type; + +}; + +struct add_alignment +{ + template + struct apply + : mpl::size_t< + ::boost::integer::static_lcm< + BOOST_MPL_AUX_VALUE_WKND(State)::value + , ::boost::alignment_of::value + >::value + > + {}; +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction find_fallback_type +// +// Provides a fallback (i.e., nothrow default-constructible) type from the +// specified sequence, or no_fallback_type if not found. +// +// This implementation is designed to prefer boost::blank over other potential +// fallback types, regardless of its position in the specified sequence. +// + +class no_fallback_type; + +struct find_fallback_type_pred +{ + template + struct apply + { + private: + typedef typename mpl::deref::type t_; + + public: + typedef mpl::not_< has_nothrow_constructor > type; + }; +}; + +template +struct find_fallback_type +{ +private: // helpers, for metafunction result (below) + + typedef typename mpl::end::type end_it; + + // [Find the first suitable fallback type...] + + typedef typename mpl::iter_fold_if< + Types + , mpl::int_<0>, mpl::protect< mpl::next<> > + , mpl::protect< find_fallback_type_pred > + >::type first_result_; + + typedef typename first_result_::first first_result_index; + typedef typename first_result_::second first_result_it; + + // [...now search the rest of the sequence for boost::blank...] + + typedef typename mpl::iter_fold_if< + mpl::iterator_range< first_result_it,end_it > + , first_result_index, mpl::protect< mpl::next<> > + , mpl::protect< mpl::not_same_as > + >::type second_result_; + + typedef typename second_result_::second second_result_it; + +public: // metafunction result + + // [...and return the results of the search:] + typedef typename mpl::eval_if< + is_same< second_result_it,end_it > + , mpl::if_< + is_same< first_result_it,end_it > + , mpl::pair< no_fallback_type,no_fallback_type > + , first_result_ + > + , mpl::identity< second_result_ > + >::type type; + +}; + +#ifndef BOOST_NO_CXX11_NOEXCEPT +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction is_variant_move_noexcept_constructible +// +// Returns true_type if all the types are nothrow move constructible. +// +template +struct is_variant_move_noexcept_constructible { + typedef typename boost::mpl::find_if< + Types, mpl::not_ > + >::type iterator_t; + + typedef typename boost::mpl::end::type end_t; + typedef typename boost::is_same< + iterator_t, end_t + >::type type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction is_variant_move_noexcept_assignable +// +// Returns true_type if all the types are nothrow move constructible. +// +template +struct is_variant_move_noexcept_assignable { + typedef typename boost::mpl::find_if< + Types, mpl::not_ > + >::type iterator_t; + + typedef typename boost::mpl::end::type end_t; + typedef typename boost::is_same< + iterator_t, end_t + >::type type; +}; +#endif // BOOST_NO_CXX11_NOEXCEPT + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction is_variant_constructible_from +// +// Derives from true_type if at least one variant's type is constructible from T. +// +template +struct is_constructible_ext: + boost::mpl::or_< + boost::is_constructible< + T1, + T2 + >, + boost::is_constructible< + T1, + typename boost::add_lvalue_reference::type + > + > +{}; + +template +struct is_variant_constructible_from: + boost::mpl::not_< boost::is_same< + typename boost::mpl::find_if< + Types, + is_constructible_ext + >::type, + typename boost::mpl::end::type + > > +{}; + +template +struct is_variant_constructible_from< boost::variant, Types >: + boost::is_same< + typename boost::mpl::find_if< + typename boost::variant::recursive_enabled_types, + mpl::not_< is_variant_constructible_from< boost::mpl::_1, Types> > + >::type, + typename boost::mpl::end< typename boost::variant::recursive_enabled_types >::type + > +{}; + +template +struct is_variant_constructible_from< const boost::variant& , Types >: + is_variant_constructible_from, Types > +{}; + +template +struct is_variant_constructible_from< boost::variant& , Types >: + is_variant_constructible_from, Types > +{}; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template +struct is_variant_constructible_from< boost::variant&& , Types >: + is_variant_constructible_from, Types > +{}; + +template +struct is_variant_constructible_from< boost::variant const && , Types >: + is_variant_constructible_from, Types > +{}; + +#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCE + + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction make_storage +// +// Provides an aligned storage type capable of holding any of the types +// specified in the given type-sequence. +// + +template +struct make_storage +{ +private: // helpers, for metafunction result (below) + + typedef typename mpl::eval_if< + NeverUsesBackupFlag + , mpl::identity< Types > + , mpl::push_front< + Types, backup_holder + > + >::type types; + + typedef typename max_value< + types, mpl::sizeof_ + >::type max_size; + +#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0551)) + + typedef typename mpl::fold< + types + , mpl::size_t<1> + , add_alignment + >::type max_alignment; + +#else // borland + + // temporary workaround -- use maximal alignment + typedef mpl::size_t< -1 > max_alignment; + +#endif // borland workaround + +public: // metafunction result + + typedef ::boost::aligned_storage< + BOOST_MPL_AUX_VALUE_WKND(max_size)::value + , BOOST_MPL_AUX_VALUE_WKND(max_alignment)::value + > type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class destroyer +// +// Internal visitor that destroys the value it visits. +// +struct destroyer + : public static_visitor<> +{ +public: // visitor interfaces + + template + void internal_visit(T& operand, int) const BOOST_NOEXCEPT + { + operand.~T(); // must be noexcept + +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0551)) || \ + BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) + (void)operand; // suppresses warnings +#endif + } + +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class template known_get +// +// Visitor that returns a reference to content of the specified type. +// +// Precondition: visited variant MUST contain logical content of type T. +// +template +class known_get + : public static_visitor +{ + +public: // visitor interface + + T& operator()(T& operand) const BOOST_NOEXCEPT + { + return operand; + } + + template + T& operator()(U&) const + { + // logical error to be here: see precondition above + return ::boost::detail::variant::forced_return< T& >(); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class copy_into +// +// Internal visitor that copies the value it visits into the given buffer. +// +class copy_into + : public static_visitor<> +{ +private: // representation + + void* storage_; + +public: // structors + + explicit copy_into(void* storage) BOOST_NOEXCEPT + : storage_(storage) + { + } + +public: // internal visitor interface + + template + void internal_visit(boost::detail::variant::backup_holder& operand, long) const + { + new(storage_) T( operand.get() ); + } + + template + void internal_visit(const boost::detail::variant::backup_holder& operand, long) const + { + new(storage_) T( operand.get() ); + } + + template + void internal_visit(const T& operand, int) const + { + new(storage_) T(operand); + } + +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class move_into +// +// Internal visitor that moves the value it visits into the given buffer. +// +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +class move_into + : public static_visitor<> +{ +private: // representation + + void* storage_; + +public: // structors + + explicit move_into(void* storage) BOOST_NOEXCEPT + : storage_(storage) + { + } + +public: // internal visitor interface + + template + void internal_visit(boost::detail::variant::backup_holder& operand, long) const + { + new(storage_) T( ::boost::detail::variant::move(operand.get()) ); + } + + template + void internal_visit(T& operand, int) const BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(T(boost::declval()))) + { + new(storage_) T(::boost::detail::variant::move(operand)); + } +}; +#endif + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class assign_storage +// +// Internal visitor that assigns the given storage (which must be a +// constructed value of the same type) to the value it visits. +// +struct assign_storage + : public static_visitor<> +{ +private: // representation + + const void* rhs_storage_; + +public: // structors + + explicit assign_storage(const void* rhs_storage) BOOST_NOEXCEPT + : rhs_storage_(rhs_storage) + { + } + +public: // internal visitor interfaces + + template + void internal_visit(backup_holder& lhs_content, long) const + { + lhs_content.get() + = static_cast< const backup_holder* >(rhs_storage_)->get(); + } + + template + void internal_visit(const backup_holder& lhs_content, long) const + { + lhs_content.get() + = static_cast< const backup_holder* >(rhs_storage_)->get(); + } + + template + void internal_visit(T& lhs_content, int) const + { + // NOTE TO USER : + // Compile error here indicates one of variant's bounded types does + // not meet the requirements of the Assignable concept. Thus, + // variant is not Assignable. + // + // Hint: Are any of the bounded types const-qualified or references? + // + lhs_content = *static_cast< const T* >(rhs_storage_); + } + +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class move_storage +// +// Internal visitor that moves the given storage (which must be a +// constructed value of the same type) to the value it visits. +// +struct move_storage + : public static_visitor<> +{ +private: // representation + + void* rhs_storage_; + +public: // structors + + explicit move_storage(void* rhs_storage) BOOST_NOEXCEPT + : rhs_storage_(rhs_storage) + { + } + +public: // internal visitor interfaces + + template + void internal_visit(backup_holder& lhs_content, long) const + { + lhs_content.get() + = ::boost::detail::variant::move(static_cast* >(rhs_storage_)->get()); + } + + template + void internal_visit(const backup_holder& lhs_content, long) const + { + lhs_content.get() + = ::boost::detail::variant::move(static_cast* >(rhs_storage_)->get()); + } + + template + void internal_visit(T& lhs_content, int) const + { + // NOTE TO USER : + // Compile error here indicates one of variant's bounded types does + // not meet the requirements of the Assignable concept. Thus, + // variant is not Assignable. + // + // Hint: Are any of the bounded types const-qualified or references? + // + lhs_content = ::boost::detail::variant::move(*static_cast(rhs_storage_)); + } + +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class direct_assigner +// +// Generic static visitor that: if and only if the visited value is of the +// specified type, assigns the given value to the visited value and returns +// true; else returns false. +// +template +class direct_assigner + : public static_visitor +{ +private: // representation + + const T& rhs_; + +public: // structors + + explicit direct_assigner(const T& rhs) BOOST_NOEXCEPT + : rhs_(rhs) + { + } + +public: // visitor interface + + bool operator()(T& lhs) + { + lhs = rhs_; + return true; + } + + template + bool operator()(U&) BOOST_NOEXCEPT + { + return false; + } + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) +private: + // silence MSVC warning C4512: assignment operator could not be generated + direct_assigner& operator= (direct_assigner const&); +#endif +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class direct_mover +// +// Generic static visitor that: if and only if the visited value is of the +// specified type, move assigns the given value to the visited value and returns +// true; else returns false. +// +template +class direct_mover + : public static_visitor +{ +private: // representation + + T& rhs_; + +public: // structors + + explicit direct_mover(T& rhs) BOOST_NOEXCEPT + : rhs_(rhs) + { + } + +public: // visitor interface + + bool operator()(T& lhs) + { + lhs = ::boost::detail::variant::move(rhs_); + return true; + } + + template + bool operator()(U&) BOOST_NOEXCEPT + { + return false; + } + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) +private: + // silence MSVC warning C4512: assignment operator could not be generated + direct_mover& operator= (direct_mover const&); +#endif +}; + + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class backup_assigner +// +// Internal visitor that "assigns" the given value to the visited value, +// using backup to recover if the destroy-copy sequence fails. +// +// NOTE: This needs to be a friend of variant, as it needs access to +// indicate_which, indicate_backup_which, etc. +// +template +class backup_assigner + : public static_visitor<> +{ +private: // representation + + Variant& lhs_; + int rhs_which_; + const void* rhs_content_; + void (*copy_rhs_content_)(void*, const void*); + +public: // structors + + template + backup_assigner(Variant& lhs, int rhs_which, const RhsT& rhs_content) + : lhs_(lhs) + , rhs_which_(rhs_which) + , rhs_content_(&rhs_content) + , copy_rhs_content_(&construct_impl) + { + } + +private: // helpers, for visitor interface (below) + + template + static void construct_impl(void* addr, const void* obj) + { + new(addr) RhsT(*static_cast(obj)); + } + + template + void backup_assign_impl( + backup_holder& lhs_content + , mpl::false_ // is_nothrow_move_constructible + , long + ) + { + // Move lhs content to backup... + backup_holder backup_lhs_content(0); + backup_lhs_content.swap(lhs_content); // nothrow + + // ...destroy lhs content... + lhs_content.~backup_holder(); // nothrow + + BOOST_TRY + { + // ...and attempt to copy rhs content into lhs storage: + copy_rhs_content_(lhs_.storage_.address(), rhs_content_); + } + BOOST_CATCH (...) + { + // In case of failure, copy backup pointer to lhs storage... + new(lhs_.storage_.address()) + backup_holder( 0 ); // nothrow + + static_cast* >(lhs_.storage_.address()) + ->swap(backup_lhs_content); // nothrow + + // ...and rethrow: + BOOST_RETHROW; + } + BOOST_CATCH_END + + // In case of success, indicate new content type: + lhs_.indicate_which(rhs_which_); // nothrow + } + + template + void backup_assign_impl( + LhsT& lhs_content + , mpl::true_ // is_nothrow_move_constructible + , int + ) + { + // Move lhs content to backup... + LhsT backup_lhs_content( + ::boost::detail::variant::move(lhs_content) + ); // nothrow + + // ...destroy lhs content... + lhs_content.~LhsT(); // nothrow + + BOOST_TRY + { + // ...and attempt to copy rhs content into lhs storage: + copy_rhs_content_(lhs_.storage_.address(), rhs_content_); + } + BOOST_CATCH (...) + { + // In case of failure, restore backup content to lhs storage... + new(lhs_.storage_.address()) + LhsT( + ::boost::detail::variant::move(backup_lhs_content) + ); // nothrow + + // ...and rethrow: + BOOST_RETHROW; + } + BOOST_CATCH_END + + // In case of success, indicate new content type: + lhs_.indicate_which(rhs_which_); // nothrow + } + + template + void backup_assign_impl( + LhsT& lhs_content + , mpl::false_ // is_nothrow_move_constructible + , int + ) + { + // Backup lhs content... + LhsT* backup_lhs_ptr = new LhsT(lhs_content); + + // ...destroy lhs content... + lhs_content.~LhsT(); // nothrow + + BOOST_TRY + { + // ...and attempt to copy rhs content into lhs storage: + copy_rhs_content_(lhs_.storage_.address(), rhs_content_); + } + BOOST_CATCH (...) + { + // In case of failure, copy backup pointer to lhs storage... + new(lhs_.storage_.address()) + backup_holder( backup_lhs_ptr ); // nothrow + + // ...indicate now using backup... + lhs_.indicate_backup_which( lhs_.which() ); // nothrow + + // ...and rethrow: + BOOST_RETHROW; + } + BOOST_CATCH_END + + // In case of success, indicate new content type... + lhs_.indicate_which(rhs_which_); // nothrow + + // ...and delete backup: + delete backup_lhs_ptr; // nothrow + } + +public: // visitor interface + + template + void internal_visit(LhsT& lhs_content, int) + { + typedef typename is_nothrow_move_constructible::type + nothrow_move; + + backup_assign_impl( lhs_content, nothrow_move(), 1L); + } + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) +private: + // silence MSVC warning C4512: assignment operator could not be generated + backup_assigner& operator= (backup_assigner const&); +#endif +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class swap_with +// +// Visitor that swaps visited value with content of given variant. +// +// Precondition: Given variant MUST have same logical type as visited value. +// +template +struct swap_with + : public static_visitor<> +{ +private: // representation + + Variant& toswap_; + +public: // structors + + explicit swap_with(Variant& toswap) BOOST_NOEXCEPT + : toswap_(toswap) + { + } + +public: // internal visitor interfaces + + template + void operator()(T& operand) const + { + // Since the precondition ensures types are same, get T... + known_get getter; + T& other = toswap_.apply_visitor(getter); + + // ...and swap: + ::boost::detail::variant::move_swap( operand, other ); + } + +private: + swap_with& operator=(const swap_with&); + +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class reflect +// +// Generic static visitor that performs a typeid on the value it visits. +// + +class reflect + : public static_visitor +{ +public: // visitor interfaces + + template + const boost::typeindex::type_info& operator()(const T&) const BOOST_NOEXCEPT + { + return boost::typeindex::type_id().type_info(); + } + +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class comparer +// +// Generic static visitor that compares the content of the given lhs variant +// with the visited rhs content using Comp. +// +// Precondition: lhs.which() == rhs.which() +// +template +class comparer + : public static_visitor +{ +private: // representation + + const Variant& lhs_; + +public: // structors + + explicit comparer(const Variant& lhs) BOOST_NOEXCEPT + : lhs_(lhs) + { + } + +public: // visitor interfaces + + template + bool operator()(T& rhs_content) const + { + // Since the precondition ensures lhs and rhs types are same, get T... + known_get getter; + const T& lhs_content = lhs_.apply_visitor(getter); + + // ...and compare lhs and rhs contents: + return Comp()(lhs_content, rhs_content); + } + +private: + comparer& operator=(const comparer&); + +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class equal_comp +// +// Generic function object compares lhs with rhs using operator==. +// +struct equal_comp +{ + template + bool operator()(const T& lhs, const T& rhs) const + { + return lhs == rhs; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class less_comp +// +// Generic function object compares lhs with rhs using operator<. +// +struct less_comp +{ + template + bool operator()(const T& lhs, const T& rhs) const + { + return lhs < rhs; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class template invoke_visitor +// +// Internal visitor that invokes the given visitor using: +// * for wrappers (e.g., recursive_wrapper), the wrapper's held value. +// * for all other values, the value itself. +// +template +class invoke_visitor +{ +private: // representation + + Visitor& visitor_; + +public: // visitor typedefs + + typedef typename Visitor::result_type + result_type; + +public: // structors + + explicit invoke_visitor(Visitor& visitor) BOOST_NOEXCEPT + : visitor_(visitor) + { + } + +public: // internal visitor interfaces + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + + //using workaround with is_same to prenvent compilation error, because we need to use T in enable_if to make SFINAE work + template + typename enable_if_c::value, result_type>::type internal_visit(T&& operand, int) + { + return visitor_(::boost::move(operand)); + } + + //using workaround with is_same to prenvent compilation error, because we need to use T in enable_if to make SFINAE work + template + typename disable_if_c::value, result_type>::type internal_visit(T&& operand, int) + { + return visitor_(operand); + } + +#else + + template + result_type internal_visit(T& operand, int) + { + return visitor_(operand); + } + +# if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0564)) + template + result_type internal_visit(const T& operand, int) + { + return visitor_(operand); + } +# endif //BORLAND + +#endif //RVALUE REFERENCES + +public: // internal visitor interfaces, cont. + + template + result_type internal_visit(boost::recursive_wrapper& operand, long) + { + return internal_visit( operand.get(), 1L ); + } + + template + result_type internal_visit(const boost::recursive_wrapper& operand, long) + { + return internal_visit( operand.get(), 1L ); + } + + template + result_type internal_visit(boost::detail::reference_content& operand, long) + { + return internal_visit( operand.get(), 1L ); + } + + template + result_type internal_visit(const boost::detail::reference_content& operand, long) + { + return internal_visit( operand.get(), 1L ); + } + + template + result_type internal_visit(boost::detail::variant::backup_holder& operand, long) + { + return internal_visit( operand.get(), 1L ); + } + + template + result_type internal_visit(const boost::detail::variant::backup_holder& operand, long) + { + return internal_visit( operand.get(), 1L ); + } + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) +private: + // silence MSVC warning C4512: assignment operator could not be generated + invoke_visitor& operator= (invoke_visitor const&); +#endif +}; + +}} // namespace detail::variant + +/////////////////////////////////////////////////////////////////////////////// +// class template variant (concept inspired by Andrei Alexandrescu) +// +// See docs and boost/variant/variant_fwd.hpp for more information. +// +template < + typename T0_ + , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T) + > +class variant +{ +private: // helpers, for typedefs (below) + + typedef variant wknd_self_t; + + struct is_recursive_ + : detail::variant::is_recursive_flag + { + }; + + typedef typename mpl::eval_if< + is_recursive_ + , T0_ + , mpl::identity< T0_ > + >::type unwrapped_T0_; + + struct is_sequence_based_ + : detail::variant::is_over_sequence + { + }; + +#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT) + +private: // helpers, for typedefs (below) + + typedef typename mpl::eval_if< + is_sequence_based_ + , unwrapped_T0_ // over_sequence<...>::type + , detail::variant::make_variant_list< + unwrapped_T0_ + , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T) + > + >::type specified_types; + + BOOST_STATIC_ASSERT(( + ::boost::mpl::not_< mpl::empty >::value + )); + +public: // public typedefs + typedef typename mpl::eval_if< + is_recursive_ + , mpl::transform< + specified_types + , mpl::protect< + detail::variant::quoted_enable_recursive + > + > + , mpl::identity< specified_types > + >::type recursive_enabled_types; // used by is_variant_constructible_from<> trait + + typedef typename mpl::transform< + recursive_enabled_types + , unwrap_recursive + >::type types; + +private: // internal typedefs + + typedef typename mpl::transform< + recursive_enabled_types + , mpl::protect< detail::make_reference_content<> > + >::type internal_types; + + typedef typename mpl::front< + internal_types + >::type internal_T0; + +#else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT) + +private: // helpers, for typedefs (below) + + typedef unwrapped_T0_ T0; + + #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \ + typedef typename mpl::eval_if< \ + is_recursive_ \ + , detail::variant::enable_recursive< \ + BOOST_PP_CAT(T,N) \ + , wknd_self_t \ + > \ + , mpl::identity< BOOST_PP_CAT(T,N) > \ + >::type BOOST_PP_CAT(recursive_enabled_T,N); \ + /**/ + + BOOST_PP_REPEAT( + BOOST_VARIANT_LIMIT_TYPES + , BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS + , _ + ) + + #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS + + #define BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS(z,N,_) \ + typedef typename unwrap_recursive< \ + BOOST_PP_CAT(recursive_enabled_T,N) \ + >::type BOOST_PP_CAT(public_T,N); \ + /**/ + + BOOST_PP_REPEAT( + BOOST_VARIANT_LIMIT_TYPES + , BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS + , _ + ) + + #undef BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS + +public: // public typedefs + + typedef typename detail::variant::make_variant_list< + BOOST_VARIANT_ENUM_PARAMS(public_T) + >::type types; + +private: // helpers, for internal typedefs (below) + + #define BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS(z,N,_) \ + typedef detail::make_reference_content< \ + BOOST_PP_CAT(recursive_enabled_T,N) \ + >::type BOOST_PP_CAT(internal_T,N); \ + /**/ + + BOOST_PP_REPEAT( + BOOST_VARIANT_LIMIT_TYPES + , BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS + , _ + ) + + #undef BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS + +private: // internal typedefs + + typedef typename detail::variant::make_variant_list< + BOOST_VARIANT_ENUM_PARAMS(internal_T) + >::type internal_types; + +private: // static precondition assertions + + // NOTE TO USER : + // variant< type-sequence > syntax is not supported on this compiler! + // + BOOST_MPL_ASSERT_NOT(( is_sequence_based_ )); + +#endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT workaround + +private: // helpers, for representation (below) + + typedef typename detail::variant::find_fallback_type< + internal_types + >::type fallback_type_result_; + + typedef typename fallback_type_result_::first + fallback_type_index_; + typedef typename fallback_type_result_::second + fallback_type_; + + struct has_fallback_type_ + : mpl::not_< + is_same< fallback_type_, detail::variant::no_fallback_type > + > + { + }; + + typedef has_fallback_type_ + never_uses_backup_flag; + + typedef typename detail::variant::make_storage< + internal_types, never_uses_backup_flag + >::type storage_t; + +#ifndef BOOST_NO_CXX11_NOEXCEPT + typedef typename detail::variant::is_variant_move_noexcept_constructible< + internal_types + > variant_move_noexcept_constructible; + + typedef typename detail::variant::is_variant_move_noexcept_assignable< + internal_types + > variant_move_noexcept_assignable; + +#endif + +private: // helpers, for representation (below) + + // which_ on: + // * [0, size) indicates stack content + // * [-size, 0) indicates pointer to heap backup + // if which_ >= 0: + // * then which() -> which_ + // * else which() -> -(which_ + 1) + +#if !defined(BOOST_VARIANT_MINIMIZE_SIZE) + + typedef int which_t; + +#else // defined(BOOST_VARIANT_MINIMIZE_SIZE) + + // [if O1_size available, then attempt which_t size optimization...] + // [select signed char if fewer than SCHAR_MAX types, else signed int:] + typedef typename mpl::eval_if< + mpl::equal_to< mpl::O1_size, mpl::long_<-1> > + , mpl::identity< int > + , mpl::if_< + mpl::less< mpl::O1_size, mpl::int_ > + , signed char + , int + > + >::type which_t; + +#endif // BOOST_VARIANT_MINIMIZE_SIZE switch + +// representation -- private when possible +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + private: +#else + public: +#endif + + which_t which_; + storage_t storage_; + + void indicate_which(int which_arg) BOOST_NOEXCEPT + { + which_ = static_cast( which_arg ); + } + + void indicate_backup_which(int which_arg) BOOST_NOEXCEPT + { + which_ = static_cast( -(which_arg + 1) ); + } + +private: // helpers, for queries (below) + + bool using_backup() const BOOST_NOEXCEPT + { + return which_ < 0; + } + +public: // queries + + int which() const BOOST_NOEXCEPT + { + // If using heap backup... + if (using_backup()) + // ...then return adjusted which_: + return -(which_ + 1); + + // Otherwise, return which_ directly: + return which_; + } + +private: // helpers, for structors (below) + + struct initializer + : BOOST_VARIANT_AUX_INITIALIZER_T( + recursive_enabled_types, recursive_enabled_T + ) + { + }; + + void destroy_content() BOOST_NOEXCEPT + { + detail::variant::destroyer visitor; + this->internal_apply_visitor(visitor); + } + +public: // structors + + ~variant() BOOST_NOEXCEPT + { + destroy_content(); + } + + variant() +#if !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130)) + BOOST_NOEXCEPT_IF(boost::has_nothrow_constructor::value) +#endif + { +#ifdef _MSC_VER +#pragma warning( push ) +// behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized +#pragma warning( disable : 4345 ) +#endif + // NOTE TO USER : + // Compile error from here indicates that the first bound + // type is not default-constructible, and so variant cannot + // support its own default-construction. + // + new( storage_.address() ) internal_T0(); + indicate_which(0); // zero is the index of the first bounded type +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + } + +private: // helpers, for structors, cont. (below) + + class convert_copy_into + : public static_visitor + { + private: // representation + + void* storage_; + + public: // structors + + explicit convert_copy_into(void* storage) BOOST_NOEXCEPT + : storage_(storage) + { + } + + public: // internal visitor interfaces (below) + + template + int internal_visit(T& operand, int) const + { + // NOTE TO USER : + // Compile error here indicates one of the source variant's types + // cannot be unambiguously converted to the destination variant's + // types (or that no conversion exists). + // + return initializer::initialize(storage_, operand); + } + +# if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0564)) + template + result_type internal_visit(const T& operand, int) const + { + return initializer::initialize(storage_, operand); + } +# endif + + template + int internal_visit(boost::detail::reference_content& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(const boost::detail::reference_content& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(boost::detail::variant::backup_holder& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(const boost::detail::variant::backup_holder& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(boost::recursive_wrapper& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(const boost::recursive_wrapper& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + }; + + friend class convert_copy_into; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + class convert_move_into + : public static_visitor + { + private: // representation + + void* storage_; + + public: // structors + + explicit convert_move_into(void* storage) BOOST_NOEXCEPT + : storage_(storage) + { + } + + public: // internal visitor interfaces (below) + + template + int internal_visit(T& operand, int) const + { + // NOTE TO USER : + // Compile error here indicates one of the source variant's types + // cannot be unambiguously converted to the destination variant's + // types (or that no conversion exists). + // + return initializer::initialize(storage_, detail::variant::move(operand) ); + } + + template + int internal_visit(boost::detail::reference_content& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(const boost::detail::reference_content& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(boost::detail::variant::backup_holder& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(const boost::detail::variant::backup_holder& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(boost::recursive_wrapper& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(const boost::recursive_wrapper& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + }; + + friend class convert_move_into; +#endif + +private: // helpers, for structors, below + + template + void convert_construct( + T& operand + , int + , mpl::false_ = mpl::false_() // is_foreign_variant + ) + { + // NOTE TO USER : + // Compile error here indicates that the given type is not + // unambiguously convertible to one of the variant's types + // (or that no conversion exists). + // + indicate_which( + initializer::initialize( + storage_.address() + , operand + ) + ); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + typename boost::enable_if >::type convert_construct( + T&& operand + , int + , mpl::false_ = mpl::false_() // is_foreign_variant + ) + { + // NOTE TO USER : + // Compile error here indicates that the given type is not + // unambiguously convertible to one of the variant's types + // (or that no conversion exists). + // + indicate_which( + initializer::initialize( + storage_.address() + , detail::variant::move(operand) + ) + ); + } +#endif + + template + void convert_construct( + Variant& operand + , long + , mpl::true_// is_foreign_variant + ) + { + convert_copy_into visitor(storage_.address()); + indicate_which( + operand.internal_apply_visitor(visitor) + ); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + typename boost::enable_if >::type convert_construct( + Variant&& operand + , long + , mpl::true_// is_foreign_variant + ) + { + convert_move_into visitor(storage_.address()); + indicate_which( + operand.internal_apply_visitor(visitor) + ); + } +#endif + + template + void convert_construct_variant(Variant& operand) + { + // [Determine if the given variant is itself a bounded type, or if its + // content needs to be converted (i.e., it is a 'foreign' variant):] + // + + typedef typename mpl::find_if< + types + , is_same< + add_const + , const Variant + > + >::type found_it; + + typedef typename mpl::end::type not_found; + typedef typename is_same< + found_it, not_found + >::type is_foreign_variant; + + // Convert construct from operand: + convert_construct( + operand, 1L + , is_foreign_variant() + ); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + typename boost::enable_if >::type convert_construct_variant(Variant&& operand) + { + // [Determine if the given variant is itself a bounded type, or if its + // content needs to be converted (i.e., it is a 'foreign' variant):] + // + + typedef typename mpl::find_if< + types + , is_same< + add_const + , const Variant + > + >::type found_it; + + typedef typename mpl::end::type not_found; + typedef typename is_same< + found_it, not_found + >::type is_foreign_variant; + + // Convert move construct from operand: + convert_construct( + detail::variant::move(operand), 1L + , is_foreign_variant() + ); + } +#endif + + template + typename boost::enable_if, variant>, + boost::detail::variant::is_variant_constructible_from&, internal_types> + > >::type convert_construct( + boost::variant& operand + , long + ) + { + convert_construct_variant(operand); + } + + template + typename boost::enable_if, variant>, + boost::detail::variant::is_variant_constructible_from&, internal_types> + > >::type convert_construct( + const boost::variant& operand + , long + ) + { + convert_construct_variant(operand); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + typename boost::enable_if, variant>, + boost::detail::variant::is_variant_constructible_from&&, internal_types> + > >::type convert_construct( + boost::variant&& operand + , long + ) + { + convert_construct_variant( detail::variant::move(operand) ); + } +#endif + +public: // structors, cont. + + template + variant(const T& operand, + typename boost::enable_if >, + boost::detail::variant::is_variant_constructible_from + >, + boost::is_same >, + bool >::type = true) + { + convert_construct(operand, 1L); + } + + template + variant( + T& operand + , typename boost::enable_if >, + mpl::not_< boost::is_same >, + boost::detail::variant::is_variant_constructible_from + >, + boost::is_same >, + bool >::type = true + ) + { + convert_construct(operand, 1L); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + variant(T&& operand, + typename boost::enable_if, + mpl::not_< boost::is_const >, + mpl::not_< boost::is_same >, + boost::detail::variant::is_variant_constructible_from + >, + boost::is_same >, + bool >::type = true) + { + convert_construct( detail::variant::move(operand), 1L); + } +#endif + +public: // structors, cont. + + // [MSVC6 requires copy constructor appear after template constructors] + variant(const variant& operand) + { + // Copy the value of operand into *this... + detail::variant::copy_into visitor( storage_.address() ); + operand.internal_apply_visitor(visitor); + + // ...and activate the *this's primary storage on success: + indicate_which(operand.which()); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + variant(variant&& operand) BOOST_NOEXCEPT_IF(variant_move_noexcept_constructible::type::value) + { + // Move the value of operand into *this... + detail::variant::move_into visitor( storage_.address() ); + operand.internal_apply_visitor(visitor); + + // ...and activate the *this's primary storage on success: + indicate_which(operand.which()); + } +#endif + +private: // helpers, for modifiers (below) + +# if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template + friend class detail::variant::backup_assigner; +# endif + + // class assigner + // + // Internal visitor that "assigns" the visited value to the given variant + // by appropriate destruction and copy-construction. + // + + class assigner + : public static_visitor<> + { + protected: // representation + + variant& lhs_; + const int rhs_which_; + + public: // structors + + assigner(variant& lhs, int rhs_which) BOOST_NOEXCEPT + : lhs_(lhs) + , rhs_which_(rhs_which) + { + } + + protected: // helpers, for internal visitor interface (below) + + template + void assign_impl( + const RhsT& rhs_content + , mpl::true_ // has_nothrow_copy + , B1 // is_nothrow_move_constructible + , B2 // has_fallback_type + ) const BOOST_NOEXCEPT + { + // Destroy lhs's content... + lhs_.destroy_content(); // nothrow + + // ...copy rhs content into lhs's storage... + new(lhs_.storage_.address()) + RhsT( rhs_content ); // nothrow + + // ...and indicate new content type: + lhs_.indicate_which(rhs_which_); // nothrow + } + + template + void assign_impl( + const RhsT& rhs_content + , mpl::false_ // has_nothrow_copy + , mpl::true_ // is_nothrow_move_constructible + , B // has_fallback_type + ) const + { + // Attempt to make a temporary copy (so as to move it below)... + RhsT temp(rhs_content); + + // ...and upon success destroy lhs's content... + lhs_.destroy_content(); // nothrow + + // ...move the temporary copy into lhs's storage... + new(lhs_.storage_.address()) + RhsT( detail::variant::move(temp) ); // nothrow + + // ...and indicate new content type: + lhs_.indicate_which(rhs_which_); // nothrow + } + + void construct_fallback() const BOOST_NOEXCEPT { + // In case of failure, default-construct fallback type in lhs's storage... + new (lhs_.storage_.address()) + fallback_type_; // nothrow + + // ...indicate construction of fallback type... + lhs_.indicate_which( + BOOST_MPL_AUX_VALUE_WKND(fallback_type_index_)::value + ); // nothrow + } + + template + void assign_impl( + const RhsT& rhs_content + , mpl::false_ // has_nothrow_copy + , mpl::false_ // is_nothrow_move_constructible + , mpl::true_ // has_fallback_type + ) const + { + // Destroy lhs's content... + lhs_.destroy_content(); // nothrow + + BOOST_TRY + { + // ...and attempt to copy rhs's content into lhs's storage: + new(lhs_.storage_.address()) + RhsT( rhs_content ); + } + BOOST_CATCH (...) + { + construct_fallback(); + + // ...and rethrow: + BOOST_RETHROW; + } + BOOST_CATCH_END + + // In the event of success, indicate new content type: + lhs_.indicate_which(rhs_which_); // nothrow + } + + template + void assign_impl( + const RhsT& rhs_content + , mpl::false_ // has_nothrow_copy + , mpl::false_ // is_nothrow_move_constructible + , mpl::false_ // has_fallback_type + ) const + { + detail::variant::backup_assigner + visitor(lhs_, rhs_which_, rhs_content); + lhs_.internal_apply_visitor(visitor); + } + + public: // internal visitor interfaces + + template + void internal_visit(const RhsT& rhs_content, int) const + { + typedef typename has_nothrow_copy::type + nothrow_copy; + typedef typename mpl::or_< // reduces compile-time + nothrow_copy + , is_nothrow_move_constructible + >::type nothrow_move_constructor; + + assign_impl( + rhs_content + , nothrow_copy() + , nothrow_move_constructor() + , has_fallback_type_() + ); + } + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) + private: + // silence MSVC warning C4512: assignment operator could not be generated + assigner& operator= (assigner const&); +#endif + }; + + friend class assigner; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + // class move_assigner + // + // Internal visitor that "move assigns" the visited value to the given variant + // by appropriate destruction and move-construction. + // + + class move_assigner + : public assigner + { + public: // structors + + move_assigner(variant& lhs, int rhs_which) BOOST_NOEXCEPT + : assigner(lhs, rhs_which) + { + } + + private: // helpers, for internal visitor interface (below) + + template + void assign_impl( + RhsT& rhs_content + , mpl::true_ // has_nothrow_copy + , mpl::false_ // is_nothrow_move_constructible + , B2 // has_fallback_type + ) const BOOST_NOEXCEPT + { + assigner::assign_impl(rhs_content, mpl::true_(), mpl::false_(), B2()); + } + + template + void assign_impl( + RhsT& rhs_content + , B // has_nothrow_copy + , mpl::true_ // is_nothrow_move_constructible + , B2 // has_fallback_type + ) const BOOST_NOEXCEPT + { + // ...destroy lhs's content... + assigner::lhs_.destroy_content(); // nothrow + + // ...move the rhs_content into lhs's storage... + new(assigner::lhs_.storage_.address()) + RhsT( detail::variant::move(rhs_content) ); // nothrow + + // ...and indicate new content type: + assigner::lhs_.indicate_which(assigner::rhs_which_); // nothrow + } + + template + void assign_impl( + RhsT& rhs_content + , mpl::false_ // has_nothrow_copy + , mpl::false_ // is_nothrow_move_constructible + , mpl::true_ // has_fallback_type + ) const + { + // Destroy lhs's content... + assigner::lhs_.destroy_content(); // nothrow + + BOOST_TRY + { + // ...and attempt to copy rhs's content into lhs's storage: + new(assigner::lhs_.storage_.address()) + RhsT( detail::variant::move(rhs_content) ); + } + BOOST_CATCH (...) + { + assigner::construct_fallback(); + + // ...and rethrow: + BOOST_RETHROW; + } + BOOST_CATCH_END + + // In the event of success, indicate new content type: + assigner::lhs_.indicate_which(assigner::rhs_which_); // nothrow + } + + template + void assign_impl( + RhsT& rhs_content + , mpl::false_ // has_nothrow_copy + , mpl::false_ // is_nothrow_move_constructible + , mpl::false_ // has_fallback_type + ) const + { + assigner::assign_impl(rhs_content, mpl::false_(), mpl::false_(), mpl::false_()); + } + + public: // internal visitor interfaces + + template + void internal_visit(RhsT& rhs_content, int) const + { + typedef typename is_nothrow_move_constructible::type + nothrow_move_constructor; + typedef typename mpl::or_< // reduces compile-time + nothrow_move_constructor + , has_nothrow_copy + >::type nothrow_copy; + + assign_impl( + rhs_content + , nothrow_copy() + , nothrow_move_constructor() + , has_fallback_type_() + ); + } + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) + private: + // silence MSVC warning C4512: assignment operator could not be generated + move_assigner& operator= (move_assigner const&); +#endif + }; + + friend class move_assigner; +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES + + void variant_assign(const variant& rhs) + { + // If the contained types are EXACTLY the same... + if (which_ == rhs.which_) + { + // ...then assign rhs's storage to lhs's content: + detail::variant::assign_storage visitor(rhs.storage_.address()); + this->internal_apply_visitor(visitor); + } + else + { + // Otherwise, perform general (copy-based) variant assignment: + assigner visitor(*this, rhs.which()); + rhs.internal_apply_visitor(visitor); + } + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + void variant_assign(variant&& rhs) + { + // If the contained types are EXACTLY the same... + if (which_ == rhs.which_) + { + // ...then move rhs's storage to lhs's content: + detail::variant::move_storage visitor(rhs.storage_.address()); + this->internal_apply_visitor(visitor); + } + else + { + // Otherwise, perform general (move-based) variant assignment: + move_assigner visitor(*this, rhs.which()); + rhs.internal_apply_visitor(visitor); + } + } +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES + +private: // helpers, for modifiers (below) + + template + void assign(const T& rhs) + { + // If direct T-to-T assignment is not possible... + detail::variant::direct_assigner direct_assign(rhs); + if (this->apply_visitor(direct_assign) == false) + { + // ...then convert rhs to variant and assign: + // + // While potentially inefficient, the following construction of a + // variant allows T as any type convertible to one of the bounded + // types without excessive code redundancy. + // + variant temp(rhs); + variant_assign( detail::variant::move(temp) ); + } + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + void move_assign(T&& rhs) + { + // If direct T-to-T move assignment is not possible... + detail::variant::direct_mover direct_move(rhs); + if (this->apply_visitor(direct_move) == false) + { + // ...then convert rhs to variant and assign: + // + // While potentially inefficient, the following construction of a + // variant allows T as any type convertible to one of the bounded + // types without excessive code redundancy. + // + variant temp( detail::variant::move(rhs) ); + variant_assign( detail::variant::move(temp) ); + } + } +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES + +public: // modifiers + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + (!BOOST_WORKAROUND(BOOST_CLANG_VERSION, BOOST_TESTED_AT(150000)) || BOOST_CXX_VERSION <= 202002L) + template + typename boost::enable_if< + boost::mpl::and_< + boost::is_rvalue_reference, + mpl::not_< boost::is_const >, + boost::detail::variant::is_variant_constructible_from + >, + variant& + >::type operator=(T&& rhs) + { + move_assign( detail::variant::move(rhs) ); + return *this; + } +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES + + template + typename boost::enable_if< + mpl::or_< + boost::is_same, + boost::detail::variant::is_variant_constructible_from + >, + variant& + >::type operator=(const T& rhs) + { + assign(rhs); + return *this; + } + + // [MSVC6 requires copy assign appear after templated operator=] + variant& operator=(const variant& rhs) + { + variant_assign(rhs); + return *this; + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + variant& operator=(variant&& rhs) +#if !defined(__GNUC__) || (__GNUC__ != 4) || (__GNUC_MINOR__ > 6) || defined(__clang__) + BOOST_NOEXCEPT_IF(variant_move_noexcept_constructible::type::value && variant_move_noexcept_assignable::type::value) +#endif + { + variant_assign( detail::variant::move(rhs) ); + return *this; + } +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES + + void swap(variant& rhs) + { + // If the contained types are the same... + if (which() == rhs.which()) + { + // ...then swap the values directly: + detail::variant::swap_with visitor(rhs); + this->apply_visitor(visitor); + } + else + { + // ...otherwise, perform general variant swap: + variant tmp( detail::variant::move(rhs) ); + rhs = detail::variant::move(*this); + *this = detail::variant::move(tmp); + } + } + +public: // queries + + // + // NOTE: member which() defined above. + // + + bool empty() const BOOST_NOEXCEPT + { + return false; + } + + const boost::typeindex::type_info& type() const + { + detail::variant::reflect visitor; + return this->apply_visitor(visitor); + } + +public: // prevent comparison with foreign types + + template + void operator==(const U&) const + { + BOOST_STATIC_ASSERT( false && sizeof(U) ); + } + + template + void operator<(const U&) const + { + BOOST_STATIC_ASSERT( false && sizeof(U) ); + } + + template + void operator!=(const U&) const + { + BOOST_STATIC_ASSERT( false && sizeof(U) ); + } + + template + void operator>(const U&) const + { + BOOST_STATIC_ASSERT( false && sizeof(U) ); + } + + template + void operator<=(const U&) const + { + BOOST_STATIC_ASSERT( false && sizeof(U) ); + } + + template + void operator>=(const U&) const + { + BOOST_STATIC_ASSERT( false && sizeof(U) ); + } + +public: // comparison operators + + // [MSVC6 requires these operators appear after template operators] + + bool operator==(const variant& rhs) const + { + if (this->which() != rhs.which()) + return false; + + detail::variant::comparer< + variant, detail::variant::equal_comp + > visitor(*this); + return rhs.apply_visitor(visitor); + } + + bool operator<(const variant& rhs) const + { + // + // Dirk Schreib suggested this collating order. + // + + if (this->which() != rhs.which()) + return this->which() < rhs.which(); + + detail::variant::comparer< + variant, detail::variant::less_comp + > visitor(*this); + return rhs.apply_visitor(visitor); + } + + /////////////////////////////////////////////////////////////////////////////// + // comparison operators != > <= >= + inline bool operator!=(const variant& rhs) const + { + return !(*this == rhs); + } + + inline bool operator>(const variant& rhs) const + { + return rhs < *this; + } + + inline bool operator<=(const variant& rhs) const + { + return !(*this > rhs); + } + + inline bool operator>=(const variant& rhs) const + { + return !(*this < rhs); + } + +// helpers, for visitation support (below) -- private when possible +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + + template < BOOST_VARIANT_ENUM_PARAMS(typename U) > + friend class variant; + +private: + +#else// defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + +public: + +#endif// !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + + template + BOOST_FORCEINLINE static typename Visitor::result_type + internal_apply_visitor_impl( + int internal_which + , int logical_which + , Visitor& visitor + , VoidPtrCV storage + ) + { + typedef mpl::int_<0> first_which; + typedef typename mpl::begin::type first_it; + typedef typename mpl::end::type last_it; + + typedef detail::variant::visitation_impl_step< + first_it, last_it + > first_step; + + return detail::variant::visitation_impl( + internal_which, logical_which + , visitor, storage, mpl::false_() + , never_uses_backup_flag() + , static_cast(0), static_cast(0) + ); + } + + template + BOOST_FORCEINLINE typename Visitor::result_type + internal_apply_visitor(Visitor& visitor) + { + return internal_apply_visitor_impl( + which_, which(), visitor, storage_.address() + ); + } + + template + BOOST_FORCEINLINE typename Visitor::result_type + internal_apply_visitor(Visitor& visitor) const + { + return internal_apply_visitor_impl( + which_, which(), visitor, storage_.address() + ); + } + +public: // visitation support + +#ifndef BOOST_NO_CXX11_REF_QUALIFIERS + + template + typename Visitor::result_type + apply_visitor(Visitor& visitor) && + { + detail::variant::invoke_visitor invoker(visitor); + return this->internal_apply_visitor(invoker); + } + + template + typename Visitor::result_type + apply_visitor(Visitor& visitor) const&& + { + detail::variant::invoke_visitor invoker(visitor); + return this->internal_apply_visitor(invoker); + } + +#endif + + template + typename Visitor::result_type + apply_visitor(Visitor& visitor) +#ifndef BOOST_NO_CXX11_REF_QUALIFIERS + & +#endif + { + detail::variant::invoke_visitor invoker(visitor); + return this->internal_apply_visitor(invoker); + } + + template + typename Visitor::result_type + apply_visitor(Visitor& visitor) const +#ifndef BOOST_NO_CXX11_REF_QUALIFIERS + & +#endif + { + detail::variant::invoke_visitor invoker(visitor); + return this->internal_apply_visitor(invoker); + } + +}; // class variant + +/////////////////////////////////////////////////////////////////////////////// +// metafunction make_variant_over +// +// See docs and boost/variant/variant_fwd.hpp for more information. +// +template +struct make_variant_over +{ +private: // precondition assertions + + BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence::value )); + typedef typename boost::mpl::insert_range< + boost::mpl::list<> + , boost::mpl::end< boost::mpl::list<> >::type + , Types + >::type copied_sequence_t; + +public: // metafunction result + + typedef variant< + detail::variant::over_sequence + > type; + +}; + +/////////////////////////////////////////////////////////////////////////////// +// function template swap +// +// Swaps two variants of the same type (i.e., identical specification). +// +template < BOOST_VARIANT_ENUM_PARAMS(typename T) > +inline void swap( + variant< BOOST_VARIANT_ENUM_PARAMS(T) >& lhs + , variant< BOOST_VARIANT_ENUM_PARAMS(T) >& rhs + ) +{ + lhs.swap(rhs); +} + +} // namespace boost + +// implementation additions + +#if !defined(BOOST_NO_IOSTREAM) +#include +#endif // BOOST_NO_IOSTREAM + +#endif // BOOST_VARIANT_VARIANT_HPP diff --git a/boost/variant/variant_fwd.hpp b/boost/variant/variant_fwd.hpp new file mode 100644 index 00000000..613bcb67 --- /dev/null +++ b/boost/variant/variant_fwd.hpp @@ -0,0 +1,322 @@ +//----------------------------------------------------------------------------- +// boost variant/variant_fwd.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 Eric Friedman, Itay Maman +// Copyright (c) 2013-2023 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_VARIANT_FWD_HPP +#define BOOST_VARIANT_VARIANT_FWD_HPP + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +// macro BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT +// +// Defined if variant does not support make_variant_over (see below). +// +#if defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) +# define BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT +#endif + +/////////////////////////////////////////////////////////////////////////////// +// macro BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT +// +// Defined if make_recursive_variant cannot be supported as documented. +// +// Note: Currently, MPL lambda facility is used as workaround if defined, and +// so only types declared w/ MPL lambda workarounds will work. +// + +#include + +#if defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) \ + && !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT) +# define BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// macro BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES +// + +/* + GCC before 4.0 had no variadic tempaltes; + GCC 4.6 has incomplete implementation of variadic templates. + + MSVC2015 Update 1 has variadic templates, but they have issues. + + NOTE: Clang compiler defines __GNUC__ +*/ +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) \ + || (!defined(__clang__) && defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7)) \ + || (defined(_MSC_VER) && (_MSC_VER <= 1900)) \ + || defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) \ + || defined (BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT) + +#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES +# define BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES +#endif + +#endif + +#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) +#include + +#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_class class)( +#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_typename typename)( + +#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_class class... +#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_typename typename... + +#define ARGS_VARIADER_1(x) x ## N... +#define ARGS_VARIADER_2(x) BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_ ## x ## N + +#define BOOST_VARIANT_MAKE_VARIADIC(sequence, x) BOOST_VARIANT_MAKE_VARIADIC_I(BOOST_PP_SEQ_SIZE(sequence), x) +#define BOOST_VARIANT_MAKE_VARIADIC_I(argscount, x) BOOST_VARIANT_MAKE_VARIADIC_II(argscount, x) +#define BOOST_VARIANT_MAKE_VARIADIC_II(argscount, orig) ARGS_VARIADER_ ## argscount(orig) + +/////////////////////////////////////////////////////////////////////////////// +// BOOST_VARIANT_ENUM_PARAMS and BOOST_VARIANT_ENUM_SHIFTED_PARAMS +// +// Convenience macro for enumeration of variant params. +// When variadic templates are available expands: +// BOOST_VARIANT_ENUM_PARAMS(class Something) => class Something0, class... SomethingN +// BOOST_VARIANT_ENUM_PARAMS(typename Something) => typename Something0, typename... SomethingN +// BOOST_VARIANT_ENUM_PARAMS(Something) => Something0, SomethingN... +// BOOST_VARIANT_ENUM_PARAMS(Something) => Something0, SomethingN... +// BOOST_VARIANT_ENUM_SHIFTED_PARAMS(class Something) => class... SomethingN +// BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename Something) => typename... SomethingN +// BOOST_VARIANT_ENUM_SHIFTED_PARAMS(Something) => SomethingN... +// BOOST_VARIANT_ENUM_SHIFTED_PARAMS(Something) => SomethingN... +// +// Rationale: Cleaner, simpler code for clients of variant library. Minimal +// code modifications to move from C++03 to C++11. +// +// With BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES defined +// will be used BOOST_VARIANT_ENUM_PARAMS and BOOST_VARIANT_ENUM_SHIFTED_PARAMS from below `#else` +// + +#define BOOST_VARIANT_ENUM_PARAMS(x) \ + x ## 0, \ + BOOST_VARIANT_MAKE_VARIADIC( (BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_ ## x), x) \ + /**/ + +#define BOOST_VARIANT_ENUM_SHIFTED_PARAMS(x) \ + BOOST_VARIANT_MAKE_VARIADIC( (BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_ ## x), x) \ + /**/ + +#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) + +/////////////////////////////////////////////////////////////////////////////// +// macro BOOST_VARIANT_LIMIT_TYPES +// +// Implementation-defined preprocessor symbol describing the actual +// length of variant's pseudo-variadic template parameter list. +// +#include +#define BOOST_VARIANT_LIMIT_TYPES \ + BOOST_MPL_LIMIT_LIST_SIZE + +/////////////////////////////////////////////////////////////////////////////// +// macro BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY +// +// Exposes maximum allowed arity of class templates with recursive_variant +// arguments. That is, +// make_recursive_variant< ..., T<[1], recursive_variant_, ... [N]> >. +// +#include +#define BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY \ + BOOST_MPL_LIMIT_METAFUNCTION_ARITY + +/////////////////////////////////////////////////////////////////////////////// +// macro BOOST_VARIANT_ENUM_PARAMS +// +// Convenience macro for enumeration of BOOST_VARIANT_LIMIT_TYPES params. +// +// Rationale: Cleaner, simpler code for clients of variant library. +// +#define BOOST_VARIANT_ENUM_PARAMS( param ) \ + BOOST_PP_ENUM_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param) + +/////////////////////////////////////////////////////////////////////////////// +// macro BOOST_VARIANT_ENUM_SHIFTED_PARAMS +// +// Convenience macro for enumeration of BOOST_VARIANT_LIMIT_TYPES-1 params. +// +#define BOOST_VARIANT_ENUM_SHIFTED_PARAMS( param ) \ + BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param) + +#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround + + +namespace boost { + +namespace detail { namespace variant { + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class void_ and class template convert_void +// +// Provides the mechanism by which void(NN) types are converted to +// mpl::void_ (and thus can be passed to mpl::list). +// +// Rationale: This is particularly needed for the using-declarations +// workaround (below), but also to avoid associating mpl namespace with +// variant in argument dependent lookups (which used to happen because of +// defaulting of template parameters to mpl::void_). +// + +struct void_; + +template +struct convert_void +{ + typedef T type; +}; + +template <> +struct convert_void< void_ > +{ + typedef mpl::na type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// (workaround) BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +// +// Needed to work around compilers that don't support using-declaration +// overloads. (See the variant::initializer workarounds below.) +// + +#if defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) +// (detail) tags voidNN -- NN defined on [0, BOOST_VARIANT_LIMIT_TYPES) +// +// Defines void types that are each unique and specializations of +// convert_void that yields mpl::na for each voidNN type. +// + +#define BOOST_VARIANT_DETAIL_DEFINE_VOID_N(z,N,_) \ + struct BOOST_PP_CAT(void,N); \ + \ + template <> \ + struct convert_void< BOOST_PP_CAT(void,N) > \ + { \ + typedef mpl::na type; \ + }; \ + /**/ + +BOOST_PP_REPEAT( + BOOST_VARIANT_LIMIT_TYPES + , BOOST_VARIANT_DETAIL_DEFINE_VOID_N + , _ + ) + +#undef BOOST_VARIANT_DETAIL_DEFINE_VOID_N + +#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround + +}} // namespace detail::variant + +#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) +# define BOOST_VARIANT_AUX_DECLARE_PARAMS BOOST_VARIANT_ENUM_PARAMS(typename T) +#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) + +/////////////////////////////////////////////////////////////////////////////// +// (detail) macro BOOST_VARIANT_AUX_DECLARE_PARAM +// +// Template parameter list for variant and recursive_variant declarations. +// + +#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) + +# define BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL(z, N, T) \ + typename BOOST_PP_CAT(T,N) = detail::variant::void_ \ + /**/ + +#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) + +# define BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL(z, N, T) \ + typename BOOST_PP_CAT(T,N) = BOOST_PP_CAT(detail::variant::void,N) \ + /**/ + +#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround + +#define BOOST_VARIANT_AUX_DECLARE_PARAMS \ + BOOST_PP_ENUM( \ + BOOST_VARIANT_LIMIT_TYPES \ + , BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL \ + , T \ + ) \ + /**/ + +#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround + +/////////////////////////////////////////////////////////////////////////////// +// class template variant (concept inspired by Andrei Alexandrescu) +// +// Efficient, type-safe bounded discriminated union. +// +// Preconditions: +// - Each type must be unique. +// - No type may be const-qualified. +// +// Proper declaration form: +// variant (where types is a type-sequence) +// or +// variant (where T0 is NOT a type-sequence) +// +template < BOOST_VARIANT_AUX_DECLARE_PARAMS > class variant; + +/////////////////////////////////////////////////////////////////////////////// +// metafunction make_recursive_variant +// +// Exposes a boost::variant with recursive_variant_ tags (below) substituted +// with the variant itself (wrapped as needed with boost::recursive_wrapper). +// +template < BOOST_VARIANT_AUX_DECLARE_PARAMS > struct make_recursive_variant; + +#undef BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL +#undef BOOST_VARIANT_AUX_DECLARE_PARAMS + +/////////////////////////////////////////////////////////////////////////////// +// type recursive_variant_ +// +// Tag type indicates where recursive variant substitution should occur. +// +#if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT) + struct recursive_variant_ {}; +#else + typedef mpl::arg<1> recursive_variant_; +#endif + +/////////////////////////////////////////////////////////////////////////////// +// metafunction make_variant_over +// +// Result is a variant w/ types of the specified type sequence. +// +template struct make_variant_over; + +/////////////////////////////////////////////////////////////////////////////// +// metafunction make_recursive_variant_over +// +// Result is a recursive variant w/ types of the specified type sequence. +// +template struct make_recursive_variant_over; + +} // namespace boost + +#endif // BOOST_VARIANT_VARIANT_FWD_HPP diff --git a/boost/variant/visitor_ptr.hpp b/boost/variant/visitor_ptr.hpp new file mode 100644 index 00000000..00578413 --- /dev/null +++ b/boost/variant/visitor_ptr.hpp @@ -0,0 +1,88 @@ +//----------------------------------------------------------------------------- +// boost variant/visitor_ptr.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002-2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_VARIANT_VISITOR_PTR_HPP +#define BOOST_VARIANT_VISITOR_PTR_HPP + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { + +////////////////////////////////////////////////////////////////////////// +// function template visitor_ptr +// +// Adapts a function pointer for use as visitor capable of handling +// values of a single type. Throws bad_visit if inappropriately applied. +// +template +class visitor_ptr_t + : public static_visitor +{ +private: // representation + + typedef R (*visitor_t)(T); + + visitor_t visitor_; + +public: // typedefs + + typedef R result_type; + +private: // private typedefs + + typedef typename mpl::eval_if< + is_reference + , mpl::identity + , add_reference + >::type argument_fwd_type; + +public: // structors + + explicit visitor_ptr_t(visitor_t visitor) BOOST_NOEXCEPT + : visitor_(visitor) + { + } + +public: // static visitor interfaces + + template + result_type operator()(const U&) const + { + boost::throw_exception(bad_visit()); + } + +public: // static visitor interfaces, cont. + + result_type operator()(argument_fwd_type operand) const + { + return visitor_(operand); + } + +}; + +template +inline visitor_ptr_t visitor_ptr(R (*visitor)(T)) +{ + return visitor_ptr_t(visitor); +} + +} // namespace boost + +#endif// BOOST_VISITOR_VISITOR_PTR_HPP diff --git a/build.cmd b/build.cmd index a7ec5776..b0495da0 100644 --- a/build.cmd +++ b/build.cmd @@ -4,15 +4,15 @@ bcp ^ boost/container/flat_set.hpp ^ boost/container/small_vector.hpp ^ boost/container/static_vector.hpp ^ + boost/circular_buffer.hpp ^ boost/crc.hpp ^ boost/icl/interval_map.hpp ^ boost/locale/encoding_utf.hpp ^ boost/optional.hpp ^ boost/algorithm/string/replace.hpp ^ - boost/system/error_code.hpp ^ - boost/system/system_error.hpp ^ boost/process/async_pipe.hpp ^ boost/stacktrace.hpp ^ + boost/variant.hpp ^ boost/archive/binary_iarchive.hpp ^ boost/archive/binary_oarchive.hpp ^ boost/serialization/array.hpp ^ @@ -31,6 +31,7 @@ bcp ^ boost/serialization/shared_ptr.hpp ^ boost/serialization/unique_ptr.hpp ^ boost/serialization/weak_ptr.hpp ^ - boost/iostreams/ ^ - boost/url/ ^ + boost/iostreams/stream.hpp ^ + boost/iostreams/device/file_descriptor.hpp ^ + boost/url.hpp ^ --boost="%1" .